【问题标题】:Android Firebase - "onDataChange" And "onCancelled" Not Being Called With No Internet ConnectionAndroid Firebase - 在没有互联网连接的情况下不会调用“onDataChange”和“onCancelled”
【发布时间】:2016-08-18 14:53:31
【问题描述】:

在我的应用程序中,我只是尝试通过在以下代码中添加ListenerForSingleValueEvent 从我的Firebase 数据库中检索阅读文章:

myRef.child("passages").child(passageNum).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                System.out.println("ON DATA CHANGE");
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                System.out.println("DATABASE ERROR");
                FirebaseErrorHandler.handleDatabaseError(databaseError.getCode(), ReadingActivity.this);
            }

        });

当有互联网连接时,它工作得很好。但是,当我故意关闭互联网连接时,onDataChangeonCancelled 都不会被调用。这非常令人沮丧,因为databaseError.getCode() 中的两个错误代码与网络连接问题有关。

如果由于没有互联网而无法获取此数据,我想至少让用户知道,而不是让此侦听器在屏幕不断加载的情况下挂起。有没有办法解决这个问题?我只能求助于Firebase's REST API 吗?至少对于 RESTful 网络请求,它们会让您知道连接是否失败。

【问题讨论】:

    标签: android firebase firebase-realtime-database


    【解决方案1】:

    Firebase 将数据事件流(例如 onDataChange())与其他可能发生的事情分开。它只会在有服务器端原因时调用onCancelled(当前仅当客户端没有访问数据的权限时)。没有理由取消监听,只是因为没有网络连接。

    您似乎正在寻找一种方法来检测是否存在网络连接(这不是特定于 Firebase 的任务)或用户是否连接到 Firebase 数据库后端。后者您可以通过将侦听器附加到 .info/connected 来实现,这是一个隐式布尔值,当您连接到 Firebase 数据库后端时为 true,否则为 false。详情请参阅document on detecting connection state 中的部分。

    【讨论】:

    • 这是一种解决方案,但不是理想的解决方案。我可以在对 firebase 数据库进行任何查询之前检查互联网可用性,但这并不好,因为我想让我的应用程序 100% 脱机。假设,当我第一次在没有互联网连接的情况下启动应用程序时,firebase 数据库没有数据并卡在回调中。如果至少第一次提供 Internet 连接,则该问题在后续运行中消失。如何应对这种情况?如果 Firebase 至少在 onCancelled() 中提供此信息会更好。
    • @AritraRoy 你是如何处理这个 u=issue 的?你找到解决方案了吗?
    • 这真的很不幸,我必须在运行任何查询之前检查一个标志。对于 single value 事件侦听器,如果 Firebase 无法获取该值,则应返回错误。当前的行为只是将所有这些复杂性推高了应用程序来处理。
    • 不幸的是,当有互联网连接,但数据库安全规则阻止应用程序访问时,也会发生这种情况。我应该如何处理这个?
    【解决方案2】:

    希望我的解决方案可以帮助其他人(我假设您已经做了其他事情)

    除了在我的数据库参考中将keepSynced 设置为true

    databaseRef.keepSynced(true)
    

    并添加到我的应用程序类:

    FirebaseDatabase.getInstance().setPersistenceEnabled(true)
    

    我添加了两个监听器,一个用于离线模式,另一个用于在线:

    override fun create(data: BaseObject): Observable<String> {
        return Observable.create { observer ->
            val objectId = databaseRef.push().key
            objectId?.let { it ->
                data.id = it
    
                val valueEvent = object : ValueEventListener {
                    override fun onCancelled(e: DatabaseError) {
                        observer.onError(e.toException())
                    }
    
                    override fun onDataChange(dataSnapshot: DataSnapshot) {
                        observer.onComplete()
                    }
                }
                // This listener will be triggered if we try to push data without an internet connection
                databaseRef.addListenerForSingleValueEvent(valueEvent)
    
                // The following listeners will be triggered if we try to push data with an internet connection
                databaseRef.child(it)
                        .setValue(data)
                        .addOnCompleteListener {
                            observer.onComplete()
                            // If we are at this point we don't need the previous listener
                            databaseRef.removeEventListener(valueEvent)
                        }
                        .addOnFailureListener { e ->
                            if (!observer.isDisposed) {
                                observer.onError(e)
                            }
                            databaseRef.removeEventListener(valueEvent)
                        }
            } ?: observer.onError(FirebaseApiNotAvailableException("Cannot create new $reference Id"))
        }
    }
    

    说实话,我不太喜欢附加两个监听器的想法,如果其他人有更好更优雅的解决方案,请告诉我,我暂时有这个代码,直到我找到更好的东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-21
      • 2017-07-08
      • 1970-01-01
      • 2018-07-08
      • 2015-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多