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

时间:2019-02-19 12:50:02

标签: swift firebase 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
   }
}

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

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:2)

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

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

或者,您可以检查使用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() ?? [:])")
    }

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