Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
135
rated 0 times [  138] [ 3]  / answers: 1 / hits: 34207  / 8 Years ago, fri, august 26, 2016, 12:00:00

My API /auth/login endpoint takes a req.body like this:



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


At the endpoint, I make a reference to my Firebase database (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.



I followed the promise structure outlined 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;
});
});


If no child is found at ref, the function does not proceed (see this answer). I don't even get an error thrown.



My goal is to run code when no user is found with a certain email (i.e. no child is found at ref that satisfies .equalTo(req.body.email)), but not run the code if a user is found. 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. 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?


More From » node.js

 Answers
76

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.



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:



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

[#60899] Wednesday, August 24, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
johnnaj

Total Points: 490
Total Questions: 109
Total Answers: 104

Location: Zambia
Member since Thu, Jun 25, 2020
4 Years ago
;