Firebase数据库的平均评分

时间:2019-01-29 19:24:51

标签: java firebase firebase-realtime-database google-maps-api-3

  

编辑:所以我尝试编写自己的代码,以便可以在此处发布。一世   以某种方式设法读取一个位置的所有评级,然后   计算平均值并将该平均值再次保存在数据库中。   一切正常,但是当我刷新应用程序时,它崩溃并显示   错误:无法将类型为java.util.ArrayList的对象转换为类型   com.example.getlocation.MarkerLocation。但它会计算平均值   并将其保存在数据库中。所以我想我们正在努力   一点。

每个用户都在标题下添加位置到数据库,例如location1,location2,...,如下所示。然后从数据库中读取每个位置,并将其显示在地图上。每个用户都可以在星级评分栏上将地图上显示的位置评分为0到5星。每个用户的评分都作为该评分节点的子级保存在该用户的Uid下的数据库中。我需要做的是计算每个位置的平均评分,然后以某种方式显示出来。我自己可以管理这部分。只需计算平均值即可。

这就是我的数据库的样子:

在屏幕快照中,一切看起来都很好,但是在json中,应该说

的位置为null

https://ibb.co/Rc7DgRv-屏幕截图

json:

{
  "location" : {
    "location1" : {
      "Title" : "location1",
      "UserID" : "EuvmA4ep8jV87qC9Y3suouoGENI2",
      "latitude" : 63.326310173826165,
      "longitude" : 33.58473535627127,
      "rating" : {
        "EuvmA4ep8jV87qC9Y3suouoGENI2" : {
          "Rating" : 1
        },
        "bLpa0j4RDqfBcMQ5agWAi1zxJyD3" : {
          "Rating" : 5
        }
      }
    },
    "location2" : {
      "Title" : "location2",
      "UserID" : "bLpa0j4RDqfBcMQ5agWAi1zxJyD3",
      "latitude" : 54.820477453850884,
      "longitude" : 42.054178789258,
      "rating" : {
        "bLpa0j4RDqfBcMQ5agWAi1zxJyD3" : {
          "Rating" : 2
        }
      }
    },
    "marker rating" : [ null, {
      "average rating" : {
        "current" : 3
              }
            } ]
          }
        }

这是我的代码:

double Rating = Double.parseDouble(valueOf(addedRatingBar.getRating()));

    MarkerRating markerRating = new MarkerRating(Rating);
    mRating.child("location").child(String.valueOf(markerTitle.getText())).child("rating").child(user.getUid()).child("Rating").setValue(markerRating.Rating);


    final DatabaseReference db = FirebaseDatabase.getInstance().getReference("location");
    final DatabaseReference dbRef = db.child(String.valueOf(markerTitle.getText())).child("rating");

    dbRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull 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("marker rating").child(String.valueOf(markerTitle.getText())).child("average rating");
            newRef.child("current").setValue(average);

        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
  }
});

我希望这次会更好,有人会回答,因为Ipm真的很困惑

2 个答案:

答案 0 :(得分:0)

您将用每次迭代的结果数除,这将为您提供移动平均值。假设您有5个子节点,值1 ... 5。您当前的代码在循环的每次迭代中执行以下操作:

  • 当前:1,总计:1,平均值= 1/1 = 1
  • 当前:2,总计:3,平均值= 3/2 = 1.5
  • 当前:3,总计:6,平均值= 6/3 = 2
  • 当前:4,总计:10,平均值= 10/4 = 2.5
  • 当前:5,总计:15,平均值= 15/5 = 3

当获得所有节点的总和后,实际上您应该只在循环后获得平均值。所以:

public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

    long total = 0;

    for (DataSnapshot ds : dataSnapshot.getChildren()){
        long rating = Double.parseDouble(ds.child("Rating").getValue(Long.class));
        total = total + rating;
    }
    double average = (double)total / dataSnapshot.getChildrenCount();
}

这也解决了一些其他问题:

  • 数据库中的值是整数,因此应使用getValue(Long.class)来获取它们。
  • 不再将数字转换为字符串,因此可以求和。
  • 使用dataSnapshot.getChildrenCount()获取子节点的数量,而不是在循环中对其进行计数。

答案 1 :(得分:0)

在节点中创建新评分时,使用Firebase Function收听

,对于每个新费率,您可以计算平均值和收视率数量 并保存到这样的父节点中。.希望有帮助

system
相关问题