1

I am trying to make a 'facebook kind of newsfeed' in React with Firebase Firestore. In the componentDidMount I first get the friendslist and per friend I will get their activities which I push to an empty array and sort() + reverse() the id's which are timestamps. This way the newest activity will be first in the array. Once ALL the items are pushed to the array, I want to set the state with the array. This is the code that I have:

import React, { Component } from 'react'
import { db, firebaseAuth } from '../../helpers/base'
import Activities from './Activities'

export default class ActivityList extends Component {
  state = {
    activityKeys: [],
  }

  componentDidMount(){
    const uid = firebaseAuth().currentUser.uid
    var activityKeys = []

    db.doc(`users/${uid}/social/friends`).get().then( (doc) => {      
      //GET ALL THE FRIENDS
      const friends = doc.data() //OBJECT OF {friendOneId: "friendOneId", friendTwoId: "friendTwoId"}

      //LOOP THROUGH FRIENDS AND GET ACTIVITY     
      Object.keys(friends).forEach( friend => {          
        db.collection("activity").where("user", "==", friend).get().then((querySnapshot) => {
          querySnapshot.forEach( (doc) => {

          const activity = doc.id
          activityKeys.push(activity)
          activityKeys.sort().reverse()                   
          })                      
        })         
      }) 
    })    
    console.log('activityKeys: ', activityKeys)
    this.setState({ activityKeys })                               
  }

 render () {
   return (
     <div>
       <h5>Activity List</h5>
       <Activities activityKeys={this.state.activityKeys} />        
     </div>
    )
  }
}

The problem is that the array isn't set correctly or that it maybe is set before all the items are pushed. This is the log that I get: enter image description here

It looks like it is loaded but it is empty between the brackets. If I console.log This.state.activity I get the same result. Can someone tell me how to fix this? And how can I setState once all the activities are pushed to the empty array?

1 Answer 1

2

You get a Promise when you make a call to API, but you set this.setState({ activityKeys }) before the call has completed. In other words, you must chain another .then() after the data has been received, in which you will call this.setState({ activityKeys }). What makes it a little difficult is that you're creating many Promises when iterating with forEach, and you need to wait for each of them to complete. You could save them all to list, and use Promise.all to wait for their completion and return it from the previous .then. Read more on the promises: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.