【发布时间】:2019-04-18 14:47:36
【问题描述】:
我在我的应用中使用 Firestore Beta,我想检查是否存在与 Firestore 数据库的有效在线连接。文档说目前没有直接的方法来查询连接状态,但是可以使用 Firebase 连接状态作为一种解决方法。代码 sn-p 也可以在这部分文档中找到:Build presence in Cloud Firestore。
connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected");
connectionStateListener = connectedRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
Boolean connected = snapshot.getValue(Boolean.class);
if (connected == null) {
changeState(FirebaseConnectionState.error);
return;
}
if (connected) {
changeState(FirebaseConnectionState.connected);
} else {
changeState(FirebaseConnectionState.not_connected);
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
L.i("FirebaseConnectionStateListener was cancelled");
}
});
ValueEventListener 本身正在工作,我会收到状态更新。但由于某种原因,状态在 1 分钟后从“已连接”切换为“未连接”。除了这不正确之外,我无法将其恢复为“已连接”,除非重新启动应用程序。
这是一些调试输出:
2018-11-15 13:38:20.340: [FirebaseHeartbeatConnector] FirebaseHeartbeatConnector() called with: firebaseApp = [FirebaseApp{name=development, options=FirebaseOptions{applicationId=1:xxxxx:android:xxxxx, apiKey=xxxxx, databaseUrl=null, gcmSenderId=null, storageBucket=xxxx.appspot.com, projectId=xxxxx}}]
2018-11-15 13:38:20.480: [FirebaseHeartbeatConnector] startConnecting() called
2018-11-15 13:38:20.482: [FirebaseHeartbeatConnector] doSendFirestoreHeartbeatRequest() called
2018-11-15 13:38:20.840: [FirebaseHeartbeatConnector] change State called
2018-11-15 13:38:20.840: [FirebaseHeartbeatConnector] State changed initial -> not_connected
2018-11-15 13:38:21.380: [FirebaseHeartbeatConnector] change State called
2018-11-15 13:38:21.381: [FirebaseHeartbeatConnector] State changed not_connected -> connected
2018-11-15 13:39:20.514: [FirebaseHeartbeatConnector] change State called
2018-11-15 13:39:20.515: [FirebaseHeartbeatConnector] State changed connected -> not_connected
为什么会这样?如何获得正确的状态更新?
【问题讨论】:
-
在 Android 上,Firebase 会自动管理连接状态以减少带宽和电池使用量。当客户端没有活动的侦听器、没有挂起的写入或
onDisconnect操作,并且没有通过goOffline方法显式断开连接时,Firebase 会在 60 秒不活动后关闭连接。阅读Detecting Connection State 文档的更多信息。 -
如果您没有将 Firebase 实时数据库用于连接状态以外的任何其他内容,您可能需要添加一个空的连接侦听器。如果添加
FirebaseDatabase.getInstance().keepSynced(true);会有所不同,您可以试试吗? -
@FrankvanPuffelen 好主意,但这会引发 DatabaseException: Can't call keepSynced() on .info paths。
-
@Grimthorr 如果我的要求解决了问题,那么确实需要在文档中进行更新。
-
@FrankvanPuffelen 啊哈,我没有意识到
keepSynced(true)创建了一个空侦听器,这是一个巧妙的小技巧,无需手动创建。我刚刚对此进行了测试,仅使用FirebaseDatabase.getInstance().getReference().keepSynced(true);确实可以阻止它在 60 秒后断开连接。
标签: android firebase firebase-realtime-database google-cloud-firestore