I'm having trouble with a Firebase cloud function where I'm trying to fetch data. This function:
exports.fetchProducts= (req, res) => {
db.collection("products")
.where("active", "==", true)
.get()
.then(function (querySnapshot) {
querySnapshot.forEach(async function (doc) {
let data = [];
// console.log(doc.id, " => ", doc.data());
const priceSnap = await doc.ref.collection("prices").get();
priceSnap.docs.forEach((snap) => {
data.push({ product: doc.data(), price: snap.data() });
// console.log(snap.id, " => ", snap.data());
});
return res.status(200).json(data);
});
})
.catch((err) => {
console.log(err);
res.status(500).json({ error: err.code });
});
};
Returns this error message: UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client].
The data is returned (only all of it if I refresh the page) but with the error message mentioned above. If I remove this part then it disappears.
priceSnap.docs.forEach((snap) => {
data.push({ product: doc.data(), price: snap.data() });
// console.log(snap.id, " => ", snap.data());
});
Update
This will get rid of the error message but no data is returned. Same thing if I chain the return res in another .then(). My theory is that the response gets returned before the data is fetched. Any ideas how to solve that?
exports.fetchProducts = (req, res) => {
let data = [];
db.collection("products")
.where("active", "==", true)
.get()
.then(function (querySnapshot) {
querySnapshot.forEach(async function (doc) {
// console.log(doc.id, " => ", doc.data());
const priceSnap = await doc.ref.collection("prices").get();
priceSnap.docs.forEach((snap) => {
data.push({ product: doc.data(), price: snap.data() });
// console.log(snap.id, " => ", snap.data());
});
});
return res.status(200).json(data);
})
.catch((err) => {
console.log(err);
res.status(500).json({ error: err.code });
});
};
##Solution## I did find a solution to the problem. You can find it in this thread: How to achieve async behavior with nested firebase's forEach?