2017-11-21 3 views
0

私はthisライブラリを使ってRxJavaでFirebaseトランザクションをラッピングしています。私はRxJavaを初めて使うので、これは主にそれを使う方法に関する質問です。Completablesの動的リストのために単一のonCompleteを作成する

シナリオPerson秒とLabel秒の間に多対多の関係があります。 Personは複数のLabelを有することができ、Labelは多くのPersonに与えることができる。 Personが作成されると、私がしなければならない:

  • は、各Labelは、特定のラベルに属するすべてのPersons

を照会可能にするために彼らに与えられPerson

  • アップデートのリストに追加します私はLabelのリストを持っています。私のFirebaseデータベースに書きたいです。

    List<Label> labels; // Let's assume it's been instantiated and added to 
    

    私は、DBにこれらのそれぞれを書きたい:

    FirebaseDatabase database = FirebaseDatabase.getInstance(); 
    DatabaseReference peopleRef = database.getReference().child("people"); 
    DatabaseReference labelsRef = database.getReference().child("labels"); 
    int newPersonId = peopleRef.push().getKey(); 
    

    私は呼び出しが成功したかどうかを気にしない場合、私は簡単にこれを行うことができます。

    // Let's assume I already saved the Person to the DB 
    for (Label label : labels){ 
        // For each label, index the Person saved (Looks like 'personId: true') 
        labelsRef.child(label).child(newPersonId).setValue(true); 
    } 
    

    しかし、私は結果についてケアを行う場合は何? Labelが更新されていることに反応したい場合(現在のActivityからナビゲートするような)、すべて正常に更新されたかどうかを知る必要があります。

    RxFirebaseは、DBに値を設定するとCompletableを返すように実装されています。私は基本的にn個のCompletablesをまとめて、成功するか失敗するかだけをしたいと思っています。

    これまでのところ、Labelを更新したいだけですが、nLabelを更新したいと思います。一緒に

    次のコードスニペットチェーン2 Completablesが、わずか1つのラベル

     RxFirebaseDatabase.setValue(peopleRef.child(newPersonId), person) // Save the Person 
    .andThen(RxFirebaseDatabase.setValue(labelsRef.child(label).child(newPersonId), true)) // I can index 1 Label, and this returns a Completable 
    

    私はこれをどのように行うだろうが保存されますか?あなたがFirebaseを十分に知っているなら、これはアイテムのリストを保存する正しい方法ですか?

  • 答えて

    1

    私があなたの主な質問を正しく理解していれば、あなたはCompletableのコレクションを持っており、それらを1つとして購読する必要があります。

    これを解決する方法は、Completable.concatまたはCompletable.mergeの演算子を使用することです。

    完了可能です。 concat:すべてのソースが順番に完了する場合にのみ完了するCompletableを返します。

    完了。merge:すべてのソースを一度にサブスクライブし、すべてのソースCompletableが完了するか、またはいずれかがエラーを出した場合にのみ完了するCompletableインスタンスを返します。

    例:2つ目の質問について

    List<Completable> tasks; // initialized elsewhere 
    
    Completable 
        .concat(tasks) 
        .subscribe(
         () -> Log.d(TAG, "All successful"), 
         throwable -> Log.w(TAG, "One or more failed")) 
    

    、私はFirebase十分に知りません。

    更新

    List<Completable> tasks = new ArrayList<>(); 
    for (...) { 
        tasks.add(RxFirebaseDatabase.setValue(peopleRef.child(newPersonId), person)); 
    } 
    Completable.concat(tasks).etc 
    
    +0

    これは間違いなく良い私は私の質問に使用される 'andThenを()'使用して、その後素晴らしいです、そして:List<Completable>あなたがこれに似た何かを行うことができます取得します。私の唯一の問題は、これが一連の単一の 'Completable'のために働くのに対し、私の質問ではforEachループを取る最良の方法だと思いますが、それぞれの反復を' Completable'に変換してくださいそれぞれの反復が返すもの)、次にそれらを 'concat()'します。 – Brandon

    +0

    私は 'Completable'を返すメソッドをいくつか持っていて、DBで更新する必要がある' Label'ごとに呼び出すことができると思います。私はそれらのリストを作って、それらを一緒に「連結」することができました。私はそのショットを(あなたがより良い方法を持っていない限り)与えて、それがすべて動作すればオールの緑色のチェックを与えます。 – Brandon

    +0

    @Brandon次の行は何を返しますか? 'labelsRef.child(ラベル).child(newPersonId).setValue(真);'。 'Completable'を返す場合は' concat'を使う前に 'List'に入れてください。 – ESala

    関連する問題