Reputation: 19
I have a website that utilises google firebase - firestore database. I have certain functions that get data from firestore and displays the data on the website on page load.
all_data = [];
//Get all documents in collection
function getAllDocuments() {
console.log('getAllDocuments() executed');
db.collection("All data").get().then((querySnapshot) => {
console.log('Getting documents from firestore...');
querySnapshot.forEach((doc) => {
//Creating object
data_t = new dbData;
all_data.push(data_t);
});
});
console.log('All data:', all_data.length);
}
//Display documents
function displayDocuments(data) {
console.log('displayDocuments() executed');
//Other lines of code
}
//Functions to run on page load
function pageLoad() {
getAllDocuments();
displayDocuments(all_data);
}
window.onload = pageLoad;
However, the functions are executed before data is retrieved from firebase. So, my website loads as an empty page. I have to execute the displayDocuments() again to display the data on the screen.
I understand the problem behind this. The webpage is not getting my documents from firebase on page load. Even though pageLoad() executes getAllDocuments(), it skips the db.collection.get() initially. This method is executed only after window.onload is executed, that is, after all my pageLoad() are executed. My console output looks like
getAllDocuments() executed
All data: 0
displayDocuments() executed
Getting documents from firestore...
Does anyone know why db.collection.get() is not executed in the defined order? How db.collection().get() gets executed at the end without getAllDocuments() being called?
Upvotes: 0
Views: 41
Reputation: 2342
The reason why this is happening is because your getAllDocuments
function finishes its execution before the promise could resolve.
What you can do is make getAllDocuments
async and wait for promise to resolve using await, and call it from pageLoad()
function using await. i.e
all_data = [];
async function getAllDocuments() {
console.log('getAllDocuments() executed');
const querySnapshot = await db.collection("All data").get();
querySnapshot.forEach((doc) => {
//Creating object
data_t = new dbData;
all_data.push(data_t);
});
console.log('All data:', all_data.length);
}
async function pageLoad() {
await getAllDocuments();
// displayDocuments(all_data);
}
Upvotes: 1
Reputation: 914
You need to await the result of the first function since it performs an asynchronous action. You can do it by returning the promise directly. In this case, you don't need all_data global variable since you can return it from promise.
Something like that should work for you:
//Get all documents in collection
function getAllDocuments() {
console.log('getAllDocuments() executed');
return db.collection("All data").get().then((querySnapshot) => {
console.log('Getting documents from firestore...');
return querySnapshot.map((doc) => {
//Creating object using doc
// ....
return new dbData;
});
});
}
//Display documents
function displayDocuments(data) {
console.log('displayDocuments() executed');
//Other lines of code
}
//Functions to run on page load
function pageLoad() {
getAllDocuments().then(all_data => displayDocuments(all_data));
}
window.onload = pageLoad;
Upvotes: 1