Goal
Create a function that listens to changes in Firestore and publishes the result or the error
The code
func observe<T: Codable>(document: String, inCollection collection: String) -> AnyPublisher<T, Error> {
let docRef = self.db.collection(collection).document(document)
return Future<T, Error> { promise in
let docRef = self.db.collection(collection).document(document)
let listener = docRef.addSnapshotListener { (snapshot, error) in
guard let object = T(dictionary: snapshot?.data()), error == nil else {
promise(.failure(error ?? CRUDServiceError.encodingError))
return
}
promise(.success(object))
}
// Cancel the listener when the publisher is deallocated
let cancellable = AnyCancellable {
listener.remove()
}
}.eraseToAnyPublisher()
}
- Future by define produces only a single value, not suitable for subscribing. PassThroughSubject inside the function failed also.
- Error leads to publisher completion. We want to keep listening to changes even after the error is received, I found multiple approaches to achieve this, but they all require specific code on subscribing. I want to handle this problem one time inside the observe function. You can read some solutions here