Firebase 侦听器在空闲时间后无法识别或恢复连接

Dav*_*tos 5 android firebase firebase-realtime-database

我的项目是识别客户端是在线还是离线。我使用了 Android-Firebase 文档中提供的代码,该文档在“.info/connected”中使用了一个 EventListener。

// since I can connect from multiple devices, we store each connection instance separately
// any time that connectionsRef's value is null (i.e. has no children) I am offline
final FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myConnectionsRef = database.getReference("users/joe/connections");

// stores the timestamp of my last disconnect (the last time I was seen online)
final DatabaseReference lastOnlineRef = database.getReference("/users/joe/lastOnline");

final DatabaseReference connectedRef = database.getReference(".info/connected");
connectedRef.addValueEventListener(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    boolean connected = snapshot.getValue(Boolean.class);
    if (connected) {
      DatabaseReference con = myConnectionsRef.push();

      // when this device disconnects, remove it
      con.onDisconnect().removeValue();

      // when I disconnect, update the last time I was seen online
      lastOnlineRef.onDisconnect().setValue(ServerValue.TIMESTAMP);

      // add this device to my connections list
      // this value could contain info about the device or a timestamp too
      con.setValue(Boolean.TRUE);
    }
  }

  @Override
  public void onCancelled(DatabaseError error) {
    System.err.println("Listener was cancelled at .info/connected");
  }
});
Run Code Online (Sandbox Code Playgroud)

This method correctly identifies when the user terminates or reopens the application or when minor disconnections occur on the internet. However, I did a test turn off the Wifi of the device for a time of 2 minutes, it is identified in the Firebase Database that is not connected, but when I turn on the Wifi, resuming the internet connection, Firebase does not recognize the active connection, appears as if the user still remained inactive.

This code snippet was inserted into the onCreate method of my MainActivity.

Can anyone tell me why this occurs?


EDIT: Attachments

第1步

第2步

第 3 步

Error log:

11-14 10:12:55.272 27901-27926/com.example.davi.projetofirebase D/PersistentConnection: pc_0 - Trying to fetch auth token

11-14 10:12:55.276 27901-27926/com.example.davi.projetofirebase D/PersistentConnection: pc_0 - Successfully fetched token, opening connection

11-14 10:12:55.281 27901-27926/com.example.davi.projetofirebase D/Connection: conn_14 - Opening a connection

11-14 10:12:55.293 27901-27926/com.example.davi.projetofirebase D/WebSocket: ws_14 - WebSocket error. bkx: unknown host: s-usc1c-nss-208.firebaseio.com at bku.d(:com.google.android.gms.DynamiteModulesC@11746448:102) at bkv.run(:com.google.android.gms.DynamiteModulesC@11746448:4) at java.lang.Thread.run(Thread.java:760) Caused by: java.net.UnknownHostException: s-usc1c-nss-208.firebaseio.com at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:174) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:356) at java.net.Socket.connect(Socket.java:586) at com.android.org.conscrypt.OpenSSLSocketImpl.connect(OpenSSLSocketImpl.java:265) at com.android.org.conscrypt.OpenSSLSocketImpl.connect(OpenSSLSocketImpl.java:252) at java.net.Socket.(Socket.java:427) at java.net.Socket.(Socket.java:210) at javax.net.ssl.SSLSocket.(SSLSocket.java:906) at com.android.org.conscrypt.OpenSSLSocketImpl.(OpenSSLSocketImpl.java:192) at com.android.org.conscrypt.OpenSSLSocketFactoryImpl.createSocket(OpenSSLSocketFactoryImpl.java:68) at bku.d(:com.google.android.gms.DynamiteModulesC@11746448:94) at bkv.run(:com.google.android.gms.DynamiteModulesC@11746448:4)  at java.lang.Thread.run(Thread.java:760) 

11-14 10:12:55.294 27901-27926/com.example.davi.projetofirebase D/WebSocket: ws_14 - closing itself

11-14 10:12:55.295 27901-27926/com.example.davi.projetofirebase D/Connection: conn_14 - Realtime connection failed

11-14 10:12:55.295 27901-27926/com.example.davi.projetofirebase D/Connection: conn_14 - closing realtime connection

11-14 10:12:55.295 27901-27926/com.example.davi.projetofirebase D/PersistentConnection: pc_0 - Got on disconnect due to OTHER

11-14 10:12:55.296 27901-27926/com.example.davi.projetofirebase D/PersistentConnection: pc_0 - Scheduling connection attempt

11-14 10:12:55.297 27901-27926/com.example.davi.projetofirebase D/ConnectionRetryHelper: Scheduling retry in 27403ms

11-14 10:12:55.304 27901-27926/com.example.davi.projetofirebase D/WebSocket: ws_14 - closed

11-14 10:13:02.947 27901-27926/com.example.davi.projetofirebase D/PersistentConnection: pc_0 - Connection interrupted for: connection_idle

11-14 10:13:02.960 27901-27926/com.example.davi.projetofirebase D/ConnectionRetryHelper: Cancelling existing retry attempt

Dav*_*tos 5

我联系了 Firebase 支持团队,他们告诉我一个显然解决了我的问题的解决方案:

显然,如果数据库没有活动操作或侦听器,.info/connected 的侦听器将停止侦听。我向数据库中的任何一个节点添加了另一个辅助侦听器,并且它起作用了!

DatabaseReference myConnectionRef2 = database.getReference("/users/joe/lastOnline");
myConnectionRef2.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        if (dataSnapshot.getValue() == null) {
            System.out.println("FIREBASE: Aux connected");
        } else {
            System.out.println("FIREBASE: Aux not connected");
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});
Run Code Online (Sandbox Code Playgroud)

每次失去网络连接时,两个侦听器都会尝试恢复通信,直到网络重新连接。

感谢所有帮助我解决这个问题的人。