设置Firestore文档时如何检测缺少的网络连接 [英] How to detect absent network connection when setting Firestore document

查看:93
本文介绍了设置Firestore文档时如何检测缺少的网络连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用Firestore构建实时聊天应用程序.我们需要处理不存在Internet连接的情况.基本消息发送代码如下所示:

We are building a real-time chat app using Firestore. We need to handle a situation when Internet connection is absent. Basic message sending code looks like this

let newMsgRef = database.document("/users/\(userId)/messages/\(docId)")
newMsgRef.setData(payload) { err in
   if let error = err {
       // handle error
   } else {
      // handle OK
   }
}

连接设备后,一切正常.当设备未连接时,不会调用回调,并且我们也不会得到错误状态.

When device is connected, everything is working OK. When device is not connected, the callback is not called, and we don't get the error status.

当设备重新联机时,记录将出现在数据库和回调触发器中,但是我们无法接受此解决方案,因为与此同时,应用程序可能已终止,因此我们将永远无法获得回调并能够进行设置发送消息的状态.

When device goes back online, the record appears in the database and callback triggers, however this solution is not acceptable for us, because in the meantime application could have been terminated and then we will never get the callback and be able to set the status of the message as sent.

我们认为禁用离线持久性(默认情况下处于启用状态)会使它立即触发故障回调,但出乎意料-不会.

We thought that disabling offline persistence (which is on by default) would make it trigger the failure callback immediately, but unexpectedly - it does not.

我们还尝试添加一个超时,在此超时之后,发送操作将被视为失败,但是由于Firestore使用其队列,因此无法恢复设备恢复在线状态时的消息传递,这会导致更多的混乱,因为消息是在接收方发送,而我在发送方无法处理.

We also tried to add a timeout after which the send operation would be considered failed, but there is no way to cancel message delivery when the device is back online, as Firestore uses its queue, and that causes more confusion because message is delivered on receiver’s side, while I can’t handle that on sender’s side.

如果我们可以减少超时时间(这可能是一个很好的解决方案),我们会迅速获得成功/失败状态,但Firebase不会提供此类设置.

If we could decrease the timeout - it could be a good solution - we would quickly get a success/failure state, but Firebase doesn’t provide such a setting.

内置脱机缓存可能是另一种选择,我可以将所有写入视为成功并依靠Firestore同步机制,但是如果应用程序在脱机期间终止,则消息不会传递.

A built-in offline cache could be another option, I could treat all writes as successful and rely on Firestore sync mechanism, but if the application was terminated during the offline, message is not delivered.

最终,我们需要一个一致的反馈机制,该机制将触发回调,或者提供一种监视队列中消息的方式,等等.因此,我们可以确定消息是否已经发送以及何时发送.

Ultimately we need a consistent feedback mechanism which would trigger a callback, or provide a way to monitor the message in the queue etc. - so we know for sure that the message has or has not been sent, and when that happened.

推荐答案

仅当在服务器上写入(或拒绝)数据时,才会调用Firestore的完成回调.没有网络连接时没有回调,因为这对于Firestore SDK是正常情况.

The completion callbacks for Firestore are only called when the data has been written (or rejected) on the server. There is no callback for when there is no network connection, as this is considered a normal condition for the Firestore SDK.

您最好的选择是检测是否存在另一种网络连接,然后相应地更新您的UI.一些相关的搜索结果:

Your best option is to detect whether there is a network connection in another way, and then update your UI accordingly. Some relevant search results:

  • Check for internet connection with Swift
  • How to check for an active Internet connection on iOS or macOS?
  • Check for internet connection availability in Swift

或者,您可以检查使用Firestore的内置元数据来确定是否已传递邮件.如有关本地更改的事件的文档中所示:

As an alternatively, you can check use Firestore's built-in metadata to determine whether messages have been delivered. As shown in the documentation on events for local changes:

检索到的文档具有metadata.hasPendingWrites属性,该属性指示文档是否具有尚未写入后端的本地更改.您可以使用此属性来确定快照侦听器收到的事件的来源:

Retrieved documents have a metadata.hasPendingWrites property that indicates whether the document has local changes that haven't been written to the backend yet. You can use this property to determine the source of events received by your snapshot listener:

db.collection("cities").document("SF")
    .addSnapshotListener { documentSnapshot, error in
        guard let document = documentSnapshot else {
            print("Error fetching document: \(error!)")
            return
        }
        let source = document.metadata.hasPendingWrites ? "Local" : "Server"
        print("\(source) data: \(document.data() ?? [:])")
    }

与此同时,您还可以在用户界面中正确显示消息

With this you can also show the message correctly in the UI

这篇关于设置Firestore文档时如何检测缺少的网络连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆