Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

147
Visualizações
Returned array evaluated later from async Firestore calls doesn't update in React

It seems "images" array is first empty and the elements are added later when data is fetched from firestore - but the React state won't update, so no image is displayed, although I used await everywhere possible.

useEffect(() => {
    async function getAllImages() {
      const images = await imageStorage.downloadAllImages(true);
// images is first empty and then populated after the html has been rendered
      setImages(images);
    }
   
      getAllImages();
    
  }, []);

display images:

const handleGetImages = (images) => {
    console.log("images", images); // image is first empty and then populated after the html has been rendered
    return images.map((imageData) => {
      return (
        <Grid.Column key={imageData.url}>
          <span class="image left">
            <img src={imageData.url} style={styles.image} alt="" />
          </span>
        </Grid.Column>
      );
    });
  };

imageStorage.js

export async function downloadAllImages(thumbnail) {
  const imageRef = collection(db, "images");
  console.log("hi");
  var images = [];

  const q = query(imageRef, orderBy("date", "desc"), limit(10));
  const querySnapshot = await getDocs(q);

  querySnapshot.forEach(async (doc) => {
    var imagePath = doc.data().ref; // image/task/...
    if (thumbnail) imagePath = imagePath.replace("images", "thumbnails");
    // GET metadata of the image
    const imageRef = ref(storage, imagePath);

    // GET [imagePrefix] URL
    const url = await getDownloadURL(imageRef);
    const fullMetadata = await getMetadata(imageRef);

    images.push({
      path: imagePath,
      url: url,
      metadata: fullMetadata.customMetadata,
    });
  });

  return images;
}

Any way to fix this? Thanks!

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

Your code is close. Array.prototype.forEach is synchronous though. I suspect your downloadAllImages function isn't waiting for the loop callbacks to complete and returns the images array not populated yet.

Refactor the logic to create an array of Promises (the async callback functions) and await Promise.all them, then you'll have a populated array of images to return.

export async function downloadAllImages(thumbnail) {
  const imageRef = collection(db, "images");

  const q = query(imageRef, orderBy("date", "desc"), limit(10));
  const querySnapshot = await getDocs(q);

  // Map querySnapshot docs to array of async functions (Promises)
  const imageRequests = querySnapshot.docs.map(async (doc) => {
    const imagePath = doc.data().ref; // image/task/...
    if (thumbnail) imagePath = imagePath.replace("images", "thumbnails");
    // GET metadata of the image
    const imageRef = ref(storage, imagePath);

    // GET [imagePrefix] URL
    const url = await getDownloadURL(imageRef);
    const fullMetadata = await getMetadata(imageRef);

    // Return image objects
    return {
      path: imagePath,
      url: url,
      metadata: fullMetadata.customMetadata,
    };
  });

  // Return array of resolved promises (i.e. the image objects)
  return Promise.all(imageRequests);
}
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda