Firebase观察者事件类型

时间:2018-11-24 16:16:05

标签: ios swift firebase-realtime-database

我正在尝试修改以前的程序员编写的代码。他编写了一个getPostFromFirebase()函数,该函数在以下情况下更新表视图:1)由于应用程序在viewDidLoad中的存在而导致应用加载,以及2)用户添加了新帖子后,该表视图就会更新。问题在于他使用了.observe(.childAdded)事件类型,这意味着当帖子被删除或修改时,tableView将不会更新(我的最终目标是这样做)。当我将.childAdded更改为.value时,启动时不会加载当前数据。我一直在脑海中摸索,想出一个if let语句来添加一个.value事件类型,以便视图可以在进行任何更改后刷新(如果可能的话)。我对Firebase RT DB十分熟悉,因此我如何识别观察者问题,但是我离我想要的状态还差得远,因此我们将不胜感激。

func getPostFromFirebase() {
    let mostRecent = dbRef.lastestPostsQuery(count: 10)
    mostRecent.keepSynced(true)
    mostRecent.observe(.childAdded) { (snapshot: DataSnapshot) in

      /*parse method in the PostFetcher class 
      that returns the post data or an error by way of a tuple.*/

      let (post, error) = PostFetcher.parsePostSnapshot(snapshot: snapshot)  
      if let post = post {
        self.latestPosts.append(post)
        if let postId = post.postId { print("PostId = \(postId)") }
      }
      if let error = error {
        print("\(#function) - \(error)")
      }
    }
  }

编辑: 多亏了Franks的帮助,我得以实现他的建议,并添加了.removeAll()来删除当前状态并使视图附加新的快照。无论是添加还是删除帖子,视图现在都可以按照我的意愿进行更新。

func getPostFromFirebase() {
    let mostRecent = dbRef.lastestPostsQuery(count: 10)
    mostRecent.keepSynced(true)
    mostRecent.observe(.value) { (snapshot: DataSnapshot) in
        self.latestPosts.removeAll()
        for child in snapshot.children.allObjects as! [DataSnapshot] {
            let (post, error) = PostFetcher.parsePostSnapshot(snapshot: child)
            if let post = post {
                self.latestPosts.append(post)
                self.tableView.reloadData()
                if let postId = post.postId { print("PostId = \(postId)") }
            }
            if let error = error {
                print("\(#function) - \(error)")
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

.child*事件在您观察到的位置/查询的子节点上触发,而.value事件在位置/查询本身上触发。这意味着您获得的值在JSON中比上一层高,并且您需要遍历结果:

mostRecent.observe(.value) { (snapshot: DataSnapshot) in
  for child in snapshot.children.allObjects as! [DataSnapshot] {
    let (post, error) = PostFetcher.parsePostSnapshot(snapshot: child)  
    if let post = post {
      self.latestPosts.append(post)
      if let postId = post.postId { print("PostId = \(postId)") }
    }
    if let error = error {
      print("\(#function) - \(error)")
    }
  }
}

或者,您可以监听.childChanged.childRemoved事件(除了已经拥有的.childAdded之外)并分别处理它们。在需要有效更新UI的情况下,这样做可能会更好,因为它允许您以最有效的方式处理每种情况(新节点,已更改,节点,已删除节点)。