我的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承诺的任何内容,我如何对此数据库的调用作出反应?
答案 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 */
}