skip to Main Content

I have an application on vue 3. I need to get a link to a document from the repository. At the moment, I always get a promise, which is how it should be. But I should get a link to the document, but it doesn’t. Why is this happening?

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

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

      querySnapshot.forEach((doc) => {
        let films = async (to) => {
          const starsRef = ref(storage, `images/${doc.id}/poster.png`);

          return await getDownloadURL(starsRef);
        };

        // const poster=`gs://cell-11ef4.appspot.com/images/${doc.id}/poster.png`

        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,
          poster: to === "films" ? films() : null,
          // BipPoster: url,
        };

        data.push(item);

        // Get the download URL
      });

      commit("setData", { data, to });
    });
  } catch (err) {
    console.log(err);
  } finally {
    commit("setLoading", false);
  }
}
let url = async () => {
  let url;
  const starsRef = ref(storage, `images/${doc.id}/poster.png`);

  await getDownloadURL(starsRef).then((p) => {
    url = p;
  });

  return url;
};

What i get

enter image description here

enter image description here
enter image description here

3

Answers


  1. Chosen as BEST ANSWER

    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);
      }
    }


  2. You should use Promise.all() as follows:

    const promises = [];
    querySnapshot.forEach((doc) => {
         const starsRef = ref(storage, `images/${doc.id}/poster.png`);
    
         promises.push(getDownloadURL(starsRef));
    });
    
    const urlsArray = await Promise.all(promises);
    
    Login or Signup to reply.
  3. Map the documents collection to an array of promises that resolve with the full item data, including download URL and await them all with Promise.all().

    You’re also registering a real-time updates listener which seems counter to what you seem to want FetchData to do. I would suggest you want to use getDocs() instead of onSnapshot()

    async FetchData({ state, commit }, to) {
      try {
        commit("setLoading", true);
    
        // `onSnapshot` registers a real-time updates listener,
        // use `getDocs` to retrieve documents
        const { docs } = await getDocs(query(collection(db, to)));
    
        // Map over the `docs` array and return fully hydrated objects
        const data = await Promise.all(
          docs.map(async (doc) => ({
            ...doc.data(),
            id: doc.id,
            poster:
              to === "films"
                ? await getDownloadURL(ref(storage, `images/${doc.id}/poster.png`))
                : null,
          }))
        );
    
        commit("setData", { data, to });
      } catch (err) {
        console.error(err);
      } finally {
        commit("setLoading", false);
      }
    },
    

    If you did want to register a real-time updates listener, do so in an effect hook where you can also remove the listener in a cleanup

    useEffect(() => {
      // Return the unsub function as cleanup
      return onSnapshot(query(collection(db, to)), async ({ docs }) => {
        try {
          const data = await Promise.all(
            docs.map(async (doc) => ({
              ...doc.data(),
              id: doc.id,
              poster:
                to === "films"
                  ? await getDownloadURL(
                      ref(storage, `images/${doc.id}/poster.png`)
                    )
                  : null,
            }))
          );
    
          commit("setData", { data, to });
        } catch (err) {
          console.error(err);
        }
      });
    }, [to]);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search