【问题标题】:Firebase - Node.js - Express - Error [ERR_HTTP_HEADERS_SENT]Firebase - Node.js - Express - 错误 [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: E​​rror [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?

【问题讨论】:

    标签: node.js firebase express google-cloud-functions


    【解决方案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(); 之前,它会起作用。如果我之后推它,则不会返回任何内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 2020-07-02
    • 2021-09-02
    • 2013-03-20
    相关资源
    最近更新 更多