Reputation: 173
I am coding for my React Native app and I am having trouble getting the data from the firebase return outside of the firebase.firestore().collection("test_data").doc(ID)
loop. Whenever I check the dataArray
variable after the loop it is empty. If I check it within the loop, the data is there. I think that it is a scope problem, but I just do not understand it. I also cannot call any user defined functions inside of the loop.
try {
let dataArray = [];
// get the document using the user's uid
firebase.firestore().collection("users").doc(uid).get()
.then((userDoc) =>{
// if the document exists loop through the results
if (userDoc.exists) {
data = userDoc.data().saved_data; // an array store in firebase
data.forEach(ID => { // loop through array
firebase.firestore().collection("test_data").doc(ID).get()
.then((doc) => {
dataArray.push(doc.data().test_data);
console.log(dataArray) // the data shows
})
console.log(dataArray) // the data does not show
})
}
})
}
catch (error) {
}
}
Upvotes: 1
Views: 1019
Reputation: 1726
You're looping through asynchronous calls, so your final console.log will trigger before the data has been received. Your first console.log only triggers after the data has been received.
So the code is working, but the function (promise) will resolve (as undefined, or void) before all the data has been received from your firebase calls.
If you want to return the array to the caller, you could do something like this:
function getDataFromServer() {
// get the document using the user's uid
return firebase.firestore().collection('users').doc(uid).get().then(userDoc => {
// now we're returning this promise
const dataArray = []; // can move this to lower scope
// if the document exists loop through the results
if (userDoc.exists) {
const savedData = userDoc.data().saved_data; // an array store in firebase
return Promise.all(
// wait for all the data to come in using Promise.all and map
savedData.map(ID => {
// this will create an array
return firebase.firestore().collection('test_data').doc(ID).get().then(doc => {
// each index in the array is a promise
dataArray.push(doc.data().test_data);
console.log(dataArray); // the data shows
});
})
).then(() => {
console.log(dataArray);
return dataArray; // now data array gets returned to the caller
});
}
return dataArray; // will always be the original empty array
});
}
Now the function returns the promise of an array, so you could do...
const dataArray = await getDataFromServer()
or
getDataArrayFromServer().then(dataArray => {...})
Upvotes: 7