FIREBASE WARNING 发送标头后无法设置标头

Ham*_*dad 1 javascript node.js express firebase

当数据被推送到数据库时,我会使用数据流自动更新我的角度材料数据表

这是我的 router.js

router
  .route("/")
  .get(function (req, res, err) {

    // Get a database reference to our posts
    var db = admin.database();
    var ref = db.ref("/");

    // Attach an asynchronous callback to read the data at our posts reference
    ref.on("value", function (snapshot) {
      var list = [];
      snapshot.forEach(function (elem) {
        list.push(elem.val());
      })


      res.send(list);

    }, function (errorObject) {
      console.log("The read failed: " + errorObject.code);
    });
  });

router
  .route("/")
  .post(function (req, res, err) {
    console.log(req.body);
    // Get a database reference to our posts
    var db = admin.database();
    var ref = db.ref("/");

    // Attach an asynchronous callback to read the data at our posts reference
    ref.push(
      {
        "text": req.body.text
      }

    );

  });
Run Code Online (Sandbox Code Playgroud)

当我运行我的应用程序时,我获取了所有数据,然后当我尝试将数据发布到数据库时,出现此错误:

FIREBASE WARNING: Exception was thrown by user callback. Error: Can't set headers after they are sent.
Run Code Online (Sandbox Code Playgroud)

当我使用once而不是on我不会出错,但由于我需要在数据库的每次更新中获取新数据,我应该使用 on来获取数据流。

那么如何使用on而不出现此错误呢?

Fra*_*len 5

当您使用 附加侦听器时on("value"),它将继续侦听数据。这意味着如果数据稍后更改,它也会触发,此时您已经向客户端发送了响应并关闭了套接字。

为了防止这种情况,你应该听once("value")

router
  .route("/")
  .get(function (req, res, err) {

    // Get a database reference to our posts
    var db = admin.database();
    var ref = db.ref("/");

    // Attach an asynchronous callback to read the data at our posts reference
    ref.once("value", function (snapshot) {
      var list = [];
      snapshot.forEach(function (elem) {
        list.push(elem.val());
      })

      res.send(list);

    }, function (errorObject) {
      console.log("The read failed: " + errorObject.code);
      res.status(500).send(errorObject.code);
    });
  });
Run Code Online (Sandbox Code Playgroud)

我还添加了对错误处理程序的响应。

更新

如果您想继续向客户端发送更新,您需要保持连接打开。在这种情况下,您不应调用res.send()(关闭连接),而是调用(res.write()使连接保持打开状态)。参见node js 中 response.send 和 response.write 的区别

router
  .route("/")
  .get(function (req, res, err) {

    // Get a database reference to our posts
    var db = admin.database();
    var ref = db.ref("/");

    // Attach an asynchronous callback to read the data at our posts reference
    ref.on("value", function (snapshot) {
      var list = [];
      snapshot.forEach(function (elem) {
        list.push(elem.val());
      })


      res.write(list);

    }, function (errorObject) {
      console.log("The read failed: " + errorObject.code);
      res.status(500).send(errorObject.code);
    });
  });
Run Code Online (Sandbox Code Playgroud)