【问题标题】:Detect if Firebase connection is lost/regained检测 Firebase 连接是否丢失/重新获得
【发布时间】:2012-07-06 07:00:22
【问题描述】:

是否有适用于当前 Firebase 产品的策略来检测服务器连接是否丢失和/或重新获得?

我正在考虑一些针对移动设备的离线突发事件,我想要一种可靠的方法来确定 Firebase 数据层何时可用。

【问题讨论】:

    标签: firebase


    【解决方案1】:

    这是一个普遍要求的功能,我们刚刚发布了一个 API 更新让您可以做到这一点!

    var firebaseRef = new Firebase('http://INSTANCE.firebaseio.com');
    firebaseRef.child('.info/connected').on('value', function(connectedSnap) {
      if (connectedSnap.val() === true) {
        /* we're connected! */
      } else {
        /* we're disconnected! */
      }
    });
    

    完整文档可在https://firebase.google.com/docs/database/web/offline-capabilities 获得。

    【讨论】:

    • 迈克尔,非常感谢。您的团队似乎总是领先一步。
    • 另一个问题是,当您实际上希望连接保持正常,但您的服务器出现故障时......而不是尝试请求新连接,它只是反复尝试重新连接到“关闭”服务器。 :(
    • 嘿@Shawn,不幸的是,这是目前预期的行为。对于给定的 Firebase,客户端必须连接到特定的服务器。如果服务器出现故障,我们可以将 Firebase 移至另一台服务器所有,但这是一个手动过程,因此您会看到客户端尝试连接到故障服务器的一段时间。您可以期待这种行为(以及一般的正常运行时间)在未来几个月内会有所改善。
    • 很公平。感谢您的跟进。 :)
    • 你好,这段代码还有意义吗?当我使用setInterval 对其进行测试时,我收到一个接一个的“已连接”和“未连接”答案。我的意思是我先是“未连接”,但一秒钟后它切换到“已连接”,为什么?
    【解决方案2】:

    更新: 对于许多与状态相关的功能,客户端知道它何时在线或离线很有用。 Firebase 实时数据库客户端在 /.info/connected 提供了一个特殊位置,每次客户端的连接状态更改时都会更新该位置。这是一个例子:

    DatabaseReference connectedRef = FirebaseDatabase.getInstance().getReference(".info/connected");
    connectedRef.addValueEventListener(new ValueEventListener() {
      @Override
      public void onDataChange(DataSnapshot snapshot) {
        boolean connected = snapshot.getValue(Boolean.class);
        if (connected) {
          System.out.println("connected");
        } else {
          System.out.println("not connected");
        }
      }
    
      @Override
      public void onCancelled(DatabaseError error) {
        System.err.println("Listener was cancelled");
      }
    });
    

    【讨论】:

    • 您好,我一直在尝试将 Firebase 添加到我的项目中,但总是得到“未连接”。知道可能出了什么问题吗?
    • 这里也一样。有什么建议吗?
    • 这是安卓平台
    • @Waza_Be 您必须将您的项目的 google-services.json 添加到您的项目中的 app 文件夹中才能使其正常工作(Android 解决方案)
    【解决方案3】:

    我想这在过去几个月里发生了变化。目前的说明在这里: https://firebase.google.com/docs/database/web/offline-capabilities

    总之:

    var presenceRef = firebase.database().ref("disconnectmessage");
    // Write a string when this client loses connection
    presenceRef.onDisconnect().set("I disconnected!");
    

    和:

    var connectedRef = firebase.database().ref(".info/connected");
    connectedRef.on("value", function(snap) {
      if (snap.val() === true) {
        alert("connected");
      } else {
        alert("not connected");
      }
    });
    

    我承认我不太了解引用是如何设置的,或者这意味着什么(你是凭空制作它们还是必须事先创建它们?)或者其中哪一个会在服务器上触发一些东西,而不是在前端触发一些东西,但是如果在您阅读本文时链接仍然是最新的,那么阅读更多内容可能会有所帮助。

    【讨论】:

    • Firebase 是一个 NoSQL JSON 数据存储,因此它没有架构。因此,您可以凭空挑选它们,设置一个值,然后它们就存在了:)
    • 老实说……在仅仅使用了 8 年 SQL 之后,我花了相当长的时间来了解 NoSQL……但它确实很棒。
    • 我正在使用同样的东西。但是当用户失去他的互联网连接时,它就不起作用了。
    • @Nirmalsinh:这个答案已经有两年多了。这可能不再是这样做的方式了。如果您尝试了此处发布的所有答案,但它们都不起作用,您可以发布一个新问题,详细说明您的情况并解释这些都不起作用。
    【解决方案4】:

    对于 android,您可以通过一个名为 onDisconnect() 的函数使用户离线

    我在我的一个聊天应用程序中执行此操作,如果网络连接丢失或用户与互联网断开连接

    ,用户需要自动下线
    DatabaseReference presenceRef = FirebaseDatabase.getInstance().getReference("USERS/24/online_status");
    
    presenceRef.onDisconnect().setValue(0);
    

    在与网络断开连接时,我将 online_status 设为 Firebase 中 ID 为 24 的用户的 0。

    getReference("USERS/24/online_status") 是您需要离线/在线更新的值的路径。

    你可以在offline capabilities阅读它

    请注意,firebase 执行 onDisconnect() 函数需要大约 2-10 分钟的时间。

    【讨论】:

    • 如果您在聊天应用程序中添加此内容,其中聊天应用程序需要显示即时更改,并且正如您所说,firebase 需要 2-10 分钟来执行onDIsconnect(),那么您将如何管理用户状态。
    • @androidXP 这可能是 Firebase 的问题,实际上,有时需要 10 分钟才能更新状态。
    • 那么我们需要即时更改的在线离线状态依赖于firebase是否很好?
    • 当用户关闭 wifi/移动数据时,我找不到任何其他更好的解决方案来更新在线/离线状态。没有互联网连接时我们如何更新状态!
    • 如果用户按下后退按钮或主页按钮,它应该向其他用户显示离线或离开,但如果像您所说的那样需要 2-10 分钟,那么它可能会在用户之间造成混淆。感谢您的回复
    【解决方案5】:

    firebase for web

    firebase.database().ref(".info/connected").on("value",(snap)=> {});
    

    【讨论】:

      【解决方案6】:

      建议的解决方案对我不起作用,因此我决定通过写入和读取“健康/检查”值来检查连接。这是代码:

      const config = {databaseURL: `https://${projectName.trim()}.firebaseio.com/`};
      //if app was already initialised delete it
      if (firebase.apps.length) {
          await firebase.app().delete();
      }
      // initialise app
      let cloud = firebase.initializeApp(config).database();
      // checking connection with the app/database
      let connectionRef = cloud.ref('health');
      connectionRef.set('check')
          .then(() => {
              return connectionRef.once("value");
          })
          .then(async (snap) => {
              if (snap.val() === 'check') {
                  // clear the check input
                  await connectionRef.remove();
                  // do smth here becasue it works
          }
      });
      

      【讨论】:

        猜你喜欢
        • 2010-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-19
        • 1970-01-01
        • 2016-09-15
        • 2016-09-04
        相关资源
        最近更新 更多