Firebase - Node.js - Express - 错误 [ERR_HTTP_HEADERS_SENT]
Posted
技术标签:
【中文标题】Firebase - Node.js - Express - 错误 [ERR_HTTP_HEADERS_SENT]【英文标题】:Firebase - Node.js - Express - Error [ERR_HTTP_HEADERS_SENT] 【发布时间】:2022-01-17 17:18:57 【问题描述】:我在尝试获取数据的 Firebase 云功能时遇到问题。这个函数:
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 );
);
;
返回此错误消息:UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client]。
返回数据(如果我刷新页面,仅返回所有数据)但带有上述错误消息。如果我删除这部分,它就会消失。
priceSnap.docs.forEach((snap) =>
data.push( product: doc.data(), price: snap.data() );
// console.log(snap.id, " => ", snap.data());
);
更新
这将消除错误消息,但不返回任何数据。如果我将返回 res 链接到另一个 .then() 中也是一样的。我的理论是在获取数据之前返回响应。任何想法如何解决这个问题?
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 );
);
;
##解决方案## 我确实找到了解决问题的方法。你可以在这个线程中找到它: How to achieve async behavior with nested firebase's forEach?
【问题讨论】:
【参考方案1】:在我格式化您的代码后,答案似乎很明显。您在循环中发送响应,因此发送多个响应导致UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client].
让return res.status(200).json(data);
退出循环。
【讨论】:
感谢您抽出宝贵时间回答。如果这就是你的意思(我之前也试过)。然后它会删除消息,但也会删除数据 ` .then(function (querySnapshot) let data = []; 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 ); )` 在循环外声明data
,以便您在使用res.status(200).json(data)
时可以访问它
感谢您的帮助。但如果我将它移到外面,则不会返回任何数据。似乎响应是在获取“价格”数据之前发送的。错误消息消失了,但数据也消失了。如果我只将产品集合中的 doc.data() 推送到数据数组。如果我将它推到这条线const priceSnap = await doc.ref.collection("prices").get();
之前,它会起作用。如果我之后推它,则不会返回任何内容。以上是关于Firebase - Node.js - Express - 错误 [ERR_HTTP_HEADERS_SENT]的主要内容,如果未能解决你的问题,请参考以下文章
使用 Node.js 将 json 文件写入 Firebase?
Firebase:如何调用 https.onCall 函数 node.js?
使用 node.js 和 react.js 客户端启动一个 firebase 功能项目