Home > Enterprise >  Using listAll to map through images in Firebase Storage and pushing an object containing getDownload
Using listAll to map through images in Firebase Storage and pushing an object containing getDownload

Time:11-02

I created custom hook that gets images from my Firebase storage and returns it as an array of objects. Each object contains the name of the image file and the URL. With my current code, each object in the array contains the file name but the URL is a Promise object. Please check this picture enter image description here.

If I was to instead just return the URL only and not in an object, it works fine. It seems like it is not waiting for each Promise to resolve before setting the state? I am out of ideas! Thanks if you have any suggestions.


import { getStorage, ref, listAll, getDownloadURL } from "firebase/storage";
import { useState, useEffect } from "react";

export const useLogos = () => {
  const storage = getStorage();
  const listRef = ref(storage, "images/logos");
  const [logoList, setLogoList] = useState([]);

  useEffect(() => {
    listAll(listRef)
      .then((res) => {
        const promises = [];
        res.items.map((itemRef) => promises.push({name: itemRef.name, logoURL: getDownloadURL(itemRef)}));
        return Promise.all(promises)
      })
      .then((urlArray) => {
        setLogoList(urlArray);
      });
  }, []);

  return { logoList }
};

CodePudding user response:

You have to pass an array of Promises to Promise.all() but you pass an array of objects.

The following refactoring should do the trick (untested):

useEffect(() => {
    let fileNamesArray;
    listAll(listRef)
        .then((res) => {
            fileNamesArray = res.items.map((itemRef) => itemRef.name);
            const promises = res.items.map((itemRef) => getDownloadURL(itemRef));
            return Promise.all(promises)
        })
        .then((urlsArray) => {
            const objectsArray = urlsArray.map((elem, index) => ({ name: fileNamesArray[index], logoURL: elem }));
            setLogoList(objectsArray);
        });
}, []);
  • Related