【问题标题】:Firestore @ Android - listener is lagging on app resumeFirestore @ Android - 监听器在应用程序恢复上滞后
【发布时间】:2021-07-20 08:43:54
【问题描述】:

我在 Android 应用上使用 FireStore(不是 Firebase 实时数据库)。

当应用加载时,我正在向集合中添加一个监听器(参见下面的代码)

监听器工作得很好,只要应用程序处于活动状态,它就会正确更新。

但是,在应用程序进入后台后,在恢复应用程序时,侦听器有时会延迟大约 60-90 秒,直到它随着来自服务器的更改而更新。如果我关闭应用程序并重新启动它,它会立即更新。

当应用程序停止时,我分离监听器,并在 OnResume 上恢复它。我也尝试过不分离监听器,但我遇到了同样的问题。

有人知道怎么解决吗?见以下代码:

监听器(正在初始化 OnResume):

m_registration = db.collection('names').
        orderBy("stamp", Query.Direction.ASCENDING)
                .addSnapshotListener(new EventListener<QuerySnapshot>() {
                    @Override
                    public void onEvent(@Nullable QuerySnapshot value,
                                        @Nullable FirebaseFirestoreException e) {
                        if (e != null) {
                            Log.w(TAG, "Listen failed.", e);
                            return;
                        }

                        for (DocumentChange dc : value.getDocumentChanges()) {
 
                        }

在停止时,我正在分离监听器:

m_registration.remove();

【问题讨论】:

  • 当应用程序处于后台时,您的应用程序是否会以某种方式失去互联网连接?
  • 很难说,也许是几秒钟。使用手机时,显然无论走到哪里都没有接收信号。我猜你基本上是在问套接字是否断开连接?假设是,为什么重新连接 OnResume 需要这么多时间?与应用启动有关吗?
  • 但在你的情况下,在更新之前的 60-90 秒之前,有没有可能断开连接?
  • 您是否在 logcat 中收到 Failed to resolve name. status={1} 这样的消息?你能查一下吗?
  • 您是在询问是否在 OnResume 之前立即断开连接?我不这么认为。我对它进行了很多测试,主要是在互联网良好的地方。

标签: java android firebase google-cloud-firestore


【解决方案1】:

根据 cmets 部分的这个问题:

您是否在 logcat 中收到 Failed to resolve name. status={1} 这样的消息?

这个答案:

我检查了 logcat,我确实看到了这条消息。

我可以告诉你,这是由于用户设备上没有互联网连接而发生的,在你重新连接互联网到监听器实际激活的时间之间,有您的客户端未连接到服务器的时间量。这就是在 logcat 中打印出该警告的原因。很可能会多次打印而不会停止,直到网络重新开启并且客户端再次与 Firebase 服务器同步。

这些重试没有像您预期的那么快发生并且您遇到延迟(60-90 秒)的原因是因为执行重试的代码使用了所谓的Exponential backoff algorithm。这意味着此代码可以防止用户设备上可能发生的所有重试,以提高性能。过多的重试也会通过消耗过多的数据计划带宽来影响用户。这确实不是你想要的。

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

如果你想摆脱它,IMO,因为它只是一个警告并且不是一个例外,你可以简单地忽略它。但是,我找到了一种可以解决此问题的方法:

我没有测试过这个解决方案,但你可以试一试。

【讨论】:

  • 2个问题:1.如果监听器被分离,为什么客户端仍然尝试连接到服务器? 2. 如果我对源服务器进行 GET 请求,是否可以解决这个问题?
  • 如果我使用API​​在停止时禁用网络并在恢复时启用它,它可以解决问题吗?
  • 创建 FirebaseFirestore 实例和监听实时更新是完全不同的两件事。如果您移除侦听器以停止侦听更新,这并不意味着 FirebaseFirestore 实例为空。如果您使用Source.SERVER,则意味着每次执行 get() 调用时,您都希望从服务器检索数据。此外,如果您在 onStop 中禁用网络,则意味着任何其他依赖该网络的服务都将失败。所以恐怕这不是一个好主意。
  • 嗨大卫!我可以帮助您了解其他信息吗?如果您认为我的回答对您有所帮助,请考虑采纳(✔️)。我真的很感激。谢谢!
  • 嗨,Alex,感谢您为此付出的所有努力!我现在正在开发中,还没有机会查看您的答案。我不是很了解它,还没有测试过。在我测试并看到它工作正常后,我可以将答案标记为可以接受。
猜你喜欢
  • 2018-11-02
  • 2019-08-17
  • 2017-09-14
  • 1970-01-01
  • 1970-01-01
  • 2011-11-27
  • 1970-01-01
  • 1970-01-01
  • 2021-01-19
相关资源
最近更新 更多