Firebase storage, new image upload doesn't have a unique name - javascript

I am creating an app using firebase and react.js. When I reload the app, only the very last image shows up, when instead all of them should be loaded on the first page. Here is my handleUpload function where the issue lies (Updated):
const handleUpload = () => {
//const storageRef = ref(storage, `images/${image.name}`);
const randomId = doc(collection(db, "temp")).id;
const storageRef = ref(storage, `images/${randomId}`);
const uploadTask = uploadBytesResumable(storageRef, image);
uploadTask.on(
"state_changed",
(snapshot) => {
//Progress function ... (shows the load bar)
const progress = Math.round(
(snapshot.bytesTransferred / snapshot.totalBytes) * 100
);
setProgress(progress);
},
(error) => {
//Error Function...
console.log(error);
alert(error.message);
},
async () => {
//complete function
const url = await getDownloadURL(storageRef);
const docRef = await addDoc(collection(db, "posts"), {
imageURL: url,
caption: caption,
username: username,
timestamp: serverTimestamp()
});
console.log("THE APP HAS POSTED");
setProgress(0);
setCaption('');
setImage(null);
setUrl('');
}
)
}
Here is my storage console after restarting and posting 2 photos from an iPhone:
There should be 2 photos there, but only the latest one shows up, with the name ${image.name}, which I don't understand because I have that line commented out.
Note: this issue only occurs when someone uploads on a phone since there are no file names on a phone, just a picture from a camera roll. Is there a way to fix this that anyone can think of?

Firebase storage doesn't generate a random ID for new files. You must specify then file name while uploading it. You can use a package like UUID or even Firestore to generate random IDs as shown below:
const randomId = doc(collection(db, "temp")).id
const storageRef = ref(storage, `images/${randomId}`);
Also make sure you add the file extension at the end of filename.
Are you trying to upload image with same name? In that case it'll overwrite the existing image with that name.

Related

Uploading file to Firebase Storage with v9 SDK results in 9 byte file, instead of he actual data [duplicate]

im using react native and firebase (v9) to upload image to firebase. in the firebase storage, the file was uploaded, but the size is only 9 bytes so it's not opening properly. I'm not sure how to fix this :S
const uploadFiles = (file, name, storeKey) => {
if(!file){
console.log('no file exists')
return;
}
const exe = file.substring(file.lastIndexOf('.'));
const fileName = name + exe;
const storageRef = ref(storage, `/files/${fileName}`);
const uploadTask = uploadBytesResumable(storageRef, file);
uploadTask.on('state_changed', null,
(error) => {
alert(error);
},
() => {
getDownloadURL(uploadTask.snapshot.ref)
.then((URL) => {
setDoc(doc(db, 'Store', storeKey, 'coffeeDB', name), {postImage: URL}, {merge: true});
console.log('url registered')
});
}
)
}
Given that you're calling file.substring(...), it seems that file is a file name. You can't upload a file by just passing its name, as that'd be a security risk. Instead you'll need to pass a Blob | Uint8Array | ArrayBuffer as shown here and here, typically by passing the File reference from which you got the file name.

react firebase image post 400 error on uploading

I am trying to upload an image to a cloud storage and received an post 400 error
The file is in initialize in another component.
Thanks for help
const projectStorage = getStorage();
useEffect(() => {
const storageRef = ref(projectStorage, file.name);
uploadBytes(storageRef, file).then((snap) => {
let percentage = (snap.bytesTransferred / snap.totalBytes) * 100;
setProgress(percentage);
console.log('File Uploaded');
}, (err) => {
setError(err);
}, async () => {
//this url doesnt change the setstate url becuase it is in seperate score
const url = await storageRef.getDownloadURL();
setUrl(url);
})
}, [file]);
I created a new project on firebase and then change the permissions on the storage rules and its works.

Firebase v9 uploading image shows only 9 bytes

im using react native and firebase (v9) to upload image to firebase. in the firebase storage, the file was uploaded, but the size is only 9 bytes so it's not opening properly. I'm not sure how to fix this :S
const uploadFiles = (file, name, storeKey) => {
if(!file){
console.log('no file exists')
return;
}
const exe = file.substring(file.lastIndexOf('.'));
const fileName = name + exe;
const storageRef = ref(storage, `/files/${fileName}`);
const uploadTask = uploadBytesResumable(storageRef, file);
uploadTask.on('state_changed', null,
(error) => {
alert(error);
},
() => {
getDownloadURL(uploadTask.snapshot.ref)
.then((URL) => {
setDoc(doc(db, 'Store', storeKey, 'coffeeDB', name), {postImage: URL}, {merge: true});
console.log('url registered')
});
}
)
}
Given that you're calling file.substring(...), it seems that file is a file name. You can't upload a file by just passing its name, as that'd be a security risk. Instead you'll need to pass a Blob | Uint8Array | ArrayBuffer as shown here and here, typically by passing the File reference from which you got the file name.

I'm trying to upload image but image is not adding to cloud firestore, its uploaded on firebase storage But not showing in React app

This is the code for uploading image on React app. Its showing on firebase storage but not added in to cloud firestore. and that's why I am not able to upload any image on React app manually. I've googled and searched so many times but cant fix this.
function Imgupload({username}){
**strong text** const [caption,setCaption]=useState('');
const [image,setImage]=useState(null);
//const [url,setUrl]= useState("");
const [progress,setProgress]=useState(0);
const handlechange = (e)=>{
if(e.target.files[0]){
setImage(e.target.files[0]);
}
};
const handleUpload = () =>{
const uploadTask= storage.ref('images/$ {image.name}').put(image);
uploadTask.on(
"state_change",
(snapshot) =>{
//progress function..
const progress=Math.round(
(snapshot.bytesTransferred/snapshot.totalBytes) * 100
);
setProgress(progress);
},
(error) =>{ //error func..
console.log(error);
alert(error.message);
},
()=>{ //complete func..
storage
.ref("images")
.child(image.name)
.getDownloadURL()
.then (url =>{
//post img on db..
db.collection("posts").add({
timestamp:firebase.firestore.FieldValue.serverTimestamp(),
caption :caption,
imgurl :url,
username :username
});
setProgress(0);
setCaption("");
setImage(null);
});
}
);
}
This is the Error from console:
localhost/:1 Uncaught (in promise) FirebaseError: Firebase Storage: Object 'images/Screenshot (202).png' does not exist. (storage/object-not-found)
{
"error": {
"code": 404,
"message": "Not Found."`enter code here`
}
}
Can't fix this problem. please help.
You have an extra space in the file name here:
const uploadTask= storage.ref('images/$ {image.name}').put(image);
// 👆
You don't have that same space when you call getDownloadURL here:
storage
.ref("images")
.child(image.name)
.getDownloadURL()
So these two code fragments point to different files, which explains why the second fragment can't find the file you uploaded.
I recommend using a single variable to hold the reference, and use that in both fragments:
const imageRef = storage
.ref("images")
.child(image.name);
const uploadTask= imageRef.put(image);
...
imageRef.getDownloadURL()...

How can we update the existing image in firebase cloud storage?

I used react-native-firebase lib in my RN App
and I use Firebase Storage to save image in the cloud so it's work very well but
In profile screen and I have an Edit function that replaces the old image with a new one but it's just adding a new image to Firebase Cloud Storage not replaced it
so there any way for just replacing old with new?
because I don't want to increase my storage when users change his image profile
here is my function that's save new image profile
EditImg = async () => {
const {uid, avatar} = this.state;
let providerRef = database().ref(`Providers/users/${uid}`);
const path = 'Avatar_' + new Date().getTime() + '.jpg';
const ref = storage().ref(`providers/${uid}/providerGalary/${path}`);
await ref.putFile(avatar).then(() => {
ref.getDownloadURL().then(
img => {
console.log('img', img);
providerRef
.update({
avatar: img,
})
.then(() => console.log('saved to Db Successfully'));
},
error => console.log(error),
);
});
};
Change this:
const path = 'Avatar_' + new Date().getTime() + '.jpg';
const ref = storage().ref(`providers/${uid}/providerGalary/${path}`);
await ref.putFile(avatar).then(() => {
Into this:
const path = 'Avatar_' + uid + '.jpg';
const ref = storage().ref(`providers/${uid}/providerGalary/${path}`);
await ref.putFile(avatar).then(() => {
Use the uid instead of new Date, since the uid will stay the same thus you will be able to replace the image instead of adding a new one

Categories

Resources