如何使用firestore和express.js创建onSnapshot侦听器

时间:2019-11-18 00:16:27

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

我试图通过向文档添加onSnapshot侦听器来设置实时功能。当我调用api时,它可以正常工作,但是每当我修改数据时,我都会被

击中
  

错误[ERR_HTTP_HEADERS_SENT]:将标头发送到客户端后无法设置

function routes() {
  const router = express.Router();

  router.route("/jobs/:company").get(async (req, res) => {
      const company = req.params.company;

      const snapshot = db
        .collection("companies")
        .doc(company)
        .collection("operations")
        .doc("jobs")

        snapshot.onSnapshot(docSnapshot=> {
          res.status(200).send(docSnapshot.data());
        }, err => {
          res.status(500).send(err)
        });

  });
}

我知道当您多次调用res.send(something)时会发生这种错误,但实际情况并非如此。同时,我检查了我的firebase节点模块,发现reference.js文件调用了一个onNext函数,该函数可能会触发错误。我不太确定这里发生了什么,但我会非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

onSnapshot()附加了一个持久的侦听器,该侦听器将针对文档的每次更改不断被调用。这就是send()被多次调用的原因。 Express不允许这样做,因为它必须通过HTTP连接一次发送整个响应。

相反,您应该使用get()一次提取数据,如documentation所示。这里不需要持久的侦听器。

      const ref = db
        .collection("companies")
        .doc(company)
        .collection("operations")
        .doc("jobs")

      ref.get()
      .then(docSnapshot=> {
        res.status(200).send(docSnapshot.data());
      })
      .catch(err => {
        res.status(500).send(err)
      });

如果您实际上尝试通过HTTP连接向客户端发送多个文档更新,则必须考虑发送chunked HTTP encoded响应,并确保服务器和客户端框架都可以实际使用该HTTP协议详细信息。这可能比它值得的麻烦更多(在这种情况下,您应该让客户端直接使用Firestore SDK)。