【问题标题】:Swift Firebase observe with .childAdded retrieving duplicate data使用 .childAdded 检索重复数据的 Swift Firebase 观察
【发布时间】:2017-07-27 21:11:50
【问题描述】:

我有一个UICollectionViewController,它充当从我的 Firebase 数据库中检索和显示数据的提要。它是窗口的根视图控制器,所以它始终存在。我的问题是,每次控制器出现时,其观察节点中的所有子节点都会添加到集合视图中。最初这很好,但是当我离开控制器并返回时,所有相同的数据都会被附加,从而创建重复项。这是一些伪代码,代表我与 Firebase 的交互:

class ViewController: UIViewController {

    var children_query: DatabaseQuery!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.children_query = Database.database().reference().child("children").queryOrdered(byChild: "timestamp").queryStarting(atValue: Date().timeIntervalSince1970)
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.observeAddedChildren()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.children_query.removeAllObservers()
    }

    func observeAddedChildren() {
        self.children_query.observe(.childAdded, with: { snapshot in
            print(snapshot.value)
        })
    }

}

在这个伪代码中,我没有处理 UI,而是简单地打印 snapshot,但重点仍然存在。每次控制器出现时,所有的孩子都会被打印出来。如何仅检索尚未检索到的数据?谢谢。

【问题讨论】:

    标签: swift firebase firebase-realtime-database


    【解决方案1】:

    我没有使用 Firebase,但是当您将块传递给 observe 函数时,没有任何迹象表明当视图消失时观察停止。

    所以我想知道是否多次调用observe 是问题所在。您是否尝试过在 ViewDidLoad 中只调用一次 observe

    或者,有一个属性来记录观察是否已经开始:

    var observing: Bool = false
    
    func observeAddedChildren() {
        if observing {
            return false
        }
    
        self.children_query.observe(.childAdded, with: { snapshot in
            print(snapshot.value)
        })
        observing = true
    }
    

    编辑:这里有更多的方法,因为您可能正在将 snapshot 项添加到数组或其他集合中,那么您的 UICollectionViewDataSource 正在从该数组中读取内容。

    所以要么:

    1. 清空viewWillAppear中的这个数组,然后调用self.collectionView.reloadData(),或者
    2. 如果您的snapshot 对象具有唯一标识符属性,则将其放入数组中,然后观察块可以忽略它之前已经看到的项目

    像这样:

    var snapshotIDs : [String] = Array<String>()
    
    func observeAddedChildren() {
        self.children_query.observe(.childAdded, with: { snapshot in
            if !snapshotIDs.contains(snapshot.uniqueID) {
                print(snapshot.value)
                snapshotIDs.append(snapshot.uniqueID)
            }
        })
    }
    

    【讨论】:

    • 好吧,我在viewWillDisappear 中打电话给self.children_query.removeAllObservers(),最终我不想在视图不可见时继续观察。但好主意;我也许可以解决这样的问题。
    • 我明白了。但是,如果您调用removeAllObservers,然后在视图再次可见时调用observe,那么您正在观察的事物不知道您已经将一些项目添加到您的集合视图中。因此,要么 (1) 从 viewWillAppear 的集合视图中删除所有项目,要么 (2) you 必须跟踪已添加的项目,可能是在一个数组中,如果它们'再次出现在你的观察者区块中。
    猜你喜欢
    • 2018-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多