Search code examples
androidfirebase-realtime-databaseaveragerating

Get Average of Rating Firebase Android


I'm following this post on how I can get the average of the ratings but I'm getting an error message:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.fixitph.client, PID: 25744
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.util.HashMap to double
at com.google.android.gms.internal.zzelw.zzbz(Unknown Source)
at com.google.android.gms.internal.zzelw.zzb(Unknown Source)
at com.google.android.gms.internal.zzelw.zza(Unknown Source)
at com.google.firebase.database.DataSnapshot.getValue(Unknown Source)
at com.fixitph.client.ReceiptActivity$2.onDataChange(ReceiptActivity.java:85)

Here's my code:

ratingBar.setOnRatingChangeListener(new MaterialRatingBar.OnRatingChangeListener() {
    @Override
    public void onRatingChanged(MaterialRatingBar ratingBar, float rating) {
        final DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference(Common.worker_rating_table)
                .child(Common.workerId).child(uid).child("Rating");

        double dbRating = rating;
        dbRef.setValue(dbRating);
    }
});

public void submitRating(View view) {
    final DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference(Common.worker_rating_table)
            .child(Common.workerId);

    dbRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            double total = 0.0;
            double count = 0.0;
            double average = 0.0;
            for(DataSnapshot ds: dataSnapshot.getChildren()) {
                double rating = dataSnapshot.getValue(Double.class);
                total = total + rating;
                count = count + 1;
                average = total / count;
            }

            final DatabaseReference newRef = dbRef.child(uid);
            newRef.child("averageRating").setValue(average);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException();
        }
    });
}

My database looks like the following.

Here's the line which refers to ReceiptActivity.java:85

double rating = dataSnapshot.getValue(Double.class);

I'm wondering if it's because I tried finding a Double but there's an Int from the ratings, if this is the case, how can I tweak this around to get the average of the ratings? Please help. Thank you! :)


Solution

  •     ratingBar.setOnRatingChangeListener(new MaterialRatingBar.OnRatingChangeListener() {
                @Override
                public void onRatingChanged(MaterialRatingBar ratingBar, float rating) {
                    final DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference(Common.worker_rating_table)
                            .child(Common.workerId).child(Common.user_clients_table).child(uid).child("rating");
    
                    double intRating = rating;
    
                    dbRef.setValue(intRating);
                }
            });
    
            settingInformation();
        }
    
    public void submitRating(View view) {
        try {
            final DatabaseReference db = FirebaseDatabase.getInstance().getReference();
            final DatabaseReference dbRef = db.child(Common.worker_rating_table).child(Common.workerId).child(Common.user_clients_table);
    
            dbRef.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    double total = 0.0;
                    double count = 0.0;
                    double average = 0.0;
    
                    for(DataSnapshot ds: dataSnapshot.getChildren()) {
                        double rating = Double.parseDouble(ds.child("rating").getValue().toString());
                        total = total + rating;
                        count = count + 1;
                        average = total / count;
                    }
    
                    final DatabaseReference newRef = db.child(Common.worker_rating_table).child(Common.workerId).child("AverageRating");
                    newRef.child("current").setValue(average);
                }
    
                @Override
                public void onCancelled(DatabaseError databaseError) {
                    throw databaseError.toException();
                }
            });
        } catch (Exception e) {
            Toast.makeText(ReceiptActivity.this, "" + e, Toast.LENGTH_SHORT).show();
        }
    }
    

    I had to add nodes to separate the current average and the ratings of the clients so that it could work. This is how the database looks like: