【问题标题】:Firebase/Telegram Post requestFirebase/Telegram 发布请求
【发布时间】:2020-05-30 22:37:08
【问题描述】:

我目前正在尝试构建一个 firebase 云功能(使用 express),其中: - 我检查数据库中是否存在使用 - 根据是否存在向电报 API 发送消息

问题是,当我尝试运行该功能时,Firebase 日志能够让 console.log 告诉我用户是否存在,但不会发送到电报。错误日志说:

[2020-02-15T10:41:34.568Z] @firebase/数据库:FIREBASE 警告: 用户回调引发了异常。错误:之后无法设置标题 他们被发送。 在 validateHeader (_http_outgoing.js:491:11) 在 ServerResponse.setHeader (_http_outgoing.js:498:3) 在 ServerResponse.header (/srv/node_modules/express/lib/response.js:771:10) 在 ServerResponse.send (/srv/node_modules/express/lib/response.js:170:12) 在 ServerResponse.json (/srv/node_modules/express/lib/response.js:267:15) 在 ServerResponse.send (/srv/node_modules/express/lib/response.js:158:21) 在 firebase.database.ref.child.once.snapshot (/srv/index.js:59:40) 一次回调(/srv/node_modules/@firebase/database/dist/index.node.cjs.js:4933:51) 在 /srv/node_modules/@firebase/database/dist/index.node.cjs.js:4549:22 在 exceptionGuard (/srv/node_modules/@firebase/database/dist/index.node.cjs.js:698:9)

有人可以帮忙吗?谢谢!

 app.post("/", async (req, res) => {

    const isTelegramMessage =
        req.body &&
        req.body.message &&
        req.body.message.chat &&
        req.body.message.chat.id &&
        req.body.message.from &&
        req.body.message.from.first_name &&
        req.body.update_id;
    const user_id = req.body.message.from.id
 firebase.initializeApp(firebaseConfig);
    let myUser;
    const chat_id = req.body.message.chat.id;
    const {
        first_name
    } = req.body.message.from;
    // Check User Exists
    firebase
        .database()
        .ref("/telegramUsers")
        .child(req.body.message.from.id)
        .once("value", snapshot => {
            if (snapshot.exists()) {
                myUser = true;
                console.log("exists!", myUser);
                return res.status(200).send({
                    method: "sendMessage",
                    chat_id,
                    text: `Welcome Back ${first_name}`
                });
            } else {
                myUser = false;
                console.log("does not exist!");
                return res.status(200).send({
                    method: "sendMessage",
                    chat_id,
                    text: `Hello ${first_name}`
                });
            }
        });

    return res.status(200).send({
        status: "not a telegram message"
    });
});

【问题讨论】:

  • 您在消息发送之前返回,然后再次返回
  • 在最后一个return 之前写console.log() 你就会明白这个问题。你会得到两个日志——一个“存在”,另一个你会写

标签: javascript firebase express firebase-realtime-database telegram


【解决方案1】:

正如其他人所评论的那样,您将返回并写两次回复给调用者。由于 send 开始编写 HTTP 响应的正文,因此在您之前已在 res 上调用过 status(甚至是 send)之后,您将无法再调用它。

在看起来像这样的代码中:

 app.post("/", async (req, res) => {

    const isTelegramMessage =
        req.body &&
        req.body.message &&
        req.body.message.chat &&
        req.body.message.chat.id &&
        req.body.message.from &&
        req.body.message.from.first_name &&
        req.body.update_id;
    const user_id = req.body.message.from.id
    firebase.initializeApp(firebaseConfig);
    let myUser;
    const chat_id = req.body.message.chat.id;
    const {
        first_name
    } = req.body.message.from;
    // Check User Exists
    if (isTelegramMessage) {
      return firebase
        .database()
        .ref("/telegramUsers")
        .child(req.body.message.from.id)
        .once("value")
        .then(snapshot => {
            if (snapshot.exists()) {
                myUser = true;
                console.log("exists!", myUser);
                return res.status(200).send({
                    method: "sendMessage",
                    chat_id,
                    text: `Welcome Back ${first_name}`
                });
            } else {
                myUser = false;
                console.log("does not exist!");
                return res.status(200).send({
                    method: "sendMessage",
                    chat_id,
                    text: `Hello ${first_name}`
                });
            }
          });
    } else {
      return res.status(200).send({
        status: "not a telegram message"
      });
   }
});

变化:

  • 现在仅在isTelegramMessage 为真时检查用户是否存在。
  • 现在返回数据库读取操作的结果。
  • 使用once().then(),使return res.status().send()... 冒泡。这可确保 Cloud Functions 在数据库加载和响应发送完成之前不会终止函数。

虽然 HTTPS 触发的云函数(因为它们在您发送响应时终止)并不严格需要第二个和第三个项目符号,但我仍然建议使用它们,以便更轻松地将代码移植/复制粘贴到云由其他事件触发的函数类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    • 2019-05-17
    • 2015-09-20
    • 1970-01-01
    • 2019-06-08
    • 1970-01-01
    相关资源
    最近更新 更多