Я использую Firebase в своем приложении вместе с RxJava. Firebase может уведомлять ваше приложение, когда что-то изменилось во внутренних файлах (добавление, удаление, изменения,...). Я пытаюсь объединить функцию Firebase с RxJava.
Данные, которые я слушаю, называется Leisure
, а Observable
испускает LeisureUpdate
который содержит Leisure
и тип обновления (добавление, удаление, перемещение, изменение).
Вот мой метод, который позволяет подписаться на эти события.
private Observable<LeisureUpdate> leisureUpdatesObservable;
private ChildEventListener leisureUpdatesListener;
private int leisureUpdatesSubscriptionsCount;
@NonNull
public Observable<LeisureUpdate> subscribeToLeisuresUpdates() {
if (leisureUpdatesObservable == null) {
leisureUpdatesObservable = Observable.create(new Observable.OnSubscribe<LeisureUpdate>() {
@Override
public void call(final Subscriber<? super LeisureUpdate> subscriber) {
leisureUpdatesListener = firebase.child(FirebaseStructure.LEISURES).addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
final Leisure leisure = convertMapToLeisure((Map<String, Object>) dataSnapshot.getValue());
subscriber.onNext(new LeisureUpdate(leisure, LeisureUpdate.ADDED));
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
final Leisure leisure = convertMapToLeisure((Map<String, Object>) dataSnapshot.getValue());
subscriber.onNext(new LeisureUpdate(leisure, LeisureUpdate.CHANGED));
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
final Leisure leisure = convertMapToLeisure((Map<String, Object>) dataSnapshot.getValue());
subscriber.onNext(new LeisureUpdate(leisure, LeisureUpdate.REMOVED));
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
final Leisure leisure = convertMapToLeisure((Map<String, Object>) dataSnapshot.getValue());
subscriber.onNext(new LeisureUpdate(leisure, LeisureUpdate.MOVED));
}
@Override
public void onCancelled(FirebaseError firebaseError) {
subscriber.onError(new Error(firebaseError.getMessage()));
}
});
}
});
}
leisureUpdatesSubscriptionsCount++;
return leisureUpdatesObservable;
}
Во-первых, я хотел бы использовать метод Observable.fromCallable()
для создания Observable
, но, я думаю, это невозможно, поскольку Firebase использует обратные вызовы, правильно?
Я сохраняю один экземпляр Observable
, чтобы всегда иметь один Observable
котором может подписаться несколько Subscriber
.
Проблема возникает, когда все отписываются, и мне нужно прекратить прослушивание событий в Firebase. Я все равно не нашел, чтобы Observable
понял, есть ли какая-либо подписка. Поэтому я продолжаю подсчитывать, сколько звонков я получил, чтобы subscribeToLeisuresUpdates()
, with leisureUpdatesSubscriptionsCount
.
Затем каждый раз, когда кто-то хочет отказаться от подписки, он должен позвонить
@Override
public void unsubscribeFromLeisuresUpdates() {
if (leisureUpdatesObservable == null) {
return;
}
leisureUpdatesSubscriptionsCount--;
if (leisureUpdatesSubscriptionsCount == 0) {
firebase.child(FirebaseStructure.LEISURES).removeEventListener(leisureUpdatesListener);
leisureUpdatesObservable = null;
}
}
Это единственный способ заставить Observable
испускать элементы, когда есть подписчик, но я чувствую, что должен быть более простой способ, особенно понимая, что больше нет подписчиков, слушающих наблюдаемые.
Любой, кто столкнулся с подобной проблемой или имеет другой подход?