【问题标题】:Fetch document only once when Firestore has updatedFirestore 更新后仅获取一次文档
【发布时间】:2021-05-15 16:04:53
【问题描述】:

我有一个 tableView,它从 Firestore 集合中获取所有文档,我想在用户刷新 tableView 后将最后一个文档添加到 Firestore 时只获取一次,之后我想删除监听器,以便在用户刷新时tableView 它只获取一次文档,我使用了 detach listener [从这里的文档] [1] 但它没有用

func updatedFireStoredata() {
    
    
    let listener =  Firestore.firestore().collection("collection1").order(by: "date").limit(toLast: 1).addSnapshotListener() { querySnapshot, error in
        guard let snapshot = querySnapshot else {
            print("Error fetching snapshots: \(error!)")
            return
        }
        snapshot.documentChanges.forEach { diff in
            if (diff.type == .added) {
                
                let data = diff.document.data()
    
                self.amount.append(data["amount"] as? String ?? "")
                
                print("New city: \(diff.document.data())")
            }
            
        }
        
        
    }
    
    table2.reloadData()
    listener.remove()
}

【问题讨论】:

  • 用户每次刷新 tableView 被称为轮询,它可能没有必要(并且可能会让用户感到烦恼)。您应该在您的 firebase 上设置一个 listener 又名 observer,以便当有更新的数据时 firebase 会通知您的应用。
  • @Jay 用户应该刷新 tableView 以显示检索到的新文档,这里的问题是当用户刷新 tableView 应用程序检索文档时,每次用户刷新表视图并且我想检索如果用户刷新 tableView 则只有一次。
  • @Jay 我更新了我的问题,请你检查一下
  • 方法就是问题所在。您不应该要求用户一直按刷新来获取更新的数据。这应该会自动发生,并且用户应该始终拥有当前数据而无需交互。完全删除 listener.remove() 并在 Firebase 闭包中移动 table2.reloadData() 这样当添加新数据时,您的应用程序将自动接收它并更新表。请注意,Firebase 是异步的 - 刷新闭包 outside 的 tableView 将在闭包中执行 before 代码,因此它需要在内部。

标签: arrays swift firebase firebase-realtime-database google-cloud-firestore


【解决方案1】:

如果您的目标是只调用一次来检索此文档,我会考虑使用 SDK 中内置的离线持久性。您需要在启用离线持久性的情况下请求一次文档,但在该调用之后,您可以从该本地缓存请求此数据。

https://firebase.google.com/docs/firestore/manage-data/enable-offline https://firebase.google.com/docs/firestore/manage-data/enable-offline#disable_and_enable_network_access

或者,您可以将文档存储在本地,而不是将其包含在重新加载中。

如果这些数据确实发生了变化,只是不像每次刷新那样频繁,那么将其移至事件模型可能是有意义的。您可以使用 firestore watch/listen 来监控该查询并根据需要获取更新回调。 https://firebase.google.com/docs/firestore/query-data/listen

【讨论】:

  • 我试过了,但它检索了很多次数据,如果重新加载 tableView,请帮助我只想检索一次新数据,我做了很多研究,但我没有找到任何方法所以,请帮助我,我会感谢你的帮助
  • 编写代码的方式是您要求在刷新时重新加载数据。我看到了两条前进的道路:1)这个数据不会改变,你只需要它一次。对此的解决方案是存储文档,而不是在重新加载时刷新它作为创作的一部分。 2)数据确实会发生变化,但可能不会经常发生。您想要更新,但刷新太频繁了。考虑使用 Firestore Watch/Listener。 firebase.google.com/docs/firestore/query-data/listen
  • 我也尝试使用监听器,我面临的同样问题是它多次重新加载数据:(
  • 在这种情况下,您是否偶然尝试在刷新时重新启动侦听器?我不希望这会导致频繁更新。
  • 问题是它检索数据但不能限制到最后一个
【解决方案2】:

有几件事

首先,要求用户不断点击刷新来获取当前数据并不是一个好的体验。数据应自动呈现给用户,无需交互

其次,Firebase 是异步的 - Firebase 闭包之外的代码将在闭包中的数据之前执行。请参阅我的回答 Firebase is asynchronous

为了解决这两个问题,这里更新了代码

func updatedFireStoredata() {
    let listener =  Firestore.firestore().collection("collection1").order(by: "date").limit(toLast: 1).addSnapshotListener() { querySnapshot, error in
        if let err = error {
            print("Error fetching snapshots: \(err.localizedDescription)")
            return
        }

        

        snapshot.documentChanges.forEach { diff in
            if (diff.type == .added) {
                
                let data = diff.document.data()
    
                self.amount.append(data["amount"] as? String ?? "")
                
                print("New city: \(diff.document.data())")
            }
            
        }
        table2.reloadData()  //needs to be inside the closure
    }
}

我将 tableView 重新加载移动到闭包内,以便它在新数据到达时执行,然后删除代码以删除侦听器,以便您的 tableView 将使用新数据进行更新。

我还更新了错误处理程序以处理实际的错误代码。

您要做的一件事是跟踪用户选择的内容正在查看 - 例如,如果添加了其他数据,您不希望选择的项目取消选择,这将是什么当 tableView 重新加载时发生。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-24
    • 2018-09-03
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-18
    相关资源
    最近更新 更多