0

I try to get URL of pictures stored in the Firebase Storage. Following the reading of Firebase's documentation, I understand that I need to use the function getDownloadURL() which return a promise. The following code is the closest solution that I get for the moment.

getUserPicture(data: UserItem[]) {
data.forEach( async  (item) => {
  const storage = firebase.storage();
  const pathReference = storage.ref(item.userId + '/profile.jpg'); 

  item.picture = await pathReference.getDownloadURL()
  .then((url) => {
      return url.toString();
   })
   .catch((error) => {
       console.error(error);
   });
   console.log('TEST : item.picture: ' + item.picture + ' for user: ' + item.lastname );  
});

}

The console.log return the URL of the profile picture for each user. Unfortunately, the call of the function getUserPicture() does not get the job done (item.picture are still undefined). I think it's because the top function should be async in order to wait the process in the loop.

Do you know how to resolve such problem?

ZioTonio
  • 79
  • 2
  • 10

1 Answers1

2

You should not use async/await within a forEach() loop, see "JavaScript: async/await with forEach()" and "Using async/await with a forEach loop".

And since you execute a variable number of calls to the asynchronous getDownloadURL() method in parallel, you should use Promise.all(), as follows:

async getUserPicture(data: UserItem[]) {

    const storage = firebase.storage();
    const promises = [];

    data.forEach((item) => {
        const pathReference = storage.ref(item.userId + '/profile.jpg');
        promises.push(pathReference.getDownloadURL());
    });

    const urlsArray = await Promise.all(promises)

});
ZioTonio
  • 79
  • 2
  • 10
Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
  • Thanks Renaud. It means that I will need to do another loop after the promise.all in order to assign the right user.picture to each user (by using urlsArray). If my understanding is right, I can't do it directly in the first loop. – ZioTonio Sep 27 '22 at 16:09
  • Yes you are right. You cannot do it in the first loop: The goal of this first loop is to build an array of Promises that are passed to `Promise.all()`which is asynchronous. It's only when the execution of `Promise.all()` is complete that you have the array of URLs. – Renaud Tarnec Sep 27 '22 at 17:20