【问题标题】:Firebase query observing reshowing dataFirebase 查询观察重新显示数据
【发布时间】:2018-01-06 05:43:44
【问题描述】:

我有一个 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 
                }
            }

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

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

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

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

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

【问题讨论】:

    标签: ios arrays swift firebase tableview


    【解决方案1】:

    在使用 Firebase 将快照附加到数组时,我经常做的一件事是首先检查它是否存在。在你的情况下,我会添加

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

    但是,要使这项工作正常进行,您必须为我猜测的 Post 类制定一个平等的协议,如下所示:

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

    【讨论】:

    • 第一部分似乎是一个很好的解决方案,但是,当我添加扩展时,我得到“'Post' 与协议'Equatable' 的冗余一致性”。此外,当您设置 lhs.uid == rhs.uid 时,rhs.uid 应该是帖子 ID 还是用户 ID,因为我也收到错误“'Post' 类型的值没有成员 'uid' " 因为我的帖子类只有 var postID : String?
    • ".uid" 只是一个占位符顺便说一句。你需要把你自己的财产放在那里
    • 哦,好的。我应该放置什么属性而不​​是 .uid?我不熟悉 equatables,我应该把帖子 id 放在哪里?
    • 如果你的类是一个 NSObject 它已经符合 equatable 所以你不需要它
    • 哦,好的。我尝试了没有 equatable 的代码,并且在添加帖子后它可以工作一段时间。但是,再次发布后,即使我有 if 语句,帖子又开始重复......
    【解决方案2】:

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

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

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

    【讨论】:

    • 另外,当我使用 .childAdded 时,即使我添加了新帖子,Feed 中也没有显示帖子?
    • 如果同时使用 .childAdded 和 .childRemoved 和 queryLimited(toLast:),有没有办法在 .childAdded 之前不调用 .childRemoved?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    相关资源
    最近更新 更多