70
votes

Is there a strategy that would work within the current Firebase offering to detect if the server connection is lost and/or regained?

I'm considering some offline contingencies for mobile devices and I would like a reliable means to determine when the Firebase data layer is available.

6

6 Answers

95
votes

This is a commonly requested feature, and we just released an API update to let you do this!

var firebaseRef = new Firebase('http://INSTANCE.firebaseio.com');
firebaseRef.child('.info/connected').on('value', function(connectedSnap) {
  if (connectedSnap.val() === true) {
    /* we're connected! */
  } else {
    /* we're disconnected! */
  }
});

Full docs are available at https://firebase.google.com/docs/database/web/offline-capabilities.

16
votes

Updated: For many presence-related features, it is useful for a client to know when it is online or offline. Firebase Realtime Database clients provide a special location at /.info/connected which is updated every time the client's connection state changes. Here is an example:

DatabaseReference connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected");
connectedRef.addValueEventListener(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    boolean connected = snapshot.getValue(Boolean.class);
    if (connected) {
      System.out.println("connected");
    } else {
      System.out.println("not connected");
    }
  }

  @Override
  public void onCancelled(DatabaseError error) {
    System.err.println("Listener was cancelled");
  }
});
7
votes

I guess this changed in the last couple of months. Currently the instructions are here: https://firebase.google.com/docs/database/web/offline-capabilities

In summation:

var presenceRef = firebase.database().ref("disconnectmessage");
// Write a string when this client loses connection
presenceRef.onDisconnect().set("I disconnected!");

and:

var connectedRef = firebase.database().ref(".info/connected");
connectedRef.on("value", function(snap) {
  if (snap.val() === true) {
    alert("connected");
  } else {
    alert("not connected");
  }
});

I'll admit I don't know a lot about how references are set, or what that means (are you making them out of thin air or do you have to have already created them beforehand?) or which one of those would trigger something on the server as opposed to something on the front end, but if the link is still current when you read this, a little more reading might help.

3
votes

For android you can make user offline by just a single function called onDisconnect()

I did this in one of my chat app where user needs to get offline automatically if network connection lost or user disconnected from Internet

DatabaseReference presenceRef = FirebaseDatabase.getInstance().getReference("USERS/24/online_status");

presenceRef.onDisconnect().setValue(0);

On disconnecting from network Here I am making online_status 0 of user whose Id is 24 in firebase.

getReference("USERS/24/online_status") is the path to the value you need to update on offline/online.

You can read about it in offline capabilities

Note that firebase takes time around 2-10 minutes to execute onDisconnect() function.

2
votes

firebase for web

firebase.database().ref(".info/connected").on("value",(snap)=> {});
1
votes

The suggested solution didn't work for me, so I decided to check the connection by writing and reading 'health/check' value. This is the code:

const config = {databaseURL: `https://${projectName.trim()}.firebaseio.com/`};
//if app was already initialised delete it
if (firebase.apps.length) {
    await firebase.app().delete();
}
// initialise app
let cloud = firebase.initializeApp(config).database();
// checking connection with the app/database
let connectionRef = cloud.ref('health');
connectionRef.set('check')
    .then(() => {
        return connectionRef.once("value");
    })
    .then(async (snap) => {
        if (snap.val() === 'check') {
            // clear the check input
            await connectionRef.remove();
            // do smth here becasue it works
    }
});

enter image description here