Arik5
Arik5

Reputation: 37

How to wait for a Firebase retrieve value and only then exit the function

I have a Firebase query.

Because Firebase works asynchronously, the function continue to run without waiting for the Firebase retrieve value.

Is there a way to wait for the result from the Firebase query and only then to make the return from the function?

function CheckBuyingCondition(prefix) {

    var Res = "";

    var Current_Price_Open_ref = firebase.database().ref("dailyT/Current_Price_Open/" + nextDayTrading).orderByChild("Prefix").equalTo(prefix)
    Current_Price_Open_ref.once("value").then(function(snapshot) {
        if(snapshot.exists()) {
            snapshot.forEach(function(childSnapshot) {
                var val = childSnapshot.val();
                res = "" + val.Current_Price_Open;
            });
        }
        else {
            res = "NA";
        }
    });

    return res; // (Here I got res = "" instead of the correct value from Firebase query
}

Upvotes: 1

Views: 8588

Answers (3)

Jaye Renzo Montejo
Jaye Renzo Montejo

Reputation: 1862

Use async/await:

async function checkBuyingCondition(prefix) {
  var res = '';

  var currentPriceOpenRef = firebase.database()
    .ref(`dailyT/currentPriceOpen/${nextDayTrading}`)
    .orderByChild('prefix')
    .equalTo(prefix);

  var snapshot = await currentPriceOpenRef.once('value');

  if(snapshot.exists()) {
    snapshot.forEach(function(childSnapshot) {
      var val = childSnapshot.val();
      res = `${val.currentPriceOpen}`;
    });
  } else {
    res = 'NA';
  }

  return res;
}

Take note that this does not make your function synchronous at all, thus the async keyword at the beginning of your function declaration; it just makes your function look like one.

On the third line inside the function you'll notice the await keyword. This waits for your promise to resolve then returns the result which in your case, is the snapshot from Firebase. You can only use await inside async functions.

More reading: JavaScript Async/Await

Upvotes: 4

zb22
zb22

Reputation: 3231

Try this:

function CheckBuyingCondition(prefix) {

    var Res = "";

    var Current_Price_Open_ref = firebase.database().ref("dailyT/Current_Price_Open/" + nextDayTrading).orderByChild("Prefix").equalTo(prefix)
        return Current_Price_Open_ref.once("value").then(function(snapshot) {
            if(snapshot.exists()) {
                snapshot.forEach(function(childSnapshot) {
                var val = childSnapshot.val();

                res = "" + val.Current_Price_Open;
            });
            return res;
        }
        else {
            res = "NA";
        }
    });
}

Firebase queries are promises, so you because you can return the result from the promise and get it with another promise.

Upvotes: 0

Doug Stevenson
Doug Stevenson

Reputation: 317828

You're proposing making the Firebase SDK asynchronous call into an synchronous call. This is not a good idea, and to be honest, not even possible in JavaScript. If you need to make a helper function that deals with Firebase APIs, that function should instead accept a callback function to be invoked when the work completes, or return a promise so that the caller of the function can decide what to do next.

Read here to learn more about why Firebase APIs are asynchronous.

Upvotes: 0

Related Questions