75

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.

Kato
  • 40,352
  • 6
  • 119
  • 149

6 Answers6

97

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.

Sam Storie
  • 4,444
  • 4
  • 48
  • 74
Michael Lehenbauer
  • 16,229
  • 1
  • 57
  • 59
  • 3
    Michael, many thanks. Your teams always seems to be a step ahead. – Kato Jul 05 '12 at 20:25
  • 1
    Another issue is when you actually want the connection to stay up, but your servers go down...and instead of trying to request a new connection, it just repeatedly tries to reconnect to the 'down' server. :( – Shawn Grigson Sep 11 '13 at 19:55
  • 4
    Hey @Shawn, this is unfortunately expected behavior for right now. For a given Firebase, the client must connect to a specific server. If the server goes down, we can move the Firebase to be owned by a different server, but it is a manual process so you will see a period of time where the client tries to connect to the down server. You can expect this sort of behavior (and uptime in general) to improve over the coming months. – Michael Lehenbauer Sep 25 '13 at 20:00
  • Fair enough. Thank you for the follow up. :) – Shawn Grigson Nov 01 '13 at 19:45
  • 3
    Hello, is this code still relevant? When I tested it with `setInterval` I was receiving "connected" and "not connected" answers one after another. I mean I was getting "not connected" first but after a second it was switching to "connected", why? – Telion Nov 28 '17 at 21:51
  • I found this sample from firebase product site, but when client discoonected, client try to call server again again again. never stop. could we change this behaviiour and how? – Nuri YILMAZ Sep 29 '18 at 11:25
  • This doesn't seem to be working in js. Although, I find it working in Unity. – sn.anurag Nov 12 '18 at 05:32
  • Does the firebase database always automatically attempt to reconnect after losing the connection for whatever reason? It seems for me in testing it on my device that is does, but I notice the vast majority of my users don't get connected in the first place. Is there some code that should be put in the 'connectedSnap.val() == false' for this. – Androidcoder Sep 18 '20 at 16:36
17

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");
  }
});
André Kuhlmann
  • 4,378
  • 3
  • 23
  • 42
Baris
  • 797
  • 2
  • 10
  • 15
8

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.

knod
  • 446
  • 5
  • 8
  • Firebase is a NoSQL JSON data store, so it has no schema. Thus, you can pick them out of thin air, set a value, and then they exist : ) – Kato Nov 16 '16 at 15:03
  • To be honest ... it took me quite some time to wrap my head around NoSQL after 8 years of SQL only... but it's awesome indeed. – Eduard Feb 25 '17 at 20:27
  • I am using same thing. But it won't work when user will lost his internet connection. – Nirmalsinh Rathod Jun 03 '19 at 12:43
  • @Nirmalsinh: This answer is over two years old. This might not be the way to do it anymore. If you've tried all the answers posted here and they didn't work you could post a new question with the details of your situation and explain none of these worked. – knod Jul 22 '19 at 16:11
3

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.

Kishan Solanki
  • 13,761
  • 4
  • 85
  • 82
  • if you adding this on chat app where chat app needs to show instant change and as you said firebase takes 2-10 minutnes to execute `onDIsconnect()` then how you managing user status. – androidXP Feb 19 '19 at 11:12
  • @androidXP That's probably an issue of Firebase, actually, it takes up to 10 minutes sometimes to update status. – Kishan Solanki Feb 19 '19 at 11:14
  • so is it good to depend on firebase for online offline status where we need to change instant ? – androidXP Feb 19 '19 at 11:17
  • I don't find any other better solution to update the status of online/offline when a user turns off wifi/mobile data. How we could update status when there is no internet connection!! – Kishan Solanki Feb 19 '19 at 11:23
  • what if user press back button or home button it should show offline to others user or away but if it takes 2-10 min as you said then it might create confusion among user. Thanks for your response – androidXP Feb 19 '19 at 11:29
  • @androidXP For the back button and other user interaction stuff, you need to update online/offline status by yourself. This question is asked only for "if a user lost a connection from firebase or goes offline". So for that, you can use my solution. Hope you understand. – Kishan Solanki Feb 20 '19 at 14:13
1

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

1

firebase for web

firebase.database().ref(".info/connected").on("value",(snap)=> {});
Nikaido
  • 4,443
  • 5
  • 30
  • 47