0

I want to call the setVideos at the ending of the querySnapshot.forEach but I can see in the log that it calls it before the ending of the foreach. My intent is to get download links from a bucket in firebase storage, collect them in the data array and then update videos with the data collected in the array data.

I tried to use for and Promise.all but it says that querySnapshot is not iterable

import React, { useState, useEffect } from "react";
import Video from "./Video";
import "./Home.css";
import RetrivedVideo from "./RetrivedVideo.js";
import { collection, getDocs } from "firebase/firestore";
import { getFirestore } from "firebase/firestore";
import firebaseApp from "./firebase.js";
import { getStorage, ref, getDownloadURL } from "firebase/storage";

export default function Home() {
  const [videos, setVideos] = useState([]);

  useEffect(() => {
    async function fetchData() {
      let data = [];
      const db = getFirestore();
      const storage = getStorage();
      const querySnapshot = await getDocs(collection(db, "videos"));
      querySnapshot.forEach(async (doc) => {
        const path = "videos/" + doc.id + ".mp4";
        const url = await getDownloadURL(ref(storage, path));
        console.log(url);
        const retrivedVideo = new RetrivedVideo(doc.id, url);
        data.push(retrivedVideo);
        console.log("data: " + data);
      });
      setVideos([...videos, ...data]);
      console.log("videos: " + videos);
    }
    fetchData();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <div className="app">
      <div className="container-videos">
        {videos.map((v) => (
          <Video className="video" key={v.id} url={v.url} />
        ))}
      </div>
    </div>
  );
}
  • 1
    Does this answer your question? [Using async/await with a forEach loop](https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop) – Sinan Yaman Aug 17 '21 at 10:58
  • When I use both for and Promise.all it says that querySnapshot is not iterable – mgabriele00 Aug 17 '21 at 11:13

1 Answers1

0

I post the solution I found hooping that can helps. With querySnapshot form firebase firestore you have to use forEach that is a method of querySnapshot, if you need to wait you can collect the data you need from the querysnapshot.forEach in a local vector and then use a for to manipulate the data as you want. In my example I only need the id of the documents:

let docsId = []

querySnapshot.forEach(async (doc) => {
        docsId.push(doc.id);
      });

for (const docId of docsId){
...
}

you can also use Promise.all, to understand the difference please visit Using async/await with a forEach loop