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

Posted

技术标签:

【中文标题】Firebase .orderByChild().equalTo().once().then() 当孩子不存在时承诺【英文标题】:Firebase .orderByChild().equalTo().once().then() Promises when child doesn't exist 【发布时间】:2017-01-03 16:52:45 【问题描述】:

我的 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) 的孩子),但如果找到用户则不运行代码。没有找到任何东西时不会抛出错误。

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

    .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】:

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

您可以改用value 事件 - 它只会触发一次,并且其快照将包含users 下匹配的所有键,或者如果没有匹配项,则将具有valuenull 的所有键:

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',
          );
      
    );
);

关于错误的处理,你可以像这样连接 Promise 并表达错误处理:

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);
);

【讨论】:

以上是关于Firebase .orderByChild().equalTo().once().then() 当孩子不存在时承诺的主要内容,如果未能解决你的问题,请参考以下文章

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

firebase 和 Ionic 2 上的降序 orderByChild()

Flutter:Firebase 实时数据库 orderByChild 对查询结果没有影响

firebase 查询 orderByChild().equalTo() android kotlin 的问题

这个 orderByChild Firebase 实时代码有啥问题?

OrderByKey 工作正常,但 OrderByChild 在 firebase 实时数据库中给出了意想不到的结果