2017-04-14 7 views
0

Firebaseを使用してレストランやバーの評価システムを作成しようとしています。これまで私は個人の評価を読み書きすることができました。私が抱えている問題は、特定のレストランの平均格付けを計算するために、格付けの保管額と保管されているすべての格付けの合計額を取得する必要があるということです。現時点では、私は評価の量を格納するために苦労しています。ここに私のコードがあるonDataChangeが無限ループに突き当たりました

Query RetrieveRating = databaseReference.child("ratings").child("porterhouse"); 
RetrieveRating.addValueEventListener(new ValueEventListener() { 
    @Override 
    public void onDataChange(DataSnapshot postSnapshot) { 

    //get data from snapshot 
    String data = postSnapshot.child("numRating").getValue().toString(); 

    if (!data.equals(null)) { 
     String numRating = (String) postSnapshot.child("numRating").getValue(); 

     count = Integer.valueOf(numRating); 
     count++; 

     ratingCounter = Integer.toString(count); 

     databaseReference.child("ratings").child("porterhouse").child("numRating").setValue(ratingCounter); 
    } 
    } 

    @Override 
    public void onCancelled(DatabaseError databaseError) { 

    } 
}); 

何それはしかし、毎回のように、それはOnDataChangeの()メソッドが呼び出された格納され、それに1を加算し、現在格納されている値を取得し、データベースに戻って、それを書いているされて起こっています、プラス1をもう一度追加し、再び無限ループを作ります。 私の質問は、これを防止するため、あるいはこれを構成するための別の方法で行ってもよい変更はありますか?次のように おかげ

UPDATE

JSONコードは次のとおりです。

{ 
     "ratings" : { 
     "porterhouse" : { 
      "numRating" : "0", 
      "totalRating" : "0" 
     } 
    } 
+0

本当にループがベースになるだろうJSONコード –

+0

@MartinDeSimone ChildEventListenerがその特定のパスのすべての変更をリッスンし、リスナー内のそのパスを変更すると、何度も何度もトリガーされるため、コードに追加します – EoghanBradshaw

+0

ののrelavent一部を示すように更新あなたのJSON構造を投稿 –

答えて

2

使用addListenerForSingleValueEvent

RetrieveRating.addListenerForSingleValueEvent(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot postSnapshot) { 

      //get data from snapshot 
      String data = postSnapshot.child("numRating").getValue().toString(); 

      if (!data.equals(null)) { 
       String numRating = (String) postSnapshot.child("numRating").getValue(); 

       count = Integer.valueOf(numRating); 
       count++; 

       ratingCounter = Integer.toString(count); 



       databaseReference.child("ratings").child("porterhouse").child("numRating").setValue(ratingCounter); 

      } 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }); 

また、あなたがマーティンの答えを解決するがカウンター

+0

Martinさん、ありがとうございました。あなたの助けに本当に感謝します – EoghanBradshaw

2

をインクリメントするfirebaseトランザクションを使用する必要がありますインフィニteループ、それはあなたのアプローチに問題を残します。ほぼ同時に2人のユーザーがレストランを評価した場合、その変化はお互いに干渉する可能性があります。マーティンが言うように、この問題を解決するための

、あなたがすべきuse a transaction

DatabaseReference ratingRef = databaseReference.child("ratings/porterhouse/numRating"); 
postRef.runTransaction(new Transaction.Handler() { 
    @Override 
    public Transaction.Result doTransaction(MutableData mutableData) { 
     int count; 
     try { 
      count = Integer.parseInt(mutableData.getValue(String.class)); 
     } catch (NumberFormatException e) { 
      count = 0; 
     } 
     count++; 
     mutableData.setValue(Integer.toString(count)); 
     return Transaction.success(mutableData); 
    } 

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

私はなぜあなたは文字列としてカウンタを保存している、本当にわかりません。私は非常にこのコードはずっと簡単になる場合には、数としてそれを格納お勧めします:

DatabaseReference ratingRef = databaseReference.child("ratings/porterhouse/numRating"); 
postRef.runTransaction(new Transaction.Handler() { 
    @Override 
    public Transaction.Result doTransaction(MutableData mutableData) { 
     Integer count = Integer.parseInt(mutableData.getValue(Integer.class)); 
     if (count == null) count = 0; 
     count++; 
     mutableData.setValue(count); 
     return Transaction.success(mutableData); 
    } 

    @Override 
    public void onComplete(DatabaseError databaseError, boolean b, 
          DataSnapshot dataSnapshot) { 
     Log.d(TAG, "countTransaction:onComplete:" + databaseError); 
    } 
}); 
関連する問題