简体   繁体   English

Firebase .orderByChild()。equalTo()。once()。then()当子元素不存在时的Promise

[英]Firebase .orderByChild().equalTo().once().then() Promises when child doesn't exist

My API /auth/login endpoint takes a req.body like this: 我的API /auth/login端点需要这样的req.body

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

At the endpoint, I make a reference to my Firebase database ( https://jacob.firebaseio.com/users ). 在端点,我引用了我的Firebase数据库( https://jacob.firebaseio.com/users )。 I search through the data, and when I find one user with the email that matches req.body.email , I compare the password with the one stored in the database. 我搜索数据,当我发现一个用户的电子邮件与req.body.email匹配req.body.email ,我将密码与存储在数据库中的密码进行比较。

I followed the promise structure outlined in this Firebase blog post . 我遵循了此Firebase博客文章中概述的承诺结构。

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

If no child is found at ref , the function does not proceed (see this answer ). 如果在ref找不到子项,则该函数不会继续(请参阅此答案 )。 I don't even get an error thrown. 我甚至没有抛出错误。

My goal is to run code when no user is found with a certain email (ie no child is found at ref that satisfies .equalTo(req.body.email) ), but not run the code if a user is found. 我的目标是在没有找到某个电子邮件的用户时运行代码(即在ref中找不到满足.equalTo(req.body.email) ),但是如果找到用户则不运行代码。 No error is thrown when nothing is found. 找不到任何内容时不会抛出任何错误。

I tried adding return statements at strategic points in the call to the database (at the end of my .then() promises) with the intention of breaking out of the endpoint entirely after the code was run. 我尝试在数据库调用的战略要点(在我的.then() promises的末尾.then()添加return语句,目的是在代码运行后完全断开端点。 I then put code after the call to the database: 然后我在调用数据库之后输入代码:

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

but this code is run whether the call to the database succeeds or not, since the call is asynchronous. 但是,无论对数据库的调用是否成功,都会运行此代码,因为调用是异步的。

How do I react to this call to the database if it doesn't return anything and still use Firebase promises? 如果它没有返回任何内容并且仍然使用Firebase承诺,我如何对此数据库的调用作出反应?

The child_added event only fires if the query matches at least one of the keys under users and will fire multiple times if there are multiple matches. child_added事件仅在查询与users下的至少一个键匹配时触发,并且如果存在多个匹配则将多次触发。

You can use the value event instead - it will fire only once and its snapshot will contain all of the keys under users that matched or will have value of null if there are no matches: 您可以使用value事件 - 它只会触发一次,它的快照将包含匹配的users下的所有键,如果没有匹配则将具有null value

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

Regarding handling of errors, you can wire up the promise and express error handling like this: 关于错误的处理,您可以将承诺连接起来并表达错误处理,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM