0

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 :

  • users : uid : postids[]
  • posts : postids : content

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

2 Answers 2

2

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);})





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

1 Comment

Thanks you, it works as expected. Very clear ! I missed the map features and Promise.
1

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!

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.