Firebase / Telegram Отправить запрос - PullRequest
0 голосов
/ 15 февраля 2020

В настоящее время я пытаюсь создать облачную функцию firebase (используя express), где: - я проверяю, существует ли использование в базе данных - отправляет сообщение в API телеграммы в зависимости от того, существует оно или нет

Проблема в том, что когда я пытаюсь запустить функцию, журналы Firebase могут получить console.log, сообщающий мне, существует ли пользователь, но не будет отправлять в telegram. В журнале ошибок говорится:

[2020-02-15T10: 41: 34.568Z] @ firebase / database: FIREBASE WARNING: Исключение было вызвано обратным вызовом пользователя. Ошибка: невозможно установить заголовки после их отправки. at 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) atlyCallback (/srv/node_modules/@firebase/database/dist/index.node.cjs.js:4933:51) в / srv / node_modules / @ firebase / database / dist / index .node. cjs. js: 4549: 22 на исключение Guard (/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"
    });
});

1 Ответ

0 голосов
/ 15 февраля 2020

Как прокомментировали другие, вы возвращаетесь и пишете ответ звонящему дважды. Поскольку send начинает писать тело HTTP-ответа, вы не можете вызвать status (или даже send) после того, как вы уже вызывали его на res раньше.

В коде, который будет выглядеть примерно так:

 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()... всплыло. Это гарантирует, что облачные функции не прекратят работу до того, как будут выполнены загрузка базы данных и отправка ответа.

Хотя второй и третий маркеры не являются строго необходимыми для запускаемых по HTTPS облачных функций (как они прекращаются при отправке ответа), я все же рекомендую использовать их, чтобы упростить перенос / копирование и вставку кода в типы облачных функций, которые запускаются другими событиями.

...