【问题标题】:Firebase connection detection does not work after 60 secondsFirebase 连接检测在 60 秒后不起作用
【发布时间】:2023-03-03 21:54:01
【问题描述】:

正如一些答案中所解释的:

在 Android 上,Firebase 会自动管理连接状态以减少带宽和电池使用量。当客户端没有活动的侦听器、没有挂起的写入或 onDisconnect 操作,并且没有通过 goOffline 方法显式断开连接时,Firebase 会在 60 秒不活动后关闭连接。

问题是60年代之后,即使我去一个带有全新引用,事件监听器等的活动之后。它仍然说它是断开连接,而实际上不是。

val connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected")
var connectListener : ValueEventListener? = null

fun checkConnection() {
    connectListener = connectedRef.addValueEventListener(object : ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot) {
            val connected = snapshot.getValue(Boolean::class.java)!!
            if (connected) {
                Log.d("FRAG", "CONNECTED")
            else{
                Log.d("FRAG", "DISCONNECTED")
            }
        }

        override
        fun onCancelled(error: DatabaseError) {
            System.err.println("Listener was cancelled")
        }
    })
}

override fun onDetach() {
    super.onDetach()
    if (connectListener != null){
        connectedRef.removeEventListener(connectListener)
    }
}

如何确保保持或创建与 Firebase 的新连接?我每个片段的onAttach 和一个活动的onStart 调用checkConnection 方法。

【问题讨论】:

  • 如果您对从服务器读取的任何数据都有一个活动侦听器,则连接应该保持打开状态,除非您在代码中明确调用 goOffline()。请注意,.info/connected 本身不需要从服务器读取,因此不会保持连接打开。这听起来有点像XY problem:我感觉整个.info/connected 和超时只是红鲱鱼。你能描述一下真正的根本问题是什么吗?
  • @FrankvanPuffelen,我只想让它跟踪连接状态。因此,如果我停留在屏幕 X 并关闭 wifi/互联网连接,屏幕 X 应显示“无互联网连接”视图。如果我再次打开连接,它应该会淡出“无互联网连接”视图。问题在于 60 秒后停止跟踪连接状态。
  • 我们不要只关注 60 秒设置,因为行为取决于多种因素。如果你关闭 wifi/internet,一段时间后,connectedRef 上的侦听器应该会以 `false 的值触发。这不会发生吗?还是比您预期的要晚?
  • 在 60 秒内一切正常。之后,它只是断开连接并保持false 的值。奇怪的行为是,为了解决这个问题,我会删除onDetach for frag 和onDestroy 活动上的侦听器,然后分别将其再次放在onAttach/onStart 上,它会工作一段时间但即便如此有时它只会显示为断开连接。所以,整个问题是,当收听同一个听众时,60 秒后它总是指向断开连接(连接 =false)。更新监听器时,有时它也只是保持断开连接。
  • 如果您在.info/connected 上只有一个侦听器,那么不会保持与服务器的连接。这是设计使然。

标签: android firebase firebase-realtime-database kotlin


【解决方案1】:

如果您对从服务器读取的任何数据都有一个活动侦听器,则连接应该保持打开状态,除非您在代码中明确调用了goOffline()。请注意,.info/connected 本身不需要从服务器读取,因此不会保持连接打开。

您似乎正在使用实时数据库在基于 Firestore 的应用程序上构建状态系统。在这种情况下:Cloud Firestore 使用基于 gRPC 的协议在客户端和服务器之间进行通信,而 Firebase 实时数据库使用 Web 套接字。它们绝不兼容,甚至没有可比性。在 Firestore 中保持对数据的活动侦听器不会保持与 RTDB 的连接打开。这就是example in the Firestore documentation 还将实际数据节点写入实时数据库的原因。

【讨论】:

    【解决方案2】:
    Stream<Event> checkInternetConectivity() {
        Stream<Event> connectivityCheck = _firebaseDatabase.reference().child('.info/connected').onValue;
        Stream<Event> randomCheck = _firebaseDatabase.reference().child('connected').onValue;
        return Rx.combineLatest2(connectivityCheck, randomCheck,(connectivityCheck, _) => connectivityCheck as Event);}
    }
    

    如果没有活动的侦听器并且侦听“.info/connected”不足以保持连接处于活动状态,Firebase 会在 60 秒后自动断开与 Android 中的实时数据库的连接。创建另一个流以侦听实时数据库中的随机节点,以绕过这种自动断开连接。

    这是我在 Dart/Flutter 中解决此问题的方法

    【讨论】:

      猜你喜欢
      • 2012-05-18
      • 1970-01-01
      • 1970-01-01
      • 2015-03-31
      • 2020-03-31
      • 2019-07-01
      • 2020-09-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多