Skip to content Skip to sidebar Skip to footer

Firebase Web: Upload Multiple Files To Storage An Then Download Their Urls

I am creating a blogging website, and am writing code that does the following in order: 1. stores multiple photos that the user uploads 2. download their URLs 3. save them to the r

Solution 1:

Each time you call storageRef.put(...) it starts an asynchronous operation. Right now your `` doesn't wait for these asynchronous operations to complete, and instead returns the list of URLS before it's been populated.

The easiest way to see this is by adding some simple logging to your code:

functionurl_array_get(){
  returnnewPromise(function(resolve,reject){
    let filez=review_photo.files;
    let urlarray=[];
    let user=firebase.auth().currentUser;
    let files=Array.from(filez);
    files.forEach(function(file) {
        console.log("Starting to put file...");
        let storageRef=firebase.storage().ref('data/'+user.uid+'/posts/'+file.name);
            storageRef.put(file).then(function(snapshot){
                console.log("Upload done, getting download URL...");
                snapshot.ref.getDownloadURL().then(function(url) {
                    console.log("Download URL gotten, adding to array...");
                    urlarray.push(url);
                })
            })
        });
    if (!urlarray){
        reject("oops");
    }
    else {
        console.log("Resolving with "+urlarray.length+" download URLs");
        resolve(urlarray);
    }
  });
}

When you run this code, the output will look like:

Starting to put file...

Starting to put file...

Starting to put file...

Resolving with 0 download URLs

Upload done, getting download URL...

Download URL gotten, adding to array...

Upload done, getting download URL...

Download URL gotten, adding to array...

Upload done, getting download URL...

Download URL gotten, adding to array...

That is not the order you want of course, as you're returning the array before you added any download URL to it, and even before any of the uploads complete.


The solution is (as always when it comes to asynchronous operations) to wait until all operations have finished before resolving/returning. You can most easily do this with Promise.all() with something like this:

functionurl_array_get(){
    let promises = [];
    let filez=review_photo.files;
    let user=firebase.auth().currentUser;
    let files=Array.from(filez);
    files.forEach(function(file) {
        let storageRef=firebase.storage().ref('data/'+user.uid+'/posts/'+file.name);
        promises.push(
            storageRef.put(file).then(function(snapshot){
                return snapshot.ref.getDownloadURL()
            })
        });
    });
    returnPromise.all(promises);
}

Or slightly shorter:

functionurl_array_get(){
    let user=firebase.auth().currentUser;
    let ref = firebase.storage().ref('data/'+user.uid+'/posts/');
    let files=Array.from(review_photo.files);
    let promises = files.map(function(file) {
        return ref.child(file.name).put(file).then(function(snapshot){
            return snapshot.ref.getDownloadURL()
        })
    });
    returnPromise.all(promises);
}

Post a Comment for "Firebase Web: Upload Multiple Files To Storage An Then Download Their Urls"