Reputation: 516
I'm trying to upload multiple images to firebase at once. It is doing that, but the returned url array of those cloud image links are too late since the post is already being sent with an empty array. Here is my code:
// uploading media files using promises
async uploadMedia(mediaFile: string){
const extension = mediaFile.split('.')[mediaFile.split('.').length - 1];
const mediaFileName = `${Math.round(Math.random()*100000000000)}.${extension}`;
this.uploadProgress = 0;
const response = await fetch(mediaFile);
const blob = await response.blob();
const storageRef = storage.ref(`${mediaFileName}`).put(blob);
return storageRef.on(`state_changed`,snapshot=>{
this.uploadProgress = (snapshot.bytesTransferred/snapshot.totalBytes);
}, error=>{
this.error = error.message;
this.submitting = false;
this.uploadingMedia = false;
return;
},
async () => {
// check whether the media is an image or a video and add to correct arrays
if(extension == "png" || extension == "jpg"){
return storageRef.snapshot.ref.getDownloadURL().then(async (url)=>{
this.firebaseImageUrls = [...this.firebaseImageUrls, url];
return;
});
}
else{
return storageRef.snapshot.ref.getDownloadURL().then(async (url)=>{
this.firebaseVideoUrls = [...this.firebaseVideoUrls, url];
return;
});
}
});
}
Where everything is being called:
await Promise.all(this.props.store.selectedImagesArray.map(async (file:string) => {
await this.uploadMedia(file);
}))
this.submitPost(); // this submits everything with the firebaseImageUrls
any help is appreciated
Upvotes: 0
Views: 169
Reputation: 516
Figured it out. I had to make a promise and resolve the promise for each upload task and then loop through all the files doing this. Then when all the files are completely uploaded and the loop is completed, then I can submit the post with the files that are in firebaseImageUrls.
async uploadMedia(mediaFile: string){
return new Promise(async (resolve, reject) => {
//making the uploading task for one file
const extension = mediaFile.split('.')[mediaFile.split('.').length - 1];
const mediaFileName = `${Math.round(Math.random()*100000000000)}.${extension}`;
const response = await fetch(mediaFile);
const blob = await response.blob();
const storageRef = storage.ref(`${mediaFileName}`);
const task = storageRef.put(blob);
task.on(`state_changed`,snapshot=>{
this.uploadProgress = (snapshot.bytesTransferred/snapshot.totalBytes);
}, error=>{
this.error = error.message;
this.submitting = false;
this.uploadingMedia = false;
return;
},
async () => {
if(extension == "png" || extension == "jpg"){
task.snapshot.ref.getDownloadURL().then((url:any)=>{
console.log(url);
resolve(url);
});
}
else{
task.snapshot.ref.getDownloadURL().then((url:any)=>{
console.log(url);
resolve(url);
});
}
});
})
}
The loop:
for(var i = 0; i < this.props.store.selectedImagesArray.length; i++){
const imageUrl = await this.uploadMedia(this.props.store.selectedImagesArray[i]);
this.firebaseImageUrls = [...this.firebaseImageUrls, imageUrl];
}
this.submitPost();
Upvotes: 0
Reputation: 11317
The problem seems to be that storageRef.on()
does not return a promise. It just registers the handlers. I'm not an expert on firebase. Maybe the put(blob)
returns a promise that you can use.
Upvotes: 1