Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

331
Views
¿Usar firebase onSnapshot() en for loop?

El siguiente código funciona para obtener mis datos de firestore. Estoy tratando de actualizar esto para usar onSnapshot() en lugar de get() . Tal vez el núcleo de mi confusión es onSnapshot() no devuelve una promesa y he intentado simplemente agregar los oyentes en una matriz, pero parece que los datos no se actualizan. ¿Cómo itero sobre un bucle for de onSnapshot() y renderizo los resultados?

 const [activityDataArray, setActivityDataArray] = useState([]); const userActivityIds = userData.activities useEffect(() => { let promises = []; for (const activityId of userActivityIds) { promises.push(getFirestoreData("activities", activityId)); } Promise.all(promises).then(response => setActivityDataArray(response)); }, [userActivityIds]);

CÓDIGO ACTUALIZADO: cuando hago console.log() la matriz tiene mis datos, pero creo que esto es un truco con las herramientas de desarrollo de Chrome que muestran nueva información. Creo que cuando llamo a setActivityDataArray lo está ejecutando en una matriz vacía y luego nunca más se vuelve a llamar. Por lo tanto, los datos no se procesan a menos que cambie a una pestaña diferente en mi aplicación y regrese. Luego se procesa correctamente (así que sé que los datos son buenos, es solo un problema de procesamiento). Creo que necesito volver a renderizar dentro de onSnapshot() pero, ¿cómo hago esto correctamente?

 const [activityDataArray, setActivityDataArray] = useState<any>([]); const userActivityIds: string[] = userData.activities useEffect(() => { let activityDataArrayDummy: any[] = [] for (const i in userActivityIds) { firebase.firestore().collection("activities").doc(userActivityIds[i]) .onSnapshot((doc) => { activityDataArrayDummy[i] = doc.data(); }); } console.log("activityDataArrayDummy", activityDataArrayDummy) setActivityDataArray(activityDataArrayDummy); }, [userActivityIds]);
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

Simplemente llamar a onSnapshot() en un bucle debería hacerlo.

 import { doc, onSnapshot } from "firebase/firestore"; for (const activityId of userActivityIds) { // get reference to document const docRef = doc(db, "activities", activityId) onSnapshot(docRef, (snapshot) => { // read and render data from snapshot }) }

Sin embargo, si alguna vez necesita cancelar la suscripción de cualquiera de los oyentes, es posible que deba almacenar la función Unsubscribe devuelta por onSnapshot en algún lugar del estado.


En caso de que tenga 10 elementos o menos en userActivityIds , puede usar onSnapshot() con una Query en su lugar:

 const q = query(collection(db, "activities"), where(documentId(), "in", userActivityIds)); onSnapshot(q, (querySnapshot) => { // ... })
about 4 years ago · Juan Pablo Isaza Report

0

Fui con esto. Aparentemente, no se garantiza que el estado en reacción se actualice, por lo que la forma correcta de configurar el estado con datos actualizados es usar una función de devolución de llamada.

https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

 const [activityDataObj, setActivityDataObj] = useState({}) const userActivityIds: string[] = userData.activities useEffect(() => { for (const i in userActivityIds) { firebase.firestore().collection("activities").doc(userActivityIds[i]) .onSnapshot((doc) => { setActivityDataObj((activityDataObj) => { return {...activityDataObj, [userActivityIds[i]]: doc.data()} }) }); } }, [userActivityIds]);
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!