Firebase查询观察重新显示的数据

时间:2018-01-06 05:43:44

标签: ios arrays swift firebase tableview

我有一个firebase查询,用于观察帖子中的数据。

func fetchPosts () {

        let query = ref.queryOrdered(byChild: "timestamp").queryLimited(toFirst: 10)

        query.observe(.value) { (snapshot) in
            for child in snapshot.children.allObjects as! [DataSnapshot] {
                if let value = child.value as? NSDictionary {
                    let post = Post()
                    let poster = value["poster"] as? String ?? "Name not found"
                    let post_content = value["post"] as? String ?? "Content not found"
                    let post_reveals = value["Reveals"] as? String ?? "Reveals not found"
                    post.post_words = post_content
                    post.poster = poster
                    post.Reveals = post_reveals
                    self.postList.append(post)
                    DispatchQueue.main.async { self.tableView.reloadData() }
                    //make this for when child is added but so that it also shows psots already there something like query.observre event type of 
                }
            }

但是,当用户发布内容时,会创建一个包含数据的多个单元格。例如,如果我发布“hello”,就会出现两张新牌,上面写着你好。但是,当我退出视图并调用fetch posts函数时,它会显示正确的单元格数量。此外,当我从数据库中删除帖子时,它还会添加一个新单元格并创建它的两个副本,直到我重新加载视图,然后它会显示数据库中的正确数据。

我怀疑这与observe(.value)有关,因为它可能从数据库中获取帖子,每次数据库更改时都会创建一个新数组。因此,当我添加一个新帖子时,它正在添加一个数组,用于添加帖子并且它现在存在于数据库中,当我刷新视图时,它只是直接从数据库收集数据。

此外,有时会显示正确数量的单元格,有时会出现多个随机帖子实例,无论我是否刚刚添加它们。

如何更改我的查询以便它最初加载数据库中的所有帖子,并且当添加一些帖子时,它只创建一个新单元而不是两个?

编辑:似乎发生的逻辑是,当函数加载时,它会调用fetchPosts()来获取所有帖子。然后,当某些内容添加到数据库时,它会再次调用fetchPosts()并将新数据添加到数组中,同时获取所有旧数据。再次。

2 个答案:

答案 0 :(得分:0)

您认为.value事件类型每次发生更改时都会返回整个数组,这是对的。你真正需要的是query.observe(.childAdded)听众。这将获取单个帖子对象而不是整个数组。请在viewDidAppear方法中调用此方法。

您可能还希望实现query.observe(.childRemoved)侦听器以检测何时删除帖子。

另一种方法是在初始加载时调用observeSingleEvent(.value),然后添加一个监听器query.queryLimited(toLast: 1).observe(.childAdded)来监听最新的帖子。

答案 1 :(得分:0)

使用Firebase将快照附加到阵列时,我总是会做的一件事是检查它是否存在。在你的情况下,我会添加

    if !self.postList.contains(post) {
        self.postList.append...

然而,为了使这项工作,你必须为我猜测的Post类做出一个相同的协议:

    extension Post: Equatable { }

      func ==(lhs: Post, rhs: Post) -> Bool {
         return lhs.uid == rhs.uid
    }