Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase .then with .on('value')

I'm trying to get .then() to work with .on() but it only works with .once().

I get playersRef.on(...).then is not a function, when trying it with on()

So what I have now is this:

   let nodesRef = Firebase.database().ref('players')
   let answers = {}
   playersRef.on('value', (playersSnapshot) => {
      playersRef.once('value').then((playersSnapshot) => {
        playersSnapshot.forEach((playerSnapshot) => {
          let playerKey = playerSnapshot.key
          let answersRef = playerSnapshot.child('answers')
          if (answersRef .exists()){
            answers[playerKey ] = answersRef .val()
          }
        })
      }).then(() => {
        console.info(answers);
        dispatch(setPlayerAnswers(answers))
      })
    })

But I don't like the fact that it is querying the ref twice.

How would I go about getting each player's answer in this example? What would be a more correct way? Because I don't think this is the way the Firebase devs intended this.

And what is the reasoning that it is not implemented for .on()? Because playersSnapshot.forEach(...).then is also not a function... How do I execute something only once whenever the .on('value') triggers?

like image 996
BlockChange Avatar asked Nov 03 '16 12:11

BlockChange


1 Answers

firebaser here

I'm not entire certain of parts of your question, so will only answer the parts that I can.

what is the reasoning that [then()] is not implemented for .on()?

We implemented support for Promises in the Firebase JavaScript clients. The definition of a promise is that it resolves (or fails) only once. Since the Firebase on() methods can receive updated data multiple times, it does not fit in the definition of a promise.

How do I execute something only once whenever the .on('value') triggers?

When you want to respond only once to an event, you should use the once() method.

I'm not sure why you're having problems with forEach(). The following should work:

playersRef.on('value', (playersSnapshot) => {
   playersSnapshot.forEach((playerSnapshot) => {
      let playerKey = playerSnapshot.key
      let answersRef = playerSnapshot.child('answers')
      if (answersRef .exists()){
        answers[playerKey ] = answersRef .val()
      }
   })
})

If you're having trouble making this work, can you reproduce that problem in a jsbin?

like image 152
Frank van Puffelen Avatar answered Nov 09 '22 00:11

Frank van Puffelen