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

我的API /auth/login端点需要像这样的req.body

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

在端点上,我参考了我的Firebase数据库( https://jacob.firebaseio.com/users )。 我search数据,当我find一个与req.body.email相匹配的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找不到孩子,则该function不会继续(请参阅此答案 )。 我甚至没有得到一个错误。

我的目标是在没有find用户的情况下运行代码(即没有find满足.equalTo(req.body.email) ref .equalTo(req.body.email) ),但是如果find用户,则不运行代码。 没有发现任何错误。

我试图在调用数据库的关键点添加return语句(在我的.then() promise的末尾),意图在代码运行之后完全脱离端点。 然后我把代码放到数据库的调用之后:

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

但是由于调用是asynchronous的,因此无论对数据库的调用是否成功,都会运行此代码。

如果对数据库的调用没有任何回应, 并且仍然使用Firebase承诺,我该如何应对这种调用?

child_added事件仅在查询与users下的至less一个密钥匹配时触发,并且如果有多个匹配,则将多次触发。

您可以改为使用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', )}; } }); }); 

关于处理错误,你可以连接承诺,并表示error handling,如下所示:

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