I am trying to get data from Firestore using multiple queries, but the returned data is always undefined, even though console.log(data) in .then() block shows the data exist.
const getPeers = async () => { let query = firestore.collection("users"); if (country !== "") query = query.where("country", "==", country); if (gender !== "") query = query.where("gender", "==", gender); if (age !== "") query = query.where("age", "==", age); if (religion !== "") query = query.where("religion", "==", religion); if (budget_low !== "") query = query.where("budget_low", ">=", Number(budget_low)); if (budget_high !== "") query = query.where("budget_high", "<=", Number(budget_high)); query .get() .then((querySnapshot) => { var data = []; querySnapshot.forEach((doc) => { data.push(doc.data()); }); console.log(data) // data exist here after console log. return data; }) .catch((error) => { console.log("Error getting documents: ", error); }); }; let d = await getPeers(); console.log(d); // gets undefined
Advertisement
Answer
You have to return the promise in your function getPeers()
:
const getPeers = async () => { let query = firestore.collection("users"); if (country !== "") query = query.where("country", "==", country); if (gender !== "") query = query.where("gender", "==", gender); if (age !== "") query = query.where("age", "==", age); if (religion !== "") query = query.where("religion", "==", religion); if (budget_low !== "") query = query.where("budget_low", ">=", Number(budget_low)); if (budget_high !== "") query = query.where("budget_high", "<=", Number(budget_high)); return query // here return the promise .get() .then((querySnapshot) => { var data = []; querySnapshot.forEach((doc) => { data.push(doc.data()); }); console.log(data) // data exist here after console log. return data; }) .catch((error) => { console.log("Error getting documents: ", error); }); };
EDIT:
A little advice when handling errors in async functions, in your code you have the catch()
handler with a console.log
:
return query.get() // here return the promise .then((querySnapshot) => { ... }) .catch((error) => { console.log("Error getting documents: ", error); // If query.get() fails, then 'await getPeers();' // will return 'undefined'. }); }; let d = await getPeers(); console.log(d); // will be undefined if query.get() returns an error.
To avoid this you could throw an error in catch()
like this:
.catch((error) => { throw "An error occurred"; });
So then you can check if an error ocurred like this:
let d = await getPeers().catch(error => { // here you can throw the error or do something else like return null for example. console.error(error); return null; }); if (d){ // now you can validate that your data exists ... }
You can see more about async functions here.
Remember this:
Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise.