skip to Main Content

I have a React project where i get photo URLs from firebase storage (getPhotoArray function) I have the correct urls being console logged when i click the button, but it doesnt show on my page.

I have multiple photos in the firebase storage folder and i am getting the right amount and right photos console logged in the array(in getPhotoArray function)


export const getPhotoArray = async (selectedDonation, setPhotos) => {
  const listRef = ref(storage, '/Images/'+selectedDonation.id);
  const images = []
  listAll(listRef)
    .then((res) => {
      if (res.items.length > 0) {
        res.items.forEach((itemRef) => {
          // Get the download URL
          getDownloadURL(ref(storage, itemRef.fullPath))
          .then((url) => {
            images.push(url)
          })
          .catch((error) => {
          });
        });
        setPhotos(images)
        console.log(images)
      }else {
        toast.info('No Photos Found, Please Try Again Later')
      }
    }).catch((error) => {

    });   
}
import React, {useEffect, useMemo, useState} from 'react'
import './donation_information.css'
import {getReceiptURL, getPhotoArray} from '../../API/FirestoreAPI' 

export default function DonationInformation({ selectedDonation, selectedDonationSteps }) {
  const [Photos, setPhotos] = useState([]);
 
  const getPhotos = () => {
    getPhotoArray(selectedDonation, setPhotos)
  }

 useEffect(() => {
  setURL('')
  setPhotos([])
 }, [selectedDonation]);

  return (
    <div className='donationInformation'>
        <div className='download-photos'>
          <button onClick={getPhotos}>Show Photos</button>
          {
            useMemo(() => {
              Photos.map((photo) => {
                return <img src="photo" key={photo} alt="" />
              })
            }, [Photos])
          }
        </div>
        </div>
    </div>
  )
}

I have tried wrapping the Photos.map with useEffect, thats the only thing i could think of

2

Answers


  1. You need to add curly braces {} to your <img src attribute instead of double quotes as src is set to a variable photo. Also set a width and height

    Your current code :

    return <img src="photo" key={photo} alt="" />

    needs to be updated to

    return <img src={photo} key={photo} alt="" width="500" height="600"/>

    Login or Signup to reply.
  2. Problem is with this code:

        res.items.forEach((itemRef) => {
          // Get the download URL
          getDownloadURL(ref(storage, itemRef.fullPath))
          .then((url) => {
            images.push(url)
          })
          .catch((error) => {
          });
        });
        setPhotos(images)
    

    Each forEach iteration does not wait for getDownloadURL to resolve, so your setPhotos(images) gets called before all URLs are pushed.

    In order to wait for the URLs to load, you need to use async/await:

      listAll(listRef)
        .then(async (res) => {  // <-- remember this `async` keyword. otherwise, using `await` will throw an error
          if (res.items.length > 0) {
            for (const item of res.items) {
              const url = await getDownloadURL(ref(storage, itemRef.fullPath))
              images.push(url)
            }
            setPhotos(images)
    ...
    

    On a side note, sending a state setter to the external method doesn’t feel like the best approach. You’d better return the image URLs from the method and then set that as your state inside the component.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search