I'm using Firestore together with Swift.
I have a singleton data class UserManager. I call this from my different ViewControllers to get data to populate my tableviews. I want the tableviews to automatically update when the collections are updated so I need to use a SnapshotListener. Everything works fine but I'm not sure how to detach from the listener when the Viewcontroller is closed.
In the singleton class I have methods like this below. The method gives a list of users and will be called from several different places around my app.
I also want to give back a reference to the listener so that I can detach from it when the Viewcontroller is closed. But I can't get it working. The below solution gives compiler error.
I've been trying to look at the reference, for example here https://firebase.google.com/docs/firestore/query-data/listen but I need to get it working when the data is loaded in a singleton class instead of directly in the Viewcontroller. What is the way to go here?
In UserManager:
func allUsers(completion:@escaping ([User], ListenerRegistration?)->Void) {
    let listener = db.collection("users").addSnapshotListener { querySnapshot, error in
        if let documents = querySnapshot?.documents {
            var users = [User]()
            for document in documents {
                let user = User(snapshot: document)
                users.append(user)
            }
            completion(users, listener)
        }
    }
}
In ViewController:
override func viewDidLoad() {
    super.viewDidLoad()
    UserManager.shared.allUsers(completion: { (users, listener) in
        self.users = users
        self.listener = listener
        self.tableView.reloadData()
    })
}
deinit {
    self.listener.remove()
}
                I guess the compiler error that you see is referring to the fact that you are using listener into it's own defining context.
Try this for a change:
In UserManager:
func allUsers(completion:@escaping ([User])->Void) -> ListenerRegistration? {
    return db.collection("users").addSnapshotListener { querySnapshot, error in
        if let documents = querySnapshot?.documents {
            var users = [User]()
            for document in documents {
                let user = User(snapshot: document)
                users.append(user)
            }
            completion(users)
        }
    }
}
In ViewController:
override func viewDidLoad() {
    super.viewDidLoad()
    self.listener = UserManager.shared.allUsers(completion: { (users) in
        self.users = users
        self.tableView.reloadData()
    })
}
deinit {
    self.listener.remove()
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With