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: 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?

【问题讨论】:

【参考方案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 功能项目

firebase 和 node.js 的问题

REST API - Android Studio、Node.js、Firebase

使用自己的服务器 node.js 托管 Firebase