问题
I'm trying to verify a record in Firebase before registering the user with post request using node.js
***** Node.js Code ****
function checkUserExist(email) {
var userExist = false;
userRef.orderByChild('email').equalTo(email).once('value').then(function (snapshot) {
if (snapshot.exists()) {
userExist = true;
console.log(userExist); // Here the value is returned true
}
});
return userExist;
}
app.post('/register', urlencodedParser, function (req, res) {
var testUser = checkUserExist(req.body.reg_email);
console.log('A: '+ testUser);
// Here the value is returned false instead of true
console.log(checkUserExist(req.body.reg_email), req.body.reg_email);
// Here the value is returned false instead of true
var newUserObj = {
first_name: req.body.reg_first_name,
last_name: req.body.reg_last_name,
email: req.body.reg_email
};
userRef.push(newUserObj);
res.render('pages/register', { reg_data: { post_data: req.body, is_success: created, is_user_exist: checkUserExist(req.body.reg_email) } });
//console.log(users);
});
回答1:
Data is loaded from Firebase asynchronously. By the time your return userExist
runs, the data hasn't loaded yet.
This is easiest to see with some logging statements:
console.log('Before starting query');
userRef.orderByChild('email').equalTo(email).once('value').then(function (snapshot) {
console.log('Got query results');
});
console.log('After starting query');
When you run this code, you get this output:
Before starting query
After starting query
Got query results
That is probably not the order you expected, but it explains precisely why your method returns the wrong value: the data hasn't been loaded yet by the time your function returns.
Any code that needs the data from the database, must either be inside the then()
callback, or be called from there.
The common way to deal with asynchronous APIs is to return a promise:
function checkUserExist(email) {
var userExist = false;
return userRef.orderByChild('email').equalTo(email).once('value').then(function (snapshot) {
return snapshot.exists();
});
}
Now you can call checkUserExist
like this:
checkUserExist(req.body.reg_email).then(function(userExists) {;
console.log(userExists);
})
Note that here too, the userExists
only has the correct value inside the then()
callback.
If you're on a modern JavaScript environment, you can use async
/await
for the function call:
let userExists = await checkUserExist(req.body.reg_email);
console.log(userExists);
Note that this is still doing the asynchronous call behind the scenes.
This is a very common problem for developers new to dealing with asynchronous APIs. I highly recommend you check out some of these previous answers:
- Reading nested data from Firebase returns something else than an array
- Best way to retrieve Firebase data and return it, or an alternative way
- Why Does Firebase Lose Reference outside the once() Function?
- Asynchronous access to an array in Firebase
来源:https://stackoverflow.com/questions/55792452/firebase-returns-false-value-when-there-is-a-value-present-in-the-collection-usi