RxJava与Firestore实时数据

时间:2018-03-12 16:07:03

标签: android rx-java2

我有资源库类。在这些课程中,我像这样简单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? 将实时数据移动到存储库是否正确?

谢谢!

2 个答案:

答案 0 :(得分:4)

当您使用Observable方法创建Observable.create时,您实际上会ObservableEmitter<T>,使用此发射器,您应该使用{CancellableDisposable添加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