Ari
Ari

Reputation: 6199

How to upload images to firebase storage and wait for URLs to return before continuing

I'm trying to create a "Create Post" form where the user can input text, as well as input images.

uploadImages() {
    const files = document.querySelector('#imagesInput').files;
    files.forEach(image => {
        console.log("uploading", image.name)
        const name = (+new Date()) + '-' + image.name;
        const task = fb.storage.child(name).put(image, {contentType: image.type});
        task.then(snapshot => {
            snapshot.ref.getDownloadURL().then(url => {
                console.log(url);
            })
        })
    });
}

The image upload process needs to happen first, and I need to return all the URLs (as an array) before the post is created in the database.

imageURLs = this.uploadImages(); // <-- Wait for this to complete and return the image URIs
this.createPost("Hello, world!", imageURLs) // <-- then do this

Upvotes: 0

Views: 149

Answers (2)

Renaud Tarnec
Renaud Tarnec

Reputation: 83181

Since you call the asynchronous getDownloadURL() method a variable number of times (i.e. unknown at the time of coding), you need to use Promise.all() as follows:

uploadImages() {
    const files = document.querySelector('#imagesInput').files;

    const promises = [];
    files.forEach(image => {
        console.log("uploading", image.name)
        const name = (+new Date()) + '-' + image.name;
        const task = fb.storage.child(name).put(image, { contentType: image.type });
        promises.push(task);
    });

    return Promise.all(promises)
        .then(snapshotsArray => {
            // snapshotsArray is an array with a variable number of elements
            // You again need to use Promise.all
            const promises = [];
            snapshotsArray.forEach(snapshot => {
                promises.push(snapshot.ref.getDownloadURL());
            })
            return Promise.all(promises);
        });
}

The uploadImages() function is asynchronous and returns a Promise (since Promise.all() and then() return Promises): you therefore need to call it by using then(), as follows:

this.uploadImages()
.then(imageURLs => {
   this.createPost("Hello, world!", imageURLs) 
})

Upvotes: 2

ADITYA RANADE
ADITYA RANADE

Reputation: 293

Add an .addOnSuccessListener to the line where you upload images and add the next part of the code in that

Like this

imageURLs = this.uploadImages().addOnSuccessListener(new OnSuccessListener() 
({

this.createPost("Hello, world!", imageURLs)

});

I am not sure if the code is entirely correct, it will depend on what you are exactly trying to do, but it will give you a general idea of what you need to do

Upvotes: 1

Related Questions