0

I want to display the list of all the files and their download URLs from Firebase using React JS. But I can't do so because there are two separate functions for listing(listAll()) and getting the URLs (getDownloadUrl()).

storageRef.listAll().then( res => {

        const download = []

        res.items.forEach( down => {
         down.getDownloadURL().then( url => {

       //  res.items.forEach( item => {

          download.push(url); 
         // console.log(url)
        })
        this.setState({ download: download})
      })
})

storageRef.listAll().then( res => {

        const listItem= []

        res.items.forEach( item=> {


       //  res.items.forEach( item => {

          itemList.push(url); 

        })
        this.setState({ itemList: itemList})
      })
})

2 Answers2

1

If I understand correctly you want to add the download URLs of all files to the state. In that case, you're looking for Promise.all(), in something like this:

storageRef.listAll().then( res => {
    let promises = res.items.forEach( item => item.getDownloadURL() );

    Promise.all(promises).then((downloadURLs) => {
        this.setState({ download: downloadURLs });
    });
})

If you also want to store a list of items in the state, you can do that in the same callback:

storageRef.listAll().then( res => {
    let promises = res.items.forEach( item => item.getDownloadURL() );

    Promise.all(promises).then((downloadURLs) => {
        this.setState({ download: downloadURLs, itemList: res.items });
    });
})
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • I actually want both the item list and the download URLs to be on the same map. So that I can actually use the item list to show the corresponding download URL in a table. But as there are two loops I can't figure out how to render the table with both the list and the URL. Can you help with the render? – Hari Perisetla May 25 '20 at 04:33
  • You don't need two loops, one is enough. My second snippet does precisely that: it adds an array of download URLs and an array of items. – Frank van Puffelen May 25 '20 at 14:31
0

You need to wait for the getDownloadURL() promise to resolve, and then you can store the value of the item + URL:

const accum = [];
projectStorage.ref(rootPath).listAll().then(res => {
    if (res.items && res.items.length > 0) {
        res.items.forEach(item => {
            item.getDownloadURL().then(url => {
                accum.push({name: item.name, url: url})
            })
        })
    }
});
lejlun
  • 4,140
  • 2
  • 15
  • 31
Nacho
  • 119
  • 1
  • 3