Swift Firebase观察.childAdded检索重复数据

时间:2017-07-27 21:11:51

标签: swift firebase firebase-realtime-database

我有一个UICollectionViewController,它充当从我的Firebase数据库中检索和显示数据的Feed。它是窗口的根视图控制器,因此它始终存在。我的问题是每次控制器出现时,其观察节点中的所有子节点都会被添加到集合视图中。这最初很好,但是当我离开控制器并返回时,所有相同的数据都会被追加,从而产生重复数据。这是一些伪代码,代表我与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)
        })
    }

}

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

1 个答案:

答案 0 :(得分: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对象具有唯一标识符属性,则将其放入数组中,然后观察块可以忽略它之前已经看到的项目
  3. 像这样:

    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)
            }
        })
    }