Reputation: 107
I'm working in XCode, using compound queries and Firestore Listeners to query a Firestore collection with ~20,000 documents. I'm running out of memory and the application is crashing. At smaller volumes, these queries have performed ok (e.g. < 5,000 documents).
I call the listener from a separate class, and store a reference to the listener to call .remove() at a later time (when I no longer need to listen for updates). In an escaping closure, I return an array of the listened for objects.
This is an example of the object I am querying for (it is small/flat):
struct SomeObject: Codable, Identifiable, Hashable {
var id: String
var field_one: String
var field_two: String
var field_three: String?
var field_four: Bool = true
}
This is the query code:
func listenForSomeObjects(_ completion: @escaping ([SomeObject]?, Error?) -> Void) -> ListenerRegistration? {
let listener = db.collection("some_objects")
.addSnapshotListener {(snapshot, err) in
if let err = err {return completion(nil, err)}
guard let snapshot = snapshot else {return completion(nil, nil)}
let objects: [SomeObject]? = snapshot.documents.compactMap{document in
do {
return try document.data(as: SomeObject.self)
}
catch {
completion(nil, error)
}
return nil
}
return completion(objects, nil)
}
return listener
}
This is the calling code:
let listener = firebase.listenForSomeObjects() {objects, err in
if err != nil {return store.dispatch(AlertActions.showError(err))}
guard let objects = objects else {return}
store.dispatch(SomeObjectActions.setObjects(objects))
}
store.dispatch(SomeObjectActions.setListener(listener))
I've noticed that if I remove the listener immediately after the data is fetched, the memory usage drops from ~2GB to ~100MB, but I need the listener to stay alive for longer. I need to figure out why so much memory is being used while the listener is active, so I can keep it alive, but I'm unsure of how to debug further.
Upvotes: 0
Views: 315
Reputation: 862
Generally speaking, high memory usage is expected if a listener is created for a large number of entities. It's always recommended to use this feature for a manageable amount of data. Few things to consider is how often the listener receives updates, how long does it take for memory to grow.
Additionally you can look at limiting the number of documents read in one go by setting a limit and pagination.
Upvotes: 1