Firestore 和 SwiftUI - 我的快照阅读器是不是不必要地读取数据库?

Posted

技术标签:

【中文标题】Firestore 和 SwiftUI - 我的快照阅读器是不是不必要地读取数据库?【英文标题】:Firestore & SwiftUI - is my snapshot reader reading the db needlessly?Firestore 和 SwiftUI - 我的快照阅读器是否不必要地读取数据库? 【发布时间】:2020-07-25 01:18:29 【问题描述】:

我有一个设置了 firebase 的项目,并且我设置了一个类似于 firebase 示例的功能,但是 firebase 文档会更新我的可观察对象中的 @Published vars:


func getDataFromSession(env: GlobalEnvironmentObject) 
db.collection("sessions").document("firstSession")
    .addSnapshotListener  documentSnapshot, error in
      guard let document = documentSnapshot else 
        print("Error fetching document: \(error!)")
        return
      
      guard let data = document.data() else 
        print("Document data was empty.")
        return
      
      print("Current data: \(data)")
      env.data1 = data[data1]
// env.data1 is the @Published bar data1
    

我在我的 swiftui 视图中调用这个函数:

var body: some View 
  
        let fbConnection = FirebaseConnectionHandler(env: env)
        fbConnection.getDataFromSession()

当我运行我的应用程序时,我的调试窗口正在以闪电般的速度执行 print("Current data: (data)") 行,尽管可观察对象/全局环境中的值没有变化。我的印象是快照侦听器只会在数据更改时执行读取,而 swiftui 视图只会在 @Published 属性更改时更新,因此两者都不会发生(所以它不应该像疯了一样读取)。而且我不确定它是否连续执行大量读取,或者该输出是否正常(obv 我只希望它在我的文档发生更改时读取)...

我到底做错了什么?如何防止大型读取并使其仅在数据更新时读取?

【问题讨论】:

【参考方案1】:

欢迎来到 ***。放松,你和 SDK 没有做错什么。您遇到的第一次读取是由于数据的初始状态

查看文档查看快照之间的更改

https://firebase.google.com/docs/firestore/query-data/listen#view_changes_between_snapshots


重要提示:第​​一个查询快照包含所有添加的事件 与查询匹配的现有文档。这是因为你是 获取一组更改,使您的查询快照与 查询的初始状态。例如,这允许您 从您在第一次收到的更改中直接填充您的 UI 查询快照,无需添加特殊逻辑来处理 初始状态。

初始状态可以直接来自服务器,也可以来自本地 缓存。如果本地缓存中有可用的状态,则查询 快照最初将填充缓存的数据,然后 当客户端赶上 服务器的状态。

【讨论】:

这没有意义,因为终端只是一遍又一遍地打印相同的数据......当我删除代码以将我的数据从 firebase 设置为等于可观察对象数据时,似乎工作正常...【参考方案2】:

好的,所以我想通了...如果您要从 firebase 更新可观察对象,请将侦听器对象放在您的视图中(在“var body: some View ”下)...

然后,获取结构中的任何视图(HStack、ZStack 等)并添加一个 .onAppear 修饰符,然后调用该函数从那里更新您的 firebase...

原来视图一直在更新,但 .onAppear 将开始刷新一次...

【讨论】:

【参考方案3】:

所以,当我将数据写入 Firestore 时,我的所有数据都被写入同一个文档。而且,在网上搜索后,我了解到,当谈到 Firestore 中的听众时,这是全有或全无的事情。因此,我的整个文档都被调用和更新,这触发了其他地方的更新,这将调用和触发等等等等。

为了解决这个问题,我将文档拆分为两个文档,其中一个应用程序可以读取其中一个但只能写入另一个,而另一个应用程序反之亦然(读取另一个,写入另一个)。这样,侦听器在每个文档级别调用更改并避免循环...

【讨论】:

以上是关于Firestore 和 SwiftUI - 我的快照阅读器是不是不必要地读取数据库?的主要内容,如果未能解决你的问题,请参考以下文章

Swiftui + Firestore - 无法访问 Firestore 中的字段

删除 SwiftUI 后 Firebase Firestore 不更新 UI

SwiftUI:如何阅读 Firestore 中的特定文档?

SwiftUI+Firestore 中的多选列表

SwiftUI Lists + Firebase Firestore,获取数据然后取消获取? (漏洞)

SwiftUI Firestore 查询游标分页不起作用