Ad

Firebase OnDisconnect Not Deleting User Name On Disconnection

Perhaps I am mis-using onDisonnect(), but I looked at the example code on the firebase.blog and am doing my best.

When a user submits a user name, I call the code below, which adds the username to a firebase db. Then on disconnection, I want the username to be deleted from the db. This would mean that the db would only show users that are connected to the app at that moment in time.

I am doing it this way so I can then call the data and then map through the array to display currently logged-in users.

I have made two attempts in deleting the name, which you can see in the code below under con.onDisconnect().remove();, neither of which work the way I need. That said, if I log in once again from the same computer, the first user name replaces the second user name!

Here is my code

setName = e => {
    e.preventDefault()

    let name = this.state.name;
    let connectedRef = firebase.database().ref('.info/connected');
    connectedRef.on('value', function (snap) {
      if (snap.val() === true) {
        // Connected
        let con = myConnectionsRef.push();
        myConnectionsRef.set({
          name
        })
        // On disconnect 
        con.onDisconnect().remove();

        myConnectionsRef.orderByChild('name').equalTo(name).once('child_added', function (snapshot) {
          snapshot.ref.remove();

        // var nameRef = firebase.database().ref('users/'+name);
        // nameRef.remove()
        })
      }
    });

Where am I going wrong? Is there a better way to use onDisconnect? From the example on the fb forum, it isn't clear where I would put that block of code, hence why I am attempting to do it this way.

Thanks.

Ad

Answer

If I understand correctly what is your goal, you don't need to do

myConnectionsRef.orderByChild('name').equalTo(name).once('child_added', function (snapshot) {
  snapshot.ref.remove();

// var nameRef = firebase.database().ref('users/'+name);
// nameRef.remove()
}) 

as the onDisconnect().remove() call will take care of that.

Also, as explained in the blog article you refer to (as well as shown in the doc):

The onDisconnect() call shall be before the call to set() itself. This is to avoid a race condition where you set the user's presence to true and the client disconnects before the onDisconnect() operation takes effect, leaving a ghost user.


So the following code should do the trick:

setName = e => {
    e.preventDefault()

    let name = this.state.name;

    const connectedRef = firebase.database().ref('.info/connected');

    const usersRef = firebase.database().ref('users');

    connectedRef.on('value', function (snap) {
      if (snap.val() === true) {
        // Connected
        const con = usersRef.child(name);  //Here we define a Reference

        // When I disconnect, remove the data at the Database location corresponding to the Reference defined above 
        con.onDisconnect().remove();

       // Add this name to the list of users
        con.set(true);   //Here we write data (true) to the Database location corresponding to the Reference defined above 
      }
    });

The users node will display the list of connected users by name, as follows:

- users
   - James: true
   - Renaud: true
Ad
source: stackoverflow.com
Ad