1

How do I asynchronously observe a Firebase node? Right now, I'm using a DispatchGroup to fire off a closure once all the children in a node are observed.

I want to keep a listener on this node, because I expect the values to change in the future.

If I use a dispatchGroup, an update in the database causes the dispatchGroup.leave() to fire, without a corresponding .enter() causing my app to crash. Here is my code:

func fetchPosts(completion: @escaping ([Post]) -> Swift.Void) {
    let dispatchGroup = DispatchGroup()
    guard let uid = Auth.auth().currentUser?.uid else { return }
    let dbRef = Database.database().reference()
    let userPosts = dbRef.child("user-posts")
    let postRef = dbRef.child("posts")
    userPosts.child(uid).observe(.value, with: { (snap) in
        if let dictionary = snap.value as? [String:Any] {
            for item in dictionary {
                dispatchGroup.enter()
                postRef.child(item.key).observe(.value, with: { (snap) in
                    if let dictionary = snap.value as? [String:Any] {
                        let newPost = Post(dictionary: dictionary)
                        self.posts.append(newPost)
                        dispatchGroup.leave()
                    }
                })
            }
        }
        dispatchGroup.notify(queue: DispatchQueue.main) {
            completion(self.posts)
        }
    })
}
Charles Black
  • 143
  • 1
  • 2
  • 9

0 Answers0