user3892254
user3892254

Reputation: 139

Firebase Promises in array not resolving in time

I am trying to return 3 promises from my firebase DB and once all three promises have been fulfilled I basically want to render a new page or do whatever. So I do a Promise.All(...) but my lists are still empty afterwards.

My queries are correct because when I console.log() within each of those functions, I get the objects returned from my DB but my Promise.All isn't waiting for those promises to resolve and instead executes the code within the Promise.All which is returning empty lists.

app.get('...', function (req, res) {
  //Return first promise from DB save to zone_obj list
  var zone_key = req.params.id;
  var zone_obj = [];
  firebase.database().ref(...).once('value').then((snapme) => {
    zone_obj.push(snapme.val());
  });
  
  //Return second promise from DB save to members list
  var members = [];
  firebase.database().ref(...).on("value", function (snapshott) {
    snapshott.forEach((snapper) => {
      members.push(snapper.val());
    });
  });
  
  //Return third promise from DB save to experiences list
  var experiences = [];
  firebase.database().ref(...).on("value", function (snapshot) {
    snapshot.forEach((snap) => {
      firebase.database().ref(...).once("value").then((snapit) => {
        experiences.push(snapit);
      });
    });
   });
   
  //once all promises have resolved
  Promise.all([experiences,zone_obj,members]).then(values => {
    console.log(values[0]); //returns []
    console.log(values[1]); //returns []
    console.log(values[2]); //returns []
  });
});

Upvotes: 1

Views: 1822

Answers (1)

Ridham Tarpara
Ridham Tarpara

Reputation: 6160

This is not actually firebase's problem. Firebase method .on("value") is actually a listener that will be bound to firebase to get real-time updates and that is not actually a promise and your callback function will be called every time when data on that node is changed. so if you want to save or get data only once use firebase.database().ref(...).set() and firebase.database().ref(...).once() method respectively.

According to firebase docs

On method

on(eventType, callback, cancelCallbackOrContext, context) returns function()

once method

once(eventType, successCallback, failureCallbackOrContext, context) returns firebase.Promise containing any type

So change your code to following

app.get('...', function (req, res) {
    var promises = []

    //Return first promise from DB save to zone_obj list
    promises.push(firebase.database().ref(...).once('value'));

    //Return second promise from DB save to members list
    promises.push(firebase.database().ref(...).once('value'));

    //Return third promise from DB save to experiences list
    promises.push(firebase.database().ref(...).once('value'));

    //once all promises have resolved
    Promise.all(promises).then(values => {
        console.log(values[0]); // zone_obj 
        console.log(values[1]); // members 
        console.log(values[2]); // experiences 
    });
});

Upvotes: 2

Related Questions