title: Refreshing a Firebase object manually in ReactJS
body: <p>I have a small app where a user can input a persons name and add them to a board and then users can up or down vote them (for fantasy football). Currently, the only thing that happens immediately without need for refreshing the page is when a player is added via the text input box. This does a little fade-in for the object and it comes right to the screen:  </p>
  
  <pre><code>addPlayer(player) {
  
  this.state.user ?
    this.database.push().set({ playerContent: player, votes: 0})
    :
    console.log("Not Logged In")
  }
  </code></pre>
  
  <p>Is this done in real time because it is a push? How could I have the board of players update after a user casts a vote? Right now, when say Jane Doe has two votes, and John Doe has 2 votes and you vote John Doe up to 3, he doesn't jump up ahead of Jane Doe until after you refresh the page. Is there a way to refresh each individual object as you cast a vote? Here's my voting code  </p>
  
  <pre><code>upvotePlayer(playerId) {
  if(this.state.user) {
    let ref = firebase.database().ref('/players/' + playerId + '/voters');
  
    ref.once('value', snap =&gt; {
      var value = snap.val()
      if (value !== null) {            
          ref.child(this.uid).once('value', snap =&gt; {
            if (snap.val() === 0 || snap.val() === -1 || snap.val() == null){
              ref.child(this.uid).set(1);
            } else if (snap.val() === 1) {
            ref.child(this.uid).set(0);
            }
            else {
              console.log("Error in upvoting. snap.val(): " + snap.val())
            }
  
          })
  
      } else {
          console.log("Doesn't exist")
          ref.child(this.uid).set(1);
      }
  });
  }
  else {
      console.log("Must be logged in to vote.")
  }
  }
  </code></pre>
  
  <p>If I'm missing relevant code please let me know and I'll supply it. I tried calling <code>componentDidMount</code> after the vote is cast and <code>this.forceUpdate()</code> (even if it is discouraged) just to see if it was a solution, which it didn't seem to be.</p>
  
  <p>Heres the player component which is rendered in App.js</p>
  
  <pre><code>{
    orderedPlayersUp.map((player) =&gt; {
      return (
        &lt;Player
          playerContent={player.playerContent}
          playerId={player.id}
          key={player.id}
          upvotePlayer={this.upvotePlayer}
          downvotePlayer={this.downvotePlayer}
          userLogIn={this.userLogIn}
          userLogOut={this.userLogOut}
          uid={this.uid}
        /&gt;
      )
    })
  }
  </code></pre>
  
  <hr>
  
  <h1>Edit</h1>
  
  <p>When I change the upvotePlayer function's database call to <code>.on</code> rather than <code>.once</code> and proceed to upvote a player, it spews out an infinite amount of my console.logs from this componentWillMount function:  </p>
  
  <p>App.js line 51 is the console.log below.</p>
  
  <pre><code>  this.database.on('child_changed', function (snapshot) {
      var name = snapshot.val();
      console.log("Player: " + name.playerContent + " has  " + name.votes + " votes.")
    })
  </code></pre>
  
  <p>After 20 seconds or so when it overloads itself, an error page comes up and says <code>RangeError: Maximum call stack size exceeded</code></p>
  
  <p>Changing the componentWillMount functions database call to <code>this.database.once</code> instead of <code>.on</code> cuts down on the infinite loop, but still throws <code>RangeError: Maximum call stack size exceeded</code></p>
  
  <p>The error:<br>
  <a href="https://i.stack.imgur.com/rAGKw.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/rAGKw.png" alt="enter image description here"></a><br>
  <a href="https://i.stack.imgur.com/Yyalw.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Yyalw.png" alt="enter image description here"></a></p>
  
  <p>A gist with the App.js (where the voting occurs (upvotePlayer)) and Player.jsx. <a href="https://gist.github.com/scottmiller2/c1e5beb878db553ede50b79ff5fa70cf" rel="nofollow noreferrer">Gist with App.js and Player.jsx</a></p>
  
  <hr>
  
  <h1>Edit2</h1>
  
  <p>Votes started registering immediately to the screen when I changed from <code>.once</code> to <code>.on</code> in the Player.jsx file in the comondentDidMount() as seen below. To clarify, this solves my issue of the voting icons not changing in real-time when I change from upvote to downvote. I have yet to test whether or not it registers one player overtaking another with more votes as I originally asked. Just wanted to clarify for anyone who may look through this code to help themselves.</p>
  
  <pre><code>componentDidMount() {
    let ref = firebase.database().ref('/players/' + this.playerId + '/voters');
  
    ref.on('value', snap =&gt; {
      var value = snap.val()
  
      if (value !== null &amp;&amp; this.props.uid !== null) {       
          ref.child(this.props.uid).on('value', snap =&gt; {
            if (snap.val() === 1){
              this.setState({ votedUp: true, votedDown: false })
              }
            else if (snap.val() === 0) {
              this.setState({ votedUp: false, votedDown: false })
            }
            else if (snap.val() === -1) {
              this.setState({ votedDown: true, votedUp: false })
            }
            else {
            console.log("Error calculating the vote.")
            }
          })
      } else {
        //Error
      }
  });
  
    }
  </code></pre>