Firebase .orderByChild()。equalTo()。once()。then()当孩子不存在时承诺

时间:2016-08-26 23:48:14

标签: javascript node.js firebase promise firebase-realtime-database

我的API /auth/login端点采用req.body这样:

{
  "email": "jacob@gmail.com",
  "password": "supersecretpassword"
}

在端点,我引用了我的Firebase数据库(https://jacob.firebaseio.com/users)。我搜索数据,当我发现一个用户的电子邮件与req.body.email匹配时,我将密码与存储在数据库中的密码进行比较。

我遵循了in this Firebase blog post概述的承诺结构。

router.post('/login', function(req, res) {
  const ref = db.ref('/users');

  ref.orderByChild('email')
    .equalTo(req.body.email)
    .once('child_added')
    .then(function (snapshot) {
      return snapshot.val();
    })
    .then(function (usr) {

      // Do my thing, throw any errors that come up

    })
    .catch(function (err) {

      // Handle my errors with grace

      return;
    });
});

如果在ref找不到孩子,则该功能不会继续(请参阅this answer)。我甚至不会抛出错误。

我的目标是在没有找到某个电子邮件的用户时运行代码(即在ref找不到满足.equalTo(req.body.email)的孩子),但如果找不到用户则不运行代码。没有找到任何错误时不会抛出任何错误。

我尝试在数据库调用的战略要点(在我的return承诺的末尾)添加.then()语句,目的是在代码运行后完全中断端点。然后我在调用数据库之后输入代码:

    .then(function (usr) {

      // Do my thing, throw any errors that come up

    })
    .catch(function (err) {

      // Handle my errors with grace

      return;
    });

  res.status(401)
    .json({
      error: 'No user found',
    )};

  return;
});

但是,无论对数据库的调用是否成功,都会运行此代码,因为调用是异步的。

如果它没有返回并且仍然使用Firebase承诺的任何内容,我如何对此数据库的调用作出反应?

1 个答案:

答案 0 :(得分:22)

child_added事件仅在查询与users下的至少一个键匹配时触发,如果有多个匹配则会多次触发。

您可以使用value事件 - 它只会触发一次,其快照将包含users下匹配或value null router.post('/login', function(req, res) { const ref = db.ref('/users'); ref.orderByChild('email') .equalTo(req.body.email) .once('value') .then(function (snapshot) { var value = snapshot.val(); if (value) { // value is an object containing one or more of the users that matched your email query // choose a user and do something with it } else { res.status(401) .json({ error: 'No user found', )}; } }); }); 的所有键如果没有匹配项:

router.post('/login', function(req, res, next) {
  const ref = db.ref('/users');

  ref.orderByChild('email')
    .equalTo(req.body.email)
    .once('value')
    .then(function (snapshot) {
      ...
    })
    .catch(next);
});

关于错误的处理,您可以将承诺连接起来并表达错误处理,如下所示:

.c-services__item {
  perspective: 1000px;
  -webkit-perspective: 1000px;
  -moz-perspective: 1000px;
  -o-perspective: 1000px;
  -ms-perspective: 1000px;
  display: inline-block; /* Make div inline */
  vertical-align: middle; /* align vertically top|bottom|middle|baseline */
}