【问题标题】:Firebase loading old data into table viewFirebase 将旧数据加载到表视图中
【发布时间】:2017-08-28 20:38:48
【问题描述】:

我注意到,当我在浏览器上打开 firebase 时,我的公司表视图显示的是旧数据,而不是当前数据库中的数据。为什么?我该如何解决这个问题?

databaseHandle = databaseRef?.child("companies").observe(.value, with: 

{ (snapshot) in
            for item in snapshot.children.allObjects as! [FIRDataSnapshot] {
                //Load company data into company object
                let company = Company()
                company.name = item.childSnapshot(forPath: Property.name.rawValue).value as! String           
                let positions = item.childSnapshot(forPath: Property.jobtypes.rawValue).value as! String
                company.positions = positions.components(separatedBy: ", ")
                
                //Get company image
                let id = item.childSnapshot(forPath: Property.id.rawValue).value as! String
                let imageName = id + ".png"
                let imageRef = self.storageRef?.child(imageName)
                imageRef?.data(withMaxSize: 1 * 1024 * 1024) { data, error in
                    if let error = error {
                        print((error as Error).localizedDescription)
                    } else if let data = data {
                        DispatchQueue.main.async {
                            company.image = UIImage(data: data)
                            self.companyTableView.reloadData()                        }
                    }
                }
                self.informationStateController?.addCompany(company)
            }
        })

【问题讨论】:

    标签: ios swift firebase firebase-realtime-database


    【解决方案1】:

    如果您设置了 persistenceEnabled = true,则 Firebase API 返回的快照来自本地数据缓存。该数据被加载到您的公司对象中。

    在此过程中,会调用 Firebase 服务器,并在项目的公司节点上设置一个值观察器。该值观察者触发服务器向您的应用发送新快照。处理第二个快照似乎是个问题。

    按照完成处理程序的结构方式,第二个快照不会更新现有的 Company 对象。相反,完成处理程序将第二个快照解压缩到一组新的 Company 对象中,每个对象都通过调用 informationStateController.addCompany(company) 附加到 DOM。

    您应该修改您的完成处理程序,以便它能够将快照数据与您的 DOM 中的现有公司对象相关联,并且/或者能够确定快照数据是否对应于您的 DOM 中尚未存在的新公司对象。在前一种情况下,它应该更新现有的 Company 对象,在后一种情况下,它应该创建一个新的 Company 对象。

    我不确定最佳实践,但根据我的经验,在与 DOM 中的对象对应的节点上设置值观察器会很有帮助。在您的情况下,这意味着在每个公司节点而不是集体公司节点上设置观察者。以这种方式,更容易识别和处理数据更改。为了使这项工作发挥作用,您可能需要从公司节点上的值观察器开始编译完整的公司对象集,然后从该节点中删除值观察器,并用每个公司节点上的值观察器替换它。

    编辑:

    所以,为了让我最初的建议更加完善:

    从您的原始代码(稍作修改)开始,构建您的公司对象的 DOM 数组。对原始代码的修改是:

    (1) 在追加新对象之前检查数组中是否已经存在 Company 对象,以及

    (2) 将每个 Company 添加到 DOM 数组中,在每个 Company 的节点上调用 observe .event;每个节点的完成处理程序调用相应公司对象上的方法,以便它可以使用交付的快照更新自己。

    同时,在公司节点上设置您的 .childAdded 观察者。该观察者的完成处理程序将与您的原始代码(修改后的)基本相同。

    那么,一旦执行达到您可以知道或确信您已捕获所有当时存在的公司的程度,请从公司节点中删除原始的观察 .event。

    【讨论】:

    • 您好,您能否为您的答案提供代码?我不确定如何“从公司节点上的值观察者开始编译全套公司对象,然后从该节点中删除值观察者,并用每个公司节点上的值观察者替换它。”在我的.observe(.value 句柄中,我应该执行item.observe(.childAdded,然后将所有属性分配给.childAdded 句柄下的每个公司对象吗?
    • 您可以按照您的建议走 .childAdded 路线。但是,这不会解决特定公司数据的变化。公司数据是否会不时变化,还是仅限于添加新公司?
    • 大部分情况下,公司对象内部的数据会发生变化
    【解决方案2】:

    我遇到了同样的问题,即仍然显示旧数据。在您的 appDelegate 中,如果您有 Database.database().isPersistenceEnabled = true,则将与观察者一起显示旧数据的 vc 从 observeSingleEvent(of: .value, ...) 更改为 .observe( .childAdded, ...),它应该可以解决问题。使用observeSingleEvent(of: .value) Firebase 将通过Database.database().isPersistenceEnabled = true 从您的手机中提取数据,然后再访问数据库以获取最新信息。

    我点击了这个链接:Firebase erroneously shows deleted data / Swift 3 / Xcode 8.2

    【讨论】:

      猜你喜欢
      • 2019-12-01
      • 2020-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多