Home > Back-end >  async/await with firebase storage
async/await with firebase storage

Time:09-20

I have a function that receives data, I use an asynchronous promise to get a link to the document item.poster = await Promise.all(promises), then the data does not have time to be added to the array and I get an empty array. But if I remove the function where I get the link to the document, then everything works fine. In debug mode, I can see all the data fine, but why am I getting an empty array?

 async FetchData({ state, commit }, to) {
      try {
      
        const q = query(collection(db, to));

        await onSnapshot(q, (querySnapshot) => {
          let data = [];

          querySnapshot.forEach(async (doc) => {

            let promises = [];
            let item = {
              id: doc.id,
              name: doc.data().name,
              slug: doc.data().slug,
              country: doc.data().country,
              duration: doc.data().duration,
              year: doc.data().year,
              video: doc.data().video,
              genres: doc.data().genres,
              actors: doc.data().actors,
            };
            if (to === "films") {
              const starsRef = ref(storage, `images/${doc.id}/poster.png`);

              promises.push(getDownloadURL(starsRef));
              item.poster = await Promise.all(promises);
            }
            data.push(item);
          });
          commit("setData", { data, to });
        });
      } catch (err) {
        console.error(err);
      } }

enter image description here

CodePudding user response:

forEach and async do not work nice together, forEach is not awaitable. But the solution is simple, .map and Promise.all():

async FetchData({ state, commit }, to) {
  try {
    const q = query(collection(db, to));

    await onSnapshot(q, (querySnapshot) => {
      const allPromises = querySnapshot.docs.map(async (doc) => {
        let item = {
          id: doc.id,
          name: doc.data().name,
          slug: doc.data().slug,
          country: doc.data().country,
          duration: doc.data().duration,
          year: doc.data().year,
          video: doc.data().video,
          genres: doc.data().genres,
          actors: doc.data().actors
        };
        if (to === "films") {
          const starsRef = ref(storage, `images/${doc.id}/poster.png`);
          item.poster = await getDownloadURL(starsRef);
        }
        return item;
      });
      Promise.all(allPromises)
        .then((data) => commit("setData", { data, to }))
        .catch(console.error);
    });
  } catch (err) {
    console.error(err);
  }
}
  • Related