我在我的应用中使用Firestore。 According to the documentation,它支持离线数据持久性,并且当网络再次打开时,Firestore会同步更改。
这是我的代码。
2019/10/09 13:00.05.12345 >> POST http://mytest.url HTTP/1.1
2019/10/09 13:00.05.67890 >> User-Agent: My Agent
2019/10/09 13:00.06.12345 >> Hello World
2019/10/09 13:00.10.12345 << HTTP/1.1 200 OK
2019/10/09 13:00.11.12345 << Connection: Keep Alive
2019/10/09 13:00.12.12345 << Hello My Agent
它按预期工作:如果网络关闭,它将在本地缓存,并在网络再次打开时进行同步。但我不断收到此警告:
FirebaseFirestore db = FirebaseFirestore.getInstance();
User user = new User();
db.collection("users").document("doc").set(user);
This post说这是由于没有互联网连接。如果Firestore支持离线持久性,为什么会收到此警告?如何摆脱这个警告?
答案 0 :(得分:1)
它能按预期工作:如果网络关闭,它将在本地兑现,并在网络再次打开时进行同步。
这是预期的行为。
但我不断收到此警告:
W/ManagedChannelImpl: [{0}] Failed to resolve name. status={1}
此post说这是由于没有互联网连接。
那条正确的帖子,是因为没有互联网连接。
如果Firestore支持离线持久性,为什么我会收到此警告?
之所以能够得到它,是因为在重新建立Internet连接的时间到侦听器实际变为活动状态的时间之间,有一段时间没有客户端连接到服务器。这就是为什么除非网络打开并且客户端再次与服务器同步,否则警告会多次打印而不会停止的原因。
重试未如您期望的那样快进行的原因是,执行重试的代码使用的是所谓的exponential backoff算法。这意味着该代码可防止在用户设备上如此快速地进行所有重试,从而提高了性能。重试次数过多也会占用过多的数据计划带宽,从而影响用户。
当您正在侦听Cloud Firestore数据库中的更改并且网络断开连接时,这种情况正在发生,不幸的是您无能为力。您无法控制Firebase Firestore SDK如何管理其连接。
如何摆脱这个警告?
IMO,由于它只是警告,不是异常,并且仅显示几秒钟,直到重新建立连接为止,您只需忽略它即可。
但是,如果您真的想摆脱它,下面的代码可能会对您有所帮助。请注意,我尚未测试。
InstantiatingGrpcChannelProvider channelProvider = InstantiatingGrpcChannelProvider.newBuilder()
.setKeepAliveTime(Duration.ofSeconds(60L))
.setKeepAliveTimeout(Duration.ofMinutes(5L))
.build();
FirestoreOptions firestoreOptions = FirestoreOptions.newBuilder()
.setChannelProvider(channelProvider).build();
FirebaseOptions firebaseOptions = new FirebaseOptions.Builder()
.setCredentials(credentials).setFirestoreOptions(firestoreOptions)
.setConnectTimeout(5000).setReadTimeout(5000).build();
FirebaseApp firebaseApp = FirebaseApp.initializeApp(firebaseOptions);
Firestore firestore = FirestoreClient.getFirestore(firebaseApp);