Firebase 连接检测在 60 秒后不起作用

Posted

技术标签:

【中文标题】Firebase 连接检测在 60 秒后不起作用【英文标题】:Firebase connection detection does not work after 60 seconds 【发布时间】:2018-08-13 08:13:51 【问题描述】:

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

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 上只有一个侦听器,那么不会保持与服务器的连接。这是设计使然。 【参考方案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 中解决此问题的方法

【讨论】:

以上是关于Firebase 连接检测在 60 秒后不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 推送通知在上传到应用商店 ios 后不起作用

世博会推送通知在构建后不起作用

firebase auth的自动检测验证码不起作用

Firebase 云消息传递 requireInteraction 不起作用

代码在Flask中返回render_template后不起作用

UIButton 操作在一段时间后不起作用(可能在一些垃圾收集之后)