Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase: Query.on failed: Was called with 1 argument. Expects at least 2

The error is in the title.

The app I´m building is based on React and Firebase. I am trying to use promises. Here is my code:

gamesRef.on('value').then(function(snapshot){
      // find all empty games
      var gamesToRemove = [];
      snapshot.forEach(game => {

        if(game.val().player1 == ""
          && game.val().player2 == ""
          && game.val().player3 == ""
          && game.val().player4 == ""){
            gamesToRemove.push(game.key());
        }
      });
      return gamesToRemove;
    }).then(function(gamesToRemove){
      // remove all empty games
      for(var index in gamesToRemove){
        gamesRef.child(gamesToRemove[index]).remove();
      }
    }, function(error){
      console.log(error);
    });

I found this question on SO that addressed the same issue. The solution was that the Firebase version needs to be at least 2.4 to use promises. I used an older version, but after upgrading to 2.4.2, i still get the same error. What should I do?

Edit: Code after fix. Get error "gamesRef.on(...).then is not a function".

gamesRef.on('value', function(snapshot){
      // find all empty games
      var gamesToRemove = [];
      snapshot.forEach(game => {

        if(game.val().player1 == ""
          && game.val().player2 == ""
          && game.val().player3 == ""
          && game.val().player4 == ""){
            gamesToRemove.push(game.key());
            console.log("denna borde raderas: " + game.key());
        }
      });
      return gamesToRemove;

    }).then(function(gamesToRemove){
      // remove all empty games
      for(var index in gamesToRemove){
        gamesRef.child(gamesToRemove[index]).remove();
      }
    });
like image 305
hellogoodnight Avatar asked May 10 '16 09:05

hellogoodnight


2 Answers

You have wrong mindset about on+then,

on takes 2 arguments: the name for event, and callback, callback is just plain function which takes event as argument:

 gamesRef.on('value', function(snapshot){
  // find all empty games
  var gamesToRemove = [];
  snapshot.forEach(game => {

    if(game.val().player1 == ""
      && game.val().player2 == ""
      && game.val().player3 == ""
      && game.val().player4 == ""){
        gamesToRemove.push(game.key());
    }
  });
  return gamesToRemove;
})

and then, you can use your then :D

like image 172
Daniel Mizerski Avatar answered Nov 20 '22 15:11

Daniel Mizerski


While many function in the Firebase JavaScript client return a promise, on() is not one of them.

The reason for this is that on() will typically deliver a value multiple times, while the contract of a promise is that then() will resolve at most once.

If you only care about getting the value of the data once, you can use once() and a promise:

gamesRef.once('value').then(function(snapshot){
  // find all empty games
  var gamesToRemove = [];
  snapshot.forEach(game => {

    if(game.val().player1 == ""
      && game.val().player2 == ""
      && game.val().player3 == ""
      && game.val().player4 == ""){
        gamesToRemove.push(game.key());
    }
  });
  return gamesToRemove;
}).then(function(gamesToRemove){
  // remove all empty games
  for(var index in gamesToRemove){
    gamesRef.child(gamesToRemove[index]).remove();
  }
}.catch(function(error){
  console.log(error);
});
like image 24
Frank van Puffelen Avatar answered Nov 20 '22 15:11

Frank van Puffelen