0

I'm using the Firebase api to get a list of all the files in a directory and then I have a forEach loop where I'm getting the urls and pushing them into a temporary array. At the end of that I setUrls to the temporary array but when I console log urls it's empty. I think I need to add async and await to the code and I've tried that and it doesn't work probably because the structure of the code is wrong but I can't find any examples on how to do this the right way.

import React, { useState, useEffect, useRef } from 'react';
import firebase from "firebase/app";
import storage from "firebase/storage";
import  firebaseConfig from "../dropzone/config";

import {
    BrowserRouter as Router,
    Switch,
    Route,
    Link,
    useRouteMatch,
    BrowserRouter,
    useParams
  } from "react-router-dom";


if (!firebase.apps.length) {
    firebase.initializeApp(firebaseConfig);

}else {
    firebase.app(); // if already initialized, use that one
}

  

const FolderPage =  () => {

    let {folder} = useParams();
  
    let fb_storage = firebase.storage();
    let storageRef = fb_storage.ref();  
    
    let rootRef = storageRef.child(folder);
    console.log(rootRef);

    const [files, setFiles] = useState([]); 
    const [urls, setUrls] = useState([]);      


    const fileNames = async () =>{
       
        rootRef.listAll().then( async function(res) {
            let temp = [];
            
            res.prefixes.forEach(function(folderRef) {
               
            });
            
            res.items.forEach( async function(itemRef) {
                // All the items under listRef.
                temp.push(itemRef.name)
                console.log(itemRef.name);

               


            });
            setFiles(temp);

            
            
            }).catch(function(error) {
            // Uh-oh, an error occurred!
            });
            
            let tempUrls = [];

            
            files.forEach(async function(file){
                var fileRef =  storageRef.child( folder + '/' + file);

                // Get the download URL
               await fileRef.getDownloadURL()
                    .then((url) => {
                    
                        tempUrls.push(url);
                        // console.log(tempUrls)
                    })
                    .catch((error) => {
                    
                        switch (error.code) {
                        case 'storage/object-not-found':
                            // File doesn't exist
                            break;
                        case 'storage/unauthorized':
                            // User doesn't have permission to access the object
                            break;
                        case 'storage/canceled':
                            // User canceled the upload
                            break;
                    
                        // ...
                    
                        case 'storage/unknown':
                            // Unknown error occurred, inspect the server response
                            break;
                        }
                    });

            })
            
            setUrls(tempUrls);
            console.log(urls);

            
    }

    useEffect(()=>{
        fileNames();
    },[])

    
    


    return (
        <>
            <div>hello {folder}</div>
            {/* <div>hello {folders}</div> */}

            <ul>
                {files.map((file, index) => {
                    return <li key={index}> {file}</li>
                })}
            </ul>

            <div>
                {urls.map((url, index) => {
                   return <a key={index} href={url}> {url} </a>
                })}
                
            </div>

        </>
    )
}

export default FolderPage
oxxi
  • 452
  • 3
  • 11
  • 28
  • 1
    `forEach` doesn't wait. Use a for...of loop instead. – Phix Feb 16 '21 at 23:11
  • I used a for of loop and it doesn't work. Do you have example code that you could show? Do all of the forEach need to be converted? I did this: ` for (const file of files){ var fileRef = storageRef.child( folder + '/' + file);` – oxxi Feb 16 '21 at 23:47
  • 1
    There's lots of examples on the site, i.e. [this one](https://stackoverflow.com/questions/53149138/use-async-foreach-loop-while-fetching-data-from-firestore). Search for `async foreach`. – Phix Feb 17 '21 at 00:19

0 Answers0