Firebase将旧数据加载到表视图中

时间:2017-02-01 06:33:27

标签: ios swift firebase firebase-realtime-database

我注意到,当我在浏览器上提取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)
            }
        })

2 个答案:

答案 0 :(得分:1)

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

当发生这种情况时,会调用Firebase服务器,并在项目的公司节点上设置值观察器。该值观察器会触发服务器向您的应用发送新的快照。处理第二个快照似乎是个问题。

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

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

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

编辑:

所以,为我的原始建议添加更多的形状:

从您的原始代码开始(略微修改),并构建您的公司对象的DOM数组。原始代码的mod将是:

(1)在添加新对象之前检查公司对象是否已存在于数组中,并且

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

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

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

答案 1 :(得分:1)

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

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