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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.