设置Firestore文档时如何检测缺少网络连接

cle*_*leg 5 firebase swift google-cloud-firestore

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

let newMsgRef = database.document(“/users/\(userId)/messages/\(docId)“)
newMsgRef.setData(payload) { err in
   if let error = err {
       // handle error
   } else {
      // handle OK
   }
}
Run Code Online (Sandbox Code Playgroud)

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

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

我们认为禁用离线持久性(默认情况下处于启用状态)会使其立即触发失败回调,但出乎意料的是 - 事实并非如此。

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

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

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

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

Fra*_*len 5

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

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

或者,您可以检查使用 Firestore 的内置元数据来确定消息是否已送达。如本地更改事件的文档所示:

检索到的文档有一个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() ?? [:])")
    }
Run Code Online (Sandbox Code Playgroud)

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