Firebase returns false value when there is a value present in the collection using node.js

左心房为你撑大大i 提交于 2021-01-29 10:30:39

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!