0

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);
});
DevsLounge
  • 53
  • 6

1 Answers1

0

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:

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807