QuerySnapshot.empty 导致承诺拒绝错误

QuerySnapshot.empty causes a promise rejection error

我有一个使用 firebase-admin 和 express 的后端,允许 post 从客户端到服务器的请求来更改我拥有的包含用户数据等内容的 firestore(这是一个测试而不是真正的产品)。我想检查文档是否已经存在,以便用户无法再次使用该用户名注册。我第一次看到 doc.exists 的实例,但 returns 对我来说是未定义的,我查看了文档并发现 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: [object Array] (node:29448) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1) (node:29448) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

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

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 这将大大简化这样的逻辑。