我有资源库类。在这些课程中,我像这样简单collection("..").get()
。
override fun getTestCollectionItems(): Observable<TestModel> {
return Observable.create { subscriber ->
firebaseFirestore.collection(TEST_COLLECTION)
.get()
.addOnCompleteListener { task ->
if (task.isSuccessful()) {
for (document in task.getResult()) {
if (document.exists()) {
val documentModel = document.toObject(TestModel::class.java)
subscriber.onNext(documentModel)
}
}
subscriber.onComplete()
} else {
subscriber.onError(task.exception!!)
}
}
}
}
但我找到了实时Firecloud选项。如果我将监听器移动到存储库,那么它的意义是否很好?
我尝试了下一个:
override fun getRealTimeCollection() : Observable<TestModel> {
return Observable.create { subscriber ->
firebaseFirestore.collection(TEST_COLLECTION).document("3lPtYZEEhPdfvZ1wfHIP")
.addSnapshotListener(EventListener<DocumentSnapshot> { snapshot, e ->
if (e != null) {
Log.w("test", "Listen failed.", e)
subscriber.onError(e)
return@EventListener
}
if (snapshot != null && snapshot.exists()) {
Log.d("test", "Current data: " + snapshot.data)
val documentModel = snapshot.toObject(TestModel::class.java)
subscriber.onNext(documentModel)
} else {
Log.d("test", "Current data: null")
}
})
}
}
使用DisposableObservable。但是当我处理它时,Firebase仍然发送了新的数据。这将是内存泄漏。如何在这种情况下使用RxJava? 将实时数据移动到存储库是否正确?
谢谢!
答案 0 :(得分:4)
当您使用Observable
方法创建Observable.create
时,您实际上会ObservableEmitter<T>
,使用此发射器,您应该使用{Cancellable
或Disposable
添加setCancellable()
1}} / setDisposable
。 (你可以阅读差异here)
当您处置Observable
时,将触发这些回调,并且您应该在其中添加正确的防火登记逻辑。
override fun getRealTimeCollection(): Observable<TestModel> {
return Observable.create { emitter ->
val listenerRegistration = firebaseFirestore.collection(TEST_COLLECTION).document("3lPtYZEEhPdfvZ1wfHIP")
.addSnapshotListener(EventListener<DocumentSnapshot> { snapshot, e ->
if (e != null) {
Log.w("test", "Listen failed.", e)
emitter.onError(e)
return@EventListener
}
if (snapshot != null && snapshot.exists()) {
Log.d("test", "Current data: " + snapshot.data)
val documentModel = snapshot.toObject(TestModel::class.java)
emitter.onNext(documentModel)
} else {
Log.d("test", "Current data: null")
}
})
emitter.setCancellable { listenerRegistration.remove() }
}
}
答案 1 :(得分:0)
我相信您不应以这种方式包装firebase函数,因为它不会遵守您订阅时使用的调度程序,firebase的回调在主线程上执行。
因此,如果您这样做:
wrappedFirestore.flatMap{ networkCall }
.subscribeOn(ioScheduler)
.subscribe()
它仍然会失败,并显示NetworkOnMainThreadException
。