2017-01-04 4 views
5

私は、Firebaseのドキュメントにあるstar count on a blog post exampleに似た何かをするアプリを開発しています。私は、ポーリングシステムの設計と使用するかどうかについて質問します。Firebaseの主演/好きなシステムの適切なデザイン:私はトランザクションを使うべきですか?

例から、ポストのためのデータは、次のようになります。

postid { 
    // some data here about the post, author, id, etc, 
    starCount : <an integer count of the stars>, 
    stars : { 
     <user who starred> : true, 
     <user who starred> : true, 
     // ... and so on, basically a list of all the users who starred the post 
    } 
} 

ドキュメントはスター・カウント更新するトランザクションを使用します。両方のためのトランザクションの使用の

private void onStarClicked(DatabaseReference postRef) { 
    postRef.runTransaction(new Transaction.Handler() { 
     @Override 
     public Transaction.Result doTransaction(MutableData mutableData) { 
      Post p = mutableData.getValue(Post.class); 
      if (p == null) { 
       return Transaction.success(mutableData); 
      } 

      if (p.stars.containsKey(getUid())) { 
       // Unstar the post and remove self from stars 
       p.starCount = p.starCount - 1; 
       p.stars.remove(getUid()); 
      } else { 
       // Star the post and add self to stars 
       p.starCount = p.starCount + 1; 
       p.stars.put(getUid(), true); 
      } 

      // Set value and report transaction success 
      mutableData.setValue(p); 
      return Transaction.success(mutableData); 
     } 

     @Override 
     public void onComplete(DatabaseError databaseError, boolean b, 
           DataSnapshot dataSnapshot) { 
      // Transaction completed 
      Log.d(TAG, "postTransaction:onComplete:" + databaseError); 
     } 
    }); 
} 

starCountstarsは同じオブジェクトの一部であるとと思われます。です。どうして?なぜなら、私はトランザクションと自動性の両方を使用したいからです。自動性を保証するためのもう1つのオプションはマルチパス更新ですが、here in the commentsに記載されているように、マルチパス更新をトランジションで使用することはできません。 mutableData(この場合は投稿オブジェクト)にアクセスできます。それだけです。

SO starCountstarsが同じ場所に格納されなければならない場合には、は私がstarCountのポイントを理解していません。投稿オブジェクトを取得するたびに、投稿された全員のリストstarsが表示されます。なぜスターカウントを完全に削除しないでくださいとちょうど星のリストのサイズを取得?これに関して何か不公平なことはありますか?

この場合、何かの主演/主演は、p.stars.put(getUid(), true);p.stars.remove(getUid());のようなものになります。私がそれをした場合、私はもはや複数のユーザーが "カウンタ"オブジェクトを更新していないので、トランザクションの必要はありません。 p.stars.put(getUid(), true);ステートメントのトランザクションを使用することはできますが、2人の異なるデバイスから何かをスタート/スタートしようとする同じユーザーが、たとえあったとしても、可能な限り悲惨なことはありません教えてください。

ここで私は何が欠けていますか? ここでトランザクションを使用する理由と、スターカウントを保存して手動で追跡する利点は何ですか?this exampleに示すように、データベース内の別の場所にstarsユーザーリストを格納するとパフォーマンスが向上する可能性がありますが、トランザクションは機能しません。

洞察力がありがとうとありがとう!

答えて

0

ドキュメンテーションサンプルを取得するための単一のサンプルアプリケーションを作成するために、私たちは実際にトランザクションのために非実用的な(ただし機能的な)使用を作成している可能性があります。

複数の場所のアップデートとサーバー側のセキュリティールールを使用して、より合理的な(しかし間違いなく)安全なカウントを行う方法については、my answer to this questionをお勧めします。

一般的に、このようなケースでは、投票ロジックをカウントロジックから分割することをおすすめします。だから、ポストのためのユーザーの投票では、あなたは彼らの行動を記録したデータベースへの簡単なレコードを書くとき:

votesQueue 
    <push id> 
     <uid>: true 

をそして、あなたはこのキューをリッスンし、集約する小さなサーバースクリプト(例えばfirebase queue worker)を持っています投票数。

このアプローチは、Firebaseを使用する場合に非常に一般的であり、問​​題をもっと簡単にします。おそらく、これらの2つのノード(votesQueuevoteTotals)をどのようにして保護するのかを簡単に想像することができますが、上記で解答した解決策ではかなりのメンテナンスが必要です。

関連する問題