CollectionView在新帖子后复制数据

时间:2016-09-14 19:59:06

标签: ios swift firebase firebase-realtime-database

我似乎无法弄清楚为什么我的数据在发布新帖子后会一直重复。当应用程序启动时,所有内容都应该正常显示,数据会从firebase正确显示。

在我发布新帖并返回我的Feed后,会显示新数据,但旧数据已被复制。

这是我的代码,

    override func viewDidAppear(_ animated: Bool) {
   ref = FIRDatabase.database().reference()
   ref.child("brackets").observe(FIRDataEventType.value, with: { (snapshot)        in


if let bracketsSnapshot = snapshot.children.allObjects as? [FIRDataSnapshot] {

            for brackets in bracketsSnapshot {
     if let bracketsDict = brackets.value as? Dictionary <String, Any> {

     let key = brackets.key
     let post = BracketsPublicFeed(postKey: key, postData: bracketsDict)
     self.posts.append(post)
        }

              }

                    }




                self.collectionView.reloadData()

           })                             

                   }

以下是发布时使用的代码,

func PostData(itemToCell1: String, itemToCell2: String, itemToCell3: String, itemToCell4: String, userName: String?/*, userID: String?*/) {

    let ref : FIRDatabaseReference!
    ref = FIRDatabase.database().reference()
    let votes = 0
    let userName = ""

    let key = ref.child("brackets").childByAutoId().key
        let post = [
            "userID":     userID      as AnyObject,
            "item1":      itemToCell1 as AnyObject,
            "item2":      itemToCell2 as AnyObject,
            "item3":      itemToCell3 as AnyObject,
            "item4":      itemToCell4 as AnyObject,
            "userName":   userName    as AnyObject,
            "votes":      votes       as AnyObject ]


    let childUpdates = ["/brackets/\(key)": post,
    "/user-posts/\(userID)/\(key)/": post]
    ref.updateChildValues(childUpdates)



    }

我尝试过各种各样的事情,例如,

    ref.removeAllObservers()
    self.posts.removeAll()
viewDidDisappear

中的

如果我不画全貌,我会很乐意发布更多代码。

UPDATE,

感谢您的回复。到目前为止,除了使用ref.child("brackets").removeAllObservers()

的建议外,它们都没有工作

事情是,它在我编写此代码时完全正常工作,

 self.posts.removeAll()
 ref.child("brackets").removeAllObservers()

所以每次视图出现时我都会删除所有内容并重新加载。

3 个答案:

答案 0 :(得分:2)

来自Firebase文档:

  

- (void)removeAllObservers

     

删除当前引用的所有观察者,但不会删除子引用处的任何观察者。

     必须为每个建立侦听器以删除观察者的子引用再次调用removeAllObservers。

因此,ref.removeAllObservers()中的viewDidDisappear无法删除ref.child("brackets")的观察者。

viewDidDisappear

中试试
ref.child("brackets").removeAllObservers()

答案 1 :(得分:0)

你试过observerSingleEvent吗?看起来你每次出现视图时都会不断添加新的观察者。实际上,有一种简洁的方法可以使用FirebaseCollectionViewDataSource而无需手动填充数据,如下所示:

    dataSource = FirebaseCollectionViewDataSource.init(query: ref.child("brackets"),
            modelClass: Post.self,
            nibNamed: "PostViewCell",
            cellReuseIdentifier: "lesson",
            view: self.collectionView)

答案 2 :(得分:0)

您正在侦听.Value事件,每次数据发生更改时(例如添加项目时)都会触发整个列表。所以它第一次触发,例如项目1,2和3.然后下一次触发第1,2,3和4项。

您可以通过两种方式解决这个问题:

  • 每次都清除集合视图
  • 回复.ChildXxx个事件

第一个是最简单的,但会导致UI闪烁。因此,我将展示第二个选项:回复.ChildAdded

首次附加观察者时,会为每个现有子项触发.ChildAdded事件。那么第1项,第2项和第3项。当您添加新项目时,它将仅使用项目4 触发。这使您可以简单地将新项目添加到集合视图中:

ref.child("brackets").observe(FIRDataEventType.ChildAdded, with: { (snapshot) in
    if let bracketsDict = snapshot.value as? Dictionary <String, Any> {

    let key = brackets.key
    let post = BracketsPublicFeed(postKey: key, postData: bracketsDict)
    self.posts.append(post)
    self.collectionView.reloadData()
 })

注意:我没有编译此代码,因此您可能需要解决一些问题。如果您这样做,请留下评论,我会更新。