Toni
Toni

Reputation: 21

Read Data from Firebase and save it into an Array - React

i just can't figure out why i can't save my loaded data into an array.

i`m trying to push the data to the array once the data is fully loaded (Within then())

Any idea why it's not working?

Many thanks :)

useEffect(() => {

  fetchData = async () => {
  
  let tempArray = [];
  
  await firebase.firestore().collection('users').get().then((querySnapshot) => {
    querySnapshot.forEach((doc) => {
      firebase.firestore().collection('users').doc(doc.id).collection('posts').get().then((snapShot) => {
        snapShot.forEach((newDoc) => {
          tempArray.push({
            id: doc.id,
            data: newDoc.data()
          })
        })
      })
    })
  })
  
  console.log(tempArray) // Output: Array []
  
  }

 fetchData();

}, [])

Upvotes: 0

Views: 639

Answers (1)

LeadDreamer
LeadDreamer

Reputation: 3499

.forEach IS NOT ASYNCHRONOUS - it WILL NOT wait for your inner-loop .get()s. You need to do something like:

  await firebase.firestore().collection('users').get().then((querySnapshot) => {
    Promise.all(querySnapshot.map((doc) => {
      firebase.firestore().collection('users').doc(doc.id).collection('posts').get().then((snapShot) => {
        snapShot.forEach((newDoc) => {
          tempArray.push({
            id: doc.id,
            data: newDoc.data()
          })
        })
      })
    })
    )
  })

In addition - this seems pretty dang inefficient - since you're fetching ALL your users, and ALL their posts, you could just use a collectionGroup is a SINGLE round-trip, then sort by .parent if you need sorting (you don't show any such need in the example presented)

await firebase.firestore()..collectionGroup('posts').get().then((querySnapShot) => {
      querySnapShot.forEach((newDoc) => {
        tempArray.push({
          id: doc.id,
          data: newDoc.data()
        })
      })
    })

Finally, you're mixing async/await with .then() syntax, which is generally not recommended:

// .get() is asynchronous
const querySnapShot = await firebase.firestore()..collectionGroup('posts').get();
// push() is synchronous, so need for await
querySnapShot.forEach((newDoc) => {
  tempArray.push({
    id: doc.id,
    data: newDoc.data()
  })
})

Upvotes: 3

Related Questions