【问题标题】:QuerySnapshot.empty causes a promise rejection errorQuerySnapshot.empty 导致承诺拒绝错误
【发布时间】:2021-02-19 00:37:33
【问题描述】:

我有一个使用 firebase-admin 和 express 的后端,以允许从客户端到服务器的发布请求以更改我拥有的包含用户数据等内容的 firestore(这是一个测试,而不是真正的产品) .我想检查一个文档是否已经存在,因此用户无法再次使用该用户名注册。我第一次看到 doc.exists 的实例,但它为我返回 undefined ,我查看了文档并找到了 doc.empty ,据说它可以检查文档是否为空。我试过了,但它返回了一个承诺拒绝错误。如果我将该行更改为 .exists 或其他内容,则会消失,因此我已将问题缩小到该行。

index.js(后端)

app.post("/registeruser", function (req, res) {
    res.setHeader("Content-Type", "application/json");

    try {
        const username = req.body.username;
        const password = req.body.password;
        const passwordEncrypted = HmacSHA1(password, JSON.parse(fs.readFileSync("./keys.json"))["passwordEncryptKey"]).toString();

        // console.log(username, password, passwordEncrypted);

        try {
            firestore.collection("users").get(username).then(function (data) {
                if (data.empty == false) {
                    throw [true, "Already registered user!"];
                }
            }).catch(function (error) {
                throw [true, error];
            });

            if (username == "") {
                firestore.collection("users").add({
                    username: v4(),
                    passwordhash: passwordEncrypted,
                    email: "example@gmail.com",
                }).then(function () {
                    return res.status(200).send(JSON.stringify({
                        error: false,
                        message: "Successfully registered user!",
                    }))
                }).catch(function (error) {
                    throw [true, error];
                });
            }
            else {
                firestore.collection("users").doc(username).set({
                    username: username,
                    passwordhash: passwordEncrypted,
                    email: "example@gmail.com",
                }).then(function () {
                    return res.status(200).send(JSON.stringify({
                        error: false,
                        message: "Successfully registered user!",
                    }));
                }).catch(function (error) {
                    throw [true, error];
                });
            }
        }
        catch (error) {
            throw [true, error];
        }
    }
    catch (error) {
        console.log(error);
        const [isError, errorMessage] = error;

        return res.status(404).send(JSON.stringify({
            error: isError,
            message: errorMessage,
        }));
    }
});

终端输出

(node:29448) UnhandledPromiseRejectionWarning: [对象数组] (节点:29448)UnhandledPromiseRejectionWarning:未处理的承诺拒绝。此错误源于在没有 catch 块的情况下抛出异步函数内部,或拒绝未使用 .catch() 处理的承诺。要在未处理的 Promise 拒绝时终止节点进程,请使用 CLI 标志 --unhandled-rejections=strict(请参阅 https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode)。 (拒绝编号:1) (节点:29448)[DEP0018] DeprecationWarning:不推荐使用未处理的承诺拒绝。将来,未处理的 Promise 拒绝将使用非零退出代码终止 Node.js 进程。

【问题讨论】:

    标签: javascript node.js promise ecmascript-5 firebase-admin


    【解决方案1】:

    您有多个并发的 Promise 链,其中一些可能会独立失败。您需要将所有逻辑整合到一个 Promise 链中。

    return firestore.collection("users").get(username)
      .then((data) => {
        if (data.empty == false) {
          throw [true, "Already registered user!"];
        }
      })
      .then(() => {
        if (username == '') {
          return firestore.collection("users").add({/* Your data */});
        }
    
        return firestore.collection("users").doc(username).set({/* Your data */});
      })
      .then(() => {
        return res.status(200);
      })
      .catch((err) => {
        return res.status(500);
      });
    

    您也可以尝试使用 async/await,这将大大简化这样的逻辑。

    【讨论】:

      猜你喜欢
      • 2020-06-06
      • 2022-12-04
      • 1970-01-01
      • 1970-01-01
      • 2019-10-27
      • 1970-01-01
      • 2019-11-25
      • 1970-01-01
      • 2019-04-09
      相关资源
      最近更新 更多