私の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を使用している場合、どのように対応しますか?
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);
});