Firebase Unity:如何处理没有互联网连接的情况

Posted

技术标签:

【中文标题】Firebase Unity:如何处理没有互联网连接的情况【英文标题】:Firebase Unity: How to handle no internet connection situations 【发布时间】:2020-10-24 16:03:05 【问题描述】:

我想做的事

我有一个Unity的小游戏,我将用户分数存储在firebase实时数据库中以稍后显示排行榜,当用户第一次进入游戏时,我还询问用户名并使用deviceId保存(以识别设备)。所以现在我想处理当用户没有连接到互联网时的情况,我想将该数据存储在设备中,当用户获得连接或再次进入游戏时,我将更新 firebase 实时数据库中的数据。

我的问题是什么

这里的问题是firebase不会抛出任何没有连接的异常,它只是一直尝试连接到互联网,直到有连接。您可能会建议在用户进入游戏时检查互联网连接,但我也想在用户开始连接互联网并假设在游戏期间用户将失去互联网的情况下处理它,如果发生这种情况我想如上所述,将数据存储在设备中。所以我需要捕捉没有互联网连接的情况才能在设备中存储数据。

我的尝试

1)

DatabaseReference connectedRef = FirebaseDatabase.DefaultInstance.GetReference(".info/connected");
    connectedRef.ValueChanged += (object sender, ValueChangedEventArgs a) => 
    bool isConnected = (bool)a.Snapshot.Value;
    Debug.Log(isConnected);
;

当用户在游戏过程中失去互联网连接时不会触发,所以我无法捕捉到没有互联网连接异常

2)

Task timeoutTask = Task.Delay(1000);
Task firebaseConnection = await database.Child("users").GetValueAsync();
if (await Task.WhenAny(firebaseConnection, timeoutTask) == firebaseConnection) 
    Debug.Log("timeout");
 else 
    Debug.Log("completed");

我认为在 firebase 连接上设置超时将是目前唯一的解决方案,但这也不起作用Debug.Log("timeout"); 在没有互联网连接时从不登录。

我一直在为此寻找解决方案,只找到了那些似乎可行的 2 个答案,但没有运气,我没有想法,不知道如何解决这个问题。期待您的帮助,谢谢。

【问题讨论】:

您可以在尝试将数据提交到数据库时进行检查,而不是检查连接。如果连接未启动,则返回的任务将属性 IsFaulted 为 true。见:firebase.google.com/download/… 你能告诉我你在哪个平台上看到了这种行为吗?例如,如果您只在编辑器中进行测试,它可能是特定于编辑器的错误。另请注意,离线读取/写入仍然成功是 RTDB 持久性功能的一个特点。如果您使用 ValueChanged 侦听器读取数据并使用 Transactions 写入,您通常可以忽略数据库的连接状态(您将首先访问缓存,事务将让您在发生冲突时重播更改)。 @RyanJMcGowan 不,如果没有互联网连接,它永远不会触发 @PatrickMartin hmm 是的,我认为这可能是相关的,我只在编辑器中测试过,我的目标平台是 androidios,您能告诉我应该为这些平台使用哪种解决方案吗?跨度> 在这种情况下,尝试构建到设备并使用".info/connected" 监控连接。如果它确实适用于设备,请在此处提交问题:github.com/firebase/firebase-cpp-sdk/issues。基本上在 iOS 和 Android 上,C++ (Unity) SDK 回退到 Java 和 ObjC SDK。在桌面上(在编辑器中),它是 100% 用 C++ 实现的——所以这个特性可能没有实现(事实上,它可能只设置为 false:github.com/firebase/firebase-cpp-sdk/…,但我对这个特性还不够熟悉可以肯定地说) 【参考方案1】:

编辑:

以下代码在我的机器上运行,在 MacOS 上的 Unity SDK 6.15.1 和 6.13 的编辑器中:

FirebaseDatabase.DefaultInstance.GetReference(".info/connected").ValueChanged += HandleConnectedChanged;
FirebaseDatabase.DefaultInstance.GetReference(".info/serverTimeOffset").ValueChanged += HandleServerTimeOffsetChanged;
private void HandleServerTimeOffsetChanged(object sender, ValueChangedEventArgs e)

    Debug.Log($"Offset: e.Snapshot.Value");


private void HandleConnectedChanged(object sender, ValueChangedEventArgs e)

    Debug.Log($"Connected: e.Snapshot.Value");

虽然进入“无连接”状态可能需要一些时间(例如,当您关闭 WiFi 时它不会立即触发)但会立即响应 GoOffline()GoOnline

总结一下cmets:

".info/connected" 在 iOS 和 Android SDK 中实现,因此在设备上可用。在 Unity 编辑器中进行测试时,使用了 platform specific backend SDKs written in C++ 的重新实现,它没有完全实现诸如 ".info/connected" 之类的特殊节点(从 6.15.1 开始)。要测试与实时数据库当前连接状态相关的逻辑,您必须部署到物理设备。

此外,尝试以主要依靠ValueChanged 读取数据和RunTransaction 写入数据的方式设计您的游戏。这将使您能够在各种网络条件下保持弹性,并帮助您在竞争条件下强化您的游戏,如果您需要它们以进行快速测试,这些将在 Unity 编辑器中工作。

【讨论】:

你知道这是否也适用于 Firestore?

以上是关于Firebase Unity:如何处理没有互联网连接的情况的主要内容,如果未能解决你的问题,请参考以下文章

Firebase 如何处理离线时执行的事件?

如何处理服务器网络连接不稳定?

登录时如何处理状态(Ionic、Firebase、AngularJS)?

如何处理 Firebase Cloud Functions 中的错误 JSON?

如何处理firebase中多个where查询的索引?

如何处理 Firebase 中过期的用户 ID 令牌?