En mi gancho personalizado, obtengo todas las imágenes de la colección firestore. Eso funcionó bien HASTA que intenté obtener también metadatos de imágenes. Cuando agregué la función getMetaData, no puedo configurar los datos para indicar que incluso los datos parecen estar bien en una matriz. Vea el código por favor.
import { useState, useEffect } from "react"; import { firebaseFireStore } from "../firebase/config"; import { storage } from "../firebase/config"; import { ref, getMetadata } from "firebase/storage"; const useFirestore = (collection) => { const [docs, setDocs] = useState([]); useEffect(() => { const unsub = firebaseFireStore .collection(collection) .onSnapshot((snap) => { let documents = []; snap.forEach((doc) => { const forestRef = ref(storage, doc.data().url); getMetadata(forestRef) .then((metadata) => { documents.push({ ...doc.data(), metadata, id: doc.id }); return documents; }) .catch((error) => { console.log(error); }); }); setDocs(documents); console.log(docs); // [] EMPTY ARRAY, PROBLEM IS HERE. console.log(documents); // [] length:13 data is complete inside. }); return () => unsub(); // this is a cleanup function that react will run when // a component using the hook unmounts }, []); return { docs }; }; export default useFirestore;Por lo tanto, incluso si la matriz de documentos tiene los datos con metadatos, no se puede establecer en el estado de los documentos. Cualquier ayuda apreciada.
No puede registrar el estado de los docs justo después de poner en cola una actualización de estado, ya que React procesa las actualizaciones de estado de forma asincrónica. Pero este no es exactamente su problema o lo que realmente está tratando de resolver. El código está mapeando sobre la instantánea y poniendo en cola una solicitud asíncrona para recuperar metadatos y mutando asíncronamente la matriz de documents que se actualizó en React hace mucho * tiempo. console.log(documents) solo expone esta mutación más adelante cuando el navegador procesa el búfer de registro.
Para resolverlo, sugiero declarar la devolución de llamada snapshot.forEach async para que pueda esperar a que se resuelva la llamada getMetadata . Use una actualización de estado funcional para fusionar superficialmente cada documento a medida que se resuelve con metadatos.
Ejemplo:
useEffect(() => { const unsubscribe = firebaseFireStore .collection(collection) .onSnapshot((snap) => { snap.forEach(async (doc) => { try { const forestRef = ref(storage, doc.data().url); const metadata = await getMetadata(forestRef); setDocs(documents => [ ...documents, { ...doc.data(), metadata, id: doc.id } ]); } catch(error) { console.log(error); }; }); }); return unsubscribe; }, []);* "Hace mucho tiempo" -> algún ciclo de render anterior.