我在XCode中工作,使用复合查询和Firestore监听器查询Firestore集合约20,000个文档。内存快用完了,应用程序快崩溃了。在较小的卷上,这些查询执行得很好(例如<5000个文档)。
我从一个单独的类调用侦听器,并存储对侦听器的引用,以便在以后调用.remove()(当我不再需要侦听更新时)。在转义闭包中,我返回侦听对象的数组。
这是我要查询的对象的一个例子(它是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
}
这是查询代码:
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
}
这是呼叫代码:
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))
我注意到,如果我在获取数据后立即删除侦听器,内存使用量从~2GB下降到~100MB,但我需要侦听器保持更长时间的存活。我需要弄清楚为什么这么多的内存被使用,而监听器是活跃的,所以我可以保持它活着,但我不确定如何进一步调试。
一般来说,如果为大量实体创建侦听器,预计会有很高的内存使用量。对于可管理的数据量,总是建议使用此功能。很少需要考虑的事情是侦听器接收更新的频率,内存增长需要多长时间。
此外,您可以通过设置限制和分页来限制一次读取的文档数量。