如何将Firebase实时数据库回调与RxJava2

时间:2018-05-24 08:19:19

标签: android firebase firebase-realtime-database rx-java2

我当前的Android项目在Firebase实时数据库中保存了不同类型的参考数据。

Android应用程序拥有自己的此参考数据的本地副本,必须根据上次更新日期刷新。

我希望使用RxJava来并行控制刷新此引用数据。

成功刷新所有参考数据后,我希望将本地的上次更新日期重置为今天。

我目前的解决方案并没有按照预期行事。我无法重置上次更新日期以等待成功刷新参考数据。

我的代码目前类似于: -

    Observable.just(Boolean.TRUE)
            .subscribeOn(Schedulers.io())
            .observeOn(Schedulers.io())
            .doOnNext(refresh -> referenceTypeA())
            .doOnNext(refresh -> referenceTypeB())
            .doOnNext(refresh -> referenceTypeC())
            .doOnNext(refresh -> recordTodaysDate())
            .subscribe();

每个referenceTypeX()方法都具有以下相同的结构: -

private void referenceTypeX() {

        firebaseService
                .getReferenceTypeX()
                .doAfterSuccess(this::referenceTypeX)
                .doOnError(this::processError)
                .subscribe();
    }


public Single<List<ReferenceTypeX>> getReferenceTypeX() {
    return Single.create(emitter ->
            mReferenceTypeXDatabaseReference
                    .orderByChild("typeXKey")
                    .addValueEventListener(buildTypeXListener(emitter)));
}

这就是问题所在,因为Firebase回调在主线程上运行,而一些参考数据有1000行,我在后台线程上处理数据更改事件,如下所示: -

public class TypeXListener extends BaseValueEventListener<List<ReferenceTypeX>> {
    private static final TypeXMapper TYPE_X_MAPPER = Selma.builder(TypeXMapper.class).build();
    private static final List<ReferenceTypeX> TYPE_X = new ArrayList<>();

    public TypeXListener(final SingleEmitter<List<ReferenceTypeX>> emitter) {
        super(emitter);
    }

    @Override
    public void onDataChange(final DataSnapshot dataSnapshot) {
        final GenericTypeIndicator<TypeXCsv> typeXTypeIndicator = new GenericTypeIndicator<TypeXCsv>() {
        };

        final Thread thread = new Thread(() -> {
            for (final DataSnapshot typeXDataSnapshot : dataSnapshot.getChildren()) {
                final TypeXCsv typeXCsv = typeXDataSnapshot.getValue(typeXDataSnapshot);
                final TypeX typeX = TypeXMapper.mapTypeX(typeXCsv);

                TYPE_X_s.add(typeX);
            }

            emitter.onSuccess(TYPE_X_s);
        });

        thread.start();

    }
}

我相信我需要为每个referenceTypeX()方法创建一个Observable并将它们传递给我的Observable.just()

然后使用flatMap()来并行化参考数据更新。

我如何实现这一目标?

特别是当我需要firebase实时回调在后台线程而不是主线程上运行时?

我相信我的解决方案类似于

Observable.just(referenceTypeA(), referenceTypeB(), referenceTypeC())
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.io())
                .flatMap(?????????????)
                .doOnComplete(recordTodaysDate())
                .subscribe();

1 个答案:

答案 0 :(得分:1)

您需要修改referenceTypeX()函数,以便它们不在函数中订阅:

private Single<List<ReferenceTypeX>> referenceTypeX() {
    return firebaseService
            .getReferenceTypeX()
            .doAfterSuccess(this::referenceTypeX)
            .doOnError(this::processError)
            .subscribe(); // <-- remove this, just return
}

然后,您可以通过组合这些函数来构建主要的observable:

Single
    .zip(
        referenceTypeA().subscribeOn(Schedulers.io()),
        referenceTypeB().subscribeOn(Schedulers.io()),
        referenceTypeC().subscribeOn(Schedulers.io()),
        Function3<A,B,C,Result> { combineIntoResult(...) })
    .flatMap(???) // is this necessary?
    .map(recordTodaysDate())
    .subscribe();