设置 Firestore 文档时如何检测不存在的网络连接

Posted

技术标签:

【中文标题】设置 Firestore 文档时如何检测不存在的网络连接【英文标题】:How to detect absent network connection when setting Firestore document 【发布时间】:2019-07-12 23:42:30 【问题描述】:

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

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

连接设备后,一切正常。设备未连接时,不会调用回调,也不会得到错误状态。

当设备重新上线时,记录出现在数据库中并触发回调,但是这种解决方案对我们来说是不可接受的,因为在此期间应用程序可能已经终止,然后我们将永远不会得到回调并且能够设置已发送消息的状态。

我们认为禁用离线持久性(默认启用)会使其立即触发失败回调,但出乎意料 - 它没有。

我们还尝试添加超时,在此之后发送操作将被视为失败,但是当设备重新联机时无法取消消息传递,因为 Firestore 使用其队列,这会导致更多混乱,因为消息是在接收方交付,而我无法在发送方处理。

如果我们可以减少超时 - 这可能是一个很好的解决方案 - 我们会很快获得成功/失败状态,但 Firebase 不提供这样的设置。

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

最终,我们需要一个一致的反馈机制来触发回调,或者提供一种方法来监控队列中的消息等 - 这样我们就可以确定消息是否已发送,以及何时发送。

【问题讨论】:

【参考方案1】:

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

您最好的选择是通过其他方式检测是否存在网络连接,然后相应地更新您的 UI。一些相关的搜索结果:

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 的内置元数据来确定消息是否已送达。如图documentation on events for local changes:

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

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() ?? [:])")
    

这样,您还可以在 UI 中正确显示消息

【讨论】:

谢谢,我知道只有在服务器通信后才会调用回调。我真正想知道的是如何可靠地传递(或不传递)消息。我考虑过使用一些工具来检测可达性,但它不是 100% 可靠的:我需要在发送任何单个消息之前检查这一点,并且可能会在检查后但在 Firebase 写入之前断开连接。我知道这是一个值得怀疑的情况,但无论如何我都不想面对这样的问题

以上是关于设置 Firestore 文档时如何检测不存在的网络连接的主要内容,如果未能解决你的问题,请参考以下文章

使用实时更新时如何检查 Cloud Firestore 文档是不是存在

在 Firestore 中通过 docId 批量设置文档字段时遇到问题

在 Firestore 上存储文档:检测操作是不是在服务器上成功、本地或不成功?

Firestore,检测添加到集合中的新文档等

如何使用云功能删除 Firestore 中的文档

在 Firebase Firestore 中注册时设置文档 ID