Firebase realtime database .info/connected False when it should be True

给你一囗甜甜゛ 提交于 2020-07-09 08:33:45

问题


I have an Android service that calls this at onCreate:

FirebaseDatabase database = FirebaseDatabase.getInstance();
database.getReference(".info/connected").addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
        Log.d(TAG, "connected: " + snapshot.getValue(Boolean.class));
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
        Log.w(TAG, "Failed to read value.", error.toException());
        }
});

I've noticed that when I do some amount of toggling wifi and cellular data, I eventually see a "connected: false" message and no "connected: true" message. Along with the Firebase realtime database, I'm also running Firestore in the service, and Firestore is properly connecting at this point.

I then trigger the Android service to run this code:

FirebaseDatabase.getInstance().getReference("random/data").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
           // This method is called once with the initial value and again
           // whenever data at this location is updated.
           boolean connected = snapshot.getValue(Boolean.class);
           Log.d(TAG, "random data: " + connected);
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
           // Failed to read value
           Log.w(TAG, "cancelled system/online.", error.toException());
        }
});

And now, I get a successful read and "connected: true" is printed.

What's happening? Why do I need to read from firebase for .info/connected to trigger?


回答1:


Why do I need to read from firebase for .info/connected to trigger?

The answer stays in the offical documentation:

Firebase Realtime Database provides a special location at /.info/connected which is updated every time the Firebase Realtime Database client's connection state changes.

/.info/connected is a boolean value which is not synchronized between realtime database clients because the value is dependent on the state of the client. In other words, if one client reads /.info/connected as false, this is no guarantee that a separate client will also read false.

On Android, Firebase automatically manages connection state to reduce bandwidth and battery usage. When a client has no active listeners, no pending write or onDisconnect operations, and is not explicitly disconnected by the goOffline method, Firebase closes the connection after 60 seconds of inactivity.

So on Android, you can also take advantage of the connection state management. So once you implement the above solution, you'll see that the SDK manages this dynamically in a way that the connections disconnect automatically if there are no listeners attached and if no write operations using setValue() are made in the app in last 60 seconds, but the presence of a ValueEventListners will override this and will ensure continuous connectivity with the database. You can also take a look at answers within this post.

There is also another post that I recommend you to read for a better understanding.



来源:https://stackoverflow.com/questions/53069484/firebase-realtime-database-info-connected-false-when-it-should-be-true

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!