-1

Hey guys I have a problem relating to firebase, so the problem is whenever i upload the same photo twice i got an error that the previous photos go unfetched(that's a blank img icon) due to having same names,so i installed a library 'uuidv4' which generates unique ids, so how can i put and save the unique id instead of given image name

let uniqueId = uuidv4()
const uploadTask = storage.ref(`images/${image.name}`).put(image);

then i did this

let uniqueId = uuidv4()
const uploadTask = storage.ref(`images/${uniqueId}`).put(image);

but got an error "Firebase Storage: Invalid argument in put at index 0: Expected Blob or File.

The upload function(i have jsx below that I didn't include at the bottom so don't worry about the closing brackets)

function ImageUpload({username}) {
    const [image, setImage] = useState(null);
    const [progress, setProgress] = useState(0);
    const [caption, setCaption] = useState('');

    const handleChange = (e) => {
        if (e.target.files[0]) {
            setImage(e.target.files[0]);
        }
    };

    const handleUpload = () => {
        let uniqueId = uuidv4()
        const uploadTask = storage.ref(`images/${image.name}`).put(image);

        uploadTask.on(
            "state_changed",
            (snapshot) => {
                const progress = Math.round (
                    (snapshot.bytesTransferred / snapshot.totalBytes) * 100
                );
                setProgress(progress);
            },
            (error) => {
                console.log(error);
                alert(error.message);
            },
            () => {
                storage
                .ref("images")
                .child(image.name)
                .getDownloadURL()
                .then(url => {
                    db.collection("posts").add({
                        timestamp: firebase.firestore.FieldValue.serverTimestamp(),
                        caption: caption,
                        imageUrl: url,
                        username: username                     
                    })
                })
                setProgress(0)
                setCaption('')
                setImage(null)
            }
        )
    }
return(jsx)
}

KALITA
  • 716
  • 2
  • 8
  • 20
  • 1
    if you look at the error it expects a file or blob. You need to show us the "upload code" and how you are uploading to storage and that input file – Cyrus Zei Aug 12 '20 at 21:34
  • @CyrusZei When I put the id, it works for the first image but when I choose the same image to upload it gives me the error , alternatively if I choose another image it works perfectly – KALITA Aug 13 '20 at 06:06
  • @CyrusZei I have added the code , can you check again – KALITA Aug 13 '20 at 06:12

2 Answers2

0

In firebase it's up to you to determine the name of the file you upload. However what i usually do if the image is linked to an account is to use the mAuth id of the logged in user as the directory or simply the filename. This way do you avoid duplicates!

Another way is to use a algorithm that generates unique keys due to date or time, but you still have to double check if that key already exists just to be sure.

There might be another way i don't know, since creating on realtime database creates their own keys somehow.

With the same photo can you simply recursive call the method again and add index to the end of the file, however this method is not that great to use.

For more or better details check this post: Does Firebase storage offer unique Id's for files?

Tobbin2
  • 115
  • 2
  • 7
  • but can you tell me how can i implement the unique id (uuid) instead of the actual `image.name` – KALITA Aug 13 '20 at 06:48
  • Well I actually don't know how to implement that i usually use something online xD However if youre supposed to link the image to an user can you just use his mAuth.uid as the unique key/folder. storage.ref(`images/${mAuth.uid}`), mAuth is used for users in this case. – Tobbin2 Aug 13 '20 at 07:42
0

When you need to use unique Id,

import { v4 as uuid } from "uuid";

const uniqueId = uuid();
const uploadTask = storage.ref(`images/${uniqueId}`).put(image); ....

You need to change its format, like below. And You can read more about it

const uploadTask = storage.ref(`images/${uniqueId}`).putString(image, "data_url");

One more thing you can do is to pass id into the child .child(id) instead of .child(image.name) because as you store the images with unique IDz.

Shaheryar
  • 63
  • 8