retrieving images from firebase storage to show in a component

Viewed 44

I'm trying to retrieve my images from a folder inside my firebase storage, I've tried to store the URL in an array and then attempted to map through and use the URLs to render them in a component but I'm unable to do so. I've tried multiple attempts but can't figure out why, I believe it's a promise that hasn't been resolved but again, unable to work it out. id like this to load when the ViewPhotos component has loaded. am I going about this in the completely wrong direction?

    const ViewPhotos = () => {
    const [imgData, setImgData] = useState([])

    let getData = () => {
        const storage = app.storage()
        const storageRef = storage.ref('test/')
        const newImg = storageRef.list()
        newImg.then((res) => {
            res.items.map((item)=> {
                let url = item.getDownloadURL()
                setImgData([...imgData, url])
            })
        })
        
    }

    const ListDisplay = ({ url }) => {
        return (
            <div>
                <img src={url}/>
            </div>
        )
    }
    useEffect(() => {
            getData()
    },[])

        return(
            <div id="viewPhotos">
                <h3>view photos component</h3>
                <div>
                {imgData.map(url => {
                    return <ListDisplay url={url} />
                })}
                </div>
            </div>
        )
}
2 Answers

I think you're almost there. The getDownloadURL() method also returns a promise, so you need to wait for that to resolve before calling setImgData:

newImg.then((res) => {
    res.items.map((item)=> {
        item.getDownloadURL().then((url) => {
            setImgData([...imgData, url]);
        });
    })
})

After a couple of tweaks I got the result I was after, my array and new item weren't concatenating and after each re-render it would add the same url again. Anymore further suggestions would be great, but case closed.

const ViewPhotos = () => {
    const [imgData, setImgData] = useState([])

    let getData = () => {
        const storage = app.storage()
        const storageRef = storage.ref('test/')
        const newImg = storageRef.list()
        newImg.then((res) => {
            res.items.map((item)=> {
                item.getDownloadURL().then((url) => {
                    imgData.includes(url) ?
                        console.log('url already there') :
                        setImgData(imgData => [...imgData, url])
                })
            })
        })   
    }
    
    const ListDisplay = ({ url }) => {
        return (
            <div className="listDisplayWrapper">
                <img src={url}/>
            </div>
        )
    }
    useEffect(() => {
            getData()
    },[])

        return(
            <div id="viewPhotos">
                <h3>view photos component</h3>
                <div>
                {imgData.map(url => {
                    return <ListDisplay url={url} />
                })}
                </div>
            </div>
        )
}
Related