离线时删除,添加和更新Firestore文档

时间:2019-11-13 04:43:11

标签: swift google-cloud-firestore

我一直在我的iOS Swift应用中使用以下代码:

class ProfileController
{
    func remove(pid: String, completion: @escaping ErrorCompletionHandler)
    {
        guard let uid = self.uid else
        {
            completion(Errors.userIdentifierEmpty)
            return
        }

        let db = Firestore.firestore()
        let userDocument = db.collection("profiles").document(uid)
        let collection = userDocument.collection("profiles")
        let document = collection.document(pid)

        document.delete()
        {
            error in

            completion(error)
        }
    }
}

设备在线时,一切正常。 delete调用的完成处理程序已正确执行。但是,当我离线时,我注意到只要离线,就不会执行完成处理程序。我一回到网上,就会立即调用完成处理程序。 我不想等到用户重新联机(这可能要花一辈子的时间),所以我稍微更改了代码并添加了ListenerRegistration

class ProfileController
{
    func remove(pid: String, completion: @escaping ErrorCompletionHandler)
    {
        guard let uid = self.uid else
        {
            completion(Errors.userIdentifierEmpty)
            return
        }

        let db = Firestore.firestore()
        let userDocument = db.collection("profiles").document(uid)
        let collection = userDocument.collection("profiles")
        let document = collection.document(pid)

        var listener: ListenerRegistration?

        listener = document.addSnapshotListener(includeMetadataChanges: false)
        {
            snapshot, error in

            listener?.remove() // Immediately remove the snapshot listener so we only receive one notification.

            completion(error)

            listener = nil
        }

        document.delete()
    }
}

尽管这很好,但我不确定这是否是正确的方法。我已经在线阅读了可以在实时场景中使用快照侦听器的信息,这并不是我真正想要的(或我所需要的)。 这是正确的方法还是其他(更好)的方法?我只想得到一次通知(因此我添加了includeMetadataChanged属性并将其设置为false)。一旦完成处理程序被调用一次,我还将删除ListenerRegistration

如果第一种方法在脱机时无法正常工作-这种方法的用例是什么?在我将整个代码库更改为使用侦听器之前,有什么方法可以在设备离线时执行第一种方法的完成处理程序?

TL; DR :第二种实现效果很好,我只是不确定这是否是设备离线时接收通知的正确方法。

1 个答案:

答案 0 :(得分:1)

  

如果第一种方法在脱机时无法正常工作-这种方法的用例是什么?

这取决于您所说的“正常工作”的意思。您观察到的行为完全符合预期。直到在服务器上注册写操作后,它们才能“完成”。

但是,所有写入(不是事务)实际上都是在到达服务器之前在本地提交的。这些本地更改将最终在将来的某个时刻与服务器同步,即使该应用被终止并重启。更改不会丢失。只要用户继续启动应用程序,您就可以依靠更改的同步最终使其到达服务器-这就是您所期望的。您可以在documentation中阅读有关脱机持久性的更多信息。

如果您需要了解先前的更改是否已同步,则没有简便的方法来确定应用程序是否已被终止并重新启动。如果您知道所写文档的ID,则可以尝试查询该数据,并且可以检查文档的元数据以找出数据源(缓存或服务器)。但是最后,您真的应该相信,更改将在最早的方便时与服务器同步。

如果您的用例需要更多粒度的信息,请file a feature request with Firebase support