Firebase v9 uploading image shows only 9 bytes - javascript

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.

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.

ionic Angular 9 wait until file download url is available

I am using ionic 5 and angular 9 to upload a data url to firebase storage. My code works good but i am not sure how to wait until the download url is avaialble.
below is the code
uploadToFireStore(imageData){
const storage = getStorage();
const storageRef = ref(storage, (new Date().getTime().toString()));
uploadString(storageRef, imageData, 'data_url').then((snapshot) => {
getDownloadURL(snapshot.ref).then((downloadURL) => {
console.log('File available at', downloadURL);
this.downloadURL = downloadURL
});
});
}
I am calling it in my camera plugin like this
this.uploadToFireStore(base64Image)
console.log("updated with url:", this.downloadURL)
currently the download url is printed later and my code is not waiting for download url to be there. I need this url to upload to my RTDB so please advise how can i do it without moving the code into this part
getDownloadURL(snapshot.ref).then((downloadURL) => {
...
You probably just need to return your promise chain:
uploadToFireStore(imageData){
const storage = getStorage();
const storageRef = ref(storage, (new Date().getTime().toString()));
return uploadString(storageRef, imageData, 'data_url').then((snapshot) => {
return getDownloadURL(snapshot.ref).then((downloadURL) => {
console.log('File available at', downloadURL);
this.downloadURL = downloadURL
});
});
}
Then you can do this:
this.uploadToFireStore(base64Image).then(() => {
console.log("updated with url:", this.downloadURL)
});

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 storage, new image upload doesn't have a unique name

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.

How to zip files PDF from a Storage in NodeJS

I need to create a zip file with any PDF what I recieved from Storage AWS, and I am trying do this with ADM-zip in NodeJS, but i cant read the final file.zip.
Here is the code.
var zip = new AdmZip();
// add file directly
var content = data.Body.buffer;
zip.addFile("test.pdf", content, "entry comment goes here");
// console.log(content)
// add local file
zip.addLocalFile(`./tmp/boletos/doc.pdf`);
// // get everything as a buffer
var willSendthis = zip.toBuffer();
console.log(willSendthis)
// // or write everything to disk
zip.writeZip("test.zip", `../../../tmp/boletos/${datastring}.zip`);
As it is this only creates a .zip for each file..zip
I was also facing this issue. I looked through a lot of SO posts. This is how I was able to create a zip with multiple files from download urls. Please keep in mind, I'm unsure this is best practice, or if this is going to blow up memory.
Create a zip folder from a list of id's of requested resources via the client.
const zip = new AdmZip();
await Promise.all(sheetIds.map(async (sheetId) => {
const downloadUrl = await this.downloadSds({ sheetId, userId, memberId });
if (downloadUrl) {
await new Promise((resolve) => https.get(downloadUrl, (res) => {
const data = [];
res.on('data', (chunk) => {
data.push(chunk);
}).on('end', () => {
const buffer = Buffer.concat(data);
resolve(zip.addFile(`${sheetId}.pdf`, buffer));
});
}));
} else {
console.log('could not download');
}
}));
const zipFile = zip.toBuffer();
I then used downloadjs in my React.js client to download.
const result = await sds.bulkDownloadSds(payload);
if (result.status > 399) return store.rejectWithValue({ errorMessage: result?.message || 'Error', redirect: result.redirect });
const filename = 'test1.zip';
const document = await result.blob();
download(document, filename, 'zip');

Categories

Resources