Alexy
Alexy

Reputation: 1090

Load array of object with their id in : react native + firebase

I come from C++, C, Python space and I'm new to react native / JS / back-end world.

I have some issues loading data from firebase. Here is what I want :

My Database :

I want to load the postids[] array from a user and then, load content of every postids[] in this array (according to every postids in the postids[] array).

Here is my code :

    _getPostsFromDatabase() {
    var docRef = firebase.firestore().collection("users").doc(firebase.auth().currentUser.uid);

    return docRef.get().then(function(doc) {
        if (doc.exists) {
          return doc.data()["posts"];
        }
    }).catch(function(error) {
        alert("Error getting document:", error);
    });
  }

  _loadPosts() {

    var new_posts = [];

    this._getPostsFromDatabase()
      .then(res => {

        var i;
        for (i = 0; i < res.length; i++) {

          firebase.firestore().collection("posts").doc(res[i])
            .onSnapshot(function(doc) {
                new_posts.push(doc.data());
                console.log(new_posts); --> This line print correct data 
            });
        }

      })
      .catch(error => console.log(error));

      console.log(new_posts); ---> This line print an empty array

  }

  componentDidMount() {
    this._loadPosts()
  }

So I want this behavior :

  1. In componentDidMount I begine the routine --> this works
  2. loadPosts is loading the postids[] array with _getPostsFromDatabase() function --> this works
  3. Then, I make a for loop to push every object in an array to set the state at the end --> FAIL

At step 3, everything f... up, I made some console log to debug but there is a huge real time issue because evrything is printed randomly.

How can I get my new_posts filled array at the end of the for loop to setState. Maybe I'm wrong with this method, or if I'm not, I must have some issues with Async funtion ?

Is there an expert to help me understund better what is inside this kind of use case ?

Thanks

Upvotes: 0

Views: 607

Answers (2)

Goskula Jayachandra
Goskula Jayachandra

Reputation: 4201

Your console will log before the for loop, that's the reason you are getting an empty array just include your console in the response just like this:

 this._getPostsFromDatabase()
      .then(res => {

        var i;
        for (i = 0; i < res.length; i++) {

          firebase.firestore().collection("posts").doc(res[i])
            .onSnapshot(function(doc) {
                new_posts.push(doc.data());
                console.log(new_posts); --> This line print correct data 
            });
        }
        console.log(new_posts); ---->Include here
      })

Hope this helps!

Upvotes: 1

Tom Slutsky
Tom Slutsky

Reputation: 724

Basically the problem is that you are trying to perform an asynchronous code in a synchronous way. You solution might be waiting for all promises to resolve.

_loadPosts() {

    this._getPostsFromDatabase()
      .then(res => {
       let promises = res.map(id => {
         return firebase.firestore().collection("posts").doc(id)
            .get().then(doc => doc.data())

        })
    Promise.all(promises).then(res => {console.log(res);})





  }

Upvotes: 2

Related Questions