Google Cloud function and reading data from database

332 Views Asked by At

I am trying to set up (Facebook) Webhook. My databse structure is like this:

{ "users": [
       "1" : {"FacebookID" : "1234567"},
       "2" : {"FacebookID" : "9876554"}
]}

I reduced the code for the webhook to the minimum to show where I have my problems. I go through all entries from the request and check what uid has the change. Before I want to change my data, I would like to see if the user with the id is available in my database. Facebook sends me the FacebookID of course, therefore I need to check, if there is an user account with that specific facebook id.

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

exports.webhooks = functions.https.onRequest((req, res) => {

    var i = 0;
    for (i = 0; i < req.body.entry.length; i++)
    {
        //strCurrentUser = req.body.entry[i].uid;
        strCurrentUser = "2357295025722342"; //For debug

        if (checkIfUserAvailable(strCurrentUser))
        {
            console.log("User is available " + strCurrentUser);
        }
        else 
        {
            console.log("User is not available " + strCurrentUser);
        }
    }

    return res.send(200);
});

function checkIfUserAvailable(userFacebookID)
{
    const rootRef = admin.database().ref();

    return rootRef.child('users').orderByChild('FacebookID').equalTo(userFacebookID).once('value').then( snap =>
    { 
        console.log("snap is : " + (snap.val() !== null));
        return (snap.val() !== null);
    });
}

Now the problem is, that the checkIfUserAvailable always returns true and does not wait till the read is done to return the correct boolean. How can I make sure, that it waits with the return until the read has been finished to get the entire code working?

What I get as result ist:

11:34:58.057 PM / webhooks / snap is : false
11:34:31.665 PM / webhooks / Function execution took 1880 ms, finished with status code: 200
11:34:31.569 PM / webhooks / User is available 2357295025722342
11:34:29.786 PM / webhooks / Function execution started

As you can see the res.send(200) is fired earlier and the snap is: false will be logged later. (I am also not sure why it takes 20 seconds to read data from a almost empty database)

Thanks for the help!

1

There are 1 best solutions below

2
On

You're not using promises correctly. The call to once() is asynchronous and returns immediately before the query is finished. This means the response is sent before the query is done, and Cloud Functions shuts down that async work. Instead, you should be sending that response only after the query is complete.

You might want to watch my videos on using promises in Cloud Functions in order to learn how best to deal with situations like this. Also be sure you understand the documentation.