在Firestore Java admin SDK中无法通过网络断开和重新连接收到文档更新

时间:2018-11-15 06:44:59

标签: java firebase google-cloud-firestore

我正在使用Java admin SDK在本地PC的Firestore中设置查询手表。如果网络断开并重新连接,则本地计算机将不再接收更新。我观察到,如果网络重新连接发生的时间很短(<2-3分钟),那就很好。但是,如果时间更长,则会发生此问题。另外,在侦听器回调中不会通知任何错误/异常,因此我可以再次设置监视更新的方法。我的PC不在代理服务器之后,所以不能成为代理服务器问题。

请帮助我调试此问题。

编辑:

这似乎是SDK中的错误。我启用了SDK日志并尝试了以下实验:

  • 场景1:

    1. 观察查询更新
    2. 客户端与服务器建立GRPC连接。
    3. 服务器似乎每分钟都向客户端发送一个keep alive(?),但客户端到服务器之间却没有保持活动状态
    4. 断开网络连接
    5. 在一分钟内重新连接,查询连接仍处于活动状态,文档更新按预期到达
    6. 断开网络连接
    7. 5分钟后重新连接
    8. 在这里我的猜测是,服务器将无法从其末端重置GRPC连接,因为它无法到达客户端,但SDK对此一无所知。仍然希望服务器发送保持活动状态。
    9. 未按预期在客户端收到文档更新
    10. 发出一个新查询并查看其更新。
    11. SDK尝试通过先前建立的GRPC连接发送查询,意识到该连接已关闭,并打开了一个新的GRPC连接。现在,两个查询的文档更新都开始了。
  • 场景2:

    1. 观察查询更新
    2. 断开网络约5分钟
    3. 在重新连接网络之前发出新的查询。
    4. SDK尝试通过先前建立的GRPC连接发送查询,意识到该连接已关闭,并打开了一个新的GRPC连接。即使失败,但每分钟会重试连接尝试。
    5. 重新连接网络。
    6. SDK的连接尝试成功,并且两个查询都开始更新。

2 个答案:

答案 0 :(得分:0)

当您正在侦听Cloud Firestore数据库中的更改并且某些网络断开连接时,很遗憾您无能为力。您无法控制Firebase Firestore SDK如何管理其连接。

重试未如您期望的那样快发生的原因是,执行重试的代码没有使用所谓的exponential backoff算法。这意味着该代码可防止在用户设备上如此快速地进行所有重试,从而提高了性能。重试次数过多也会占用过多的数据计划带宽,从而影响用户。

结论是,这意味着可能需要一些时间来重新建立连接,因此您应该对此耐心等待。

答案 1 :(得分:0)

必须启用GRPC keepalive,客户端才能将keepalive发送到服务器并检测从服务器端关闭的所有连接。 这可以通过在初始化TransportChannelProvider时在FirestoreOptions中提供FirebaseApp来完成。 代码段如下:

InstantiatingGrpcChannelProvider channelProvider =
    InstantiatingGrpcChannelProvider.newBuilder()
        .setKeepAliveTime(Duration.ofSeconds(60L))
        .setKeepAliveTimeout(Duration.ofMinutes(5L))
        .build();

FirestoreOptions firestoreOptions = FirestoreOptions.newBuilder()
    .setChannelProvider(channelProvider).build();

FirebaseOptions options = new FirebaseOptions.Builder()
    .setCredentials(credentials).setFirestoreOptions(firestoreOptions)
    .setConnectTimeout(5000).setReadTimeout(5000).build();
FirebaseApp firebaseApp = FirebaseApp.initializeApp(options);

Firestore firestore = FirestoreClient.getFirestore(firebaseApp);