web-dev-qa-db-ja.com

Firebase .orderByChild()。equalTo()。once()。then()子が存在しない場合の約束

私のAPI _/auth/login_エンドポイントは、次のような_req.body_を取ります。

_{
  "email": "[email protected]",
  "password": "supersecretpassword"
}
_

エンドポイントで、Firebaseデータベースへの参照を作成します(_https://jacob.firebaseio.com/users_)。データを検索し、_req.body.email_に一致する電子メールを持つユーザーを見つけたら、データベースに保存されているパスワードとパスワードを比較します。

私は この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;
    });
});
_

refに子が見つからない場合、関数は続行しません( この回答 を参照)。エラーがスローされることもありません。

私の目標は、特定の電子メールでユーザーが見つからないときにコードを実行することです(つまり、ref.equalTo(req.body.email)を満たす子が見つかりません)。ただし、ユーザーが見つかった場合はコードを実行しません。何も見つからない場合、エラーはスローされません。

コードの実行後にエンドポイントから完全に抜け出すために、データベースへの呼び出しの戦略ポイント(.then() promiseの最後)に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 promiseを使用している場合、どのように対応しますか?

13
Jacob

child_addedイベントは、クエリがusersの下のキーの少なくとも1つに一致する場合にのみ発生し、複数の一致がある場合に複数回発生します。

代わりにvalueイベントを使用できます。1回だけ起動し、スナップショットにはusersに一致するか、value of 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);
});
25
cartant