【问题标题】:Average rating from firebase databasefirebase 数据库的平均评分
【发布时间】:2019-01-29 19:24:51
【问题描述】:

编辑:所以我尝试编写自己的代码,以便可以将其发布在这里。我 以某种方式设法读取了一个位置的所有评级,然后 计算平均值并再次将该平均值保存在数据库中。 一切正常,但是当我刷新应用程序时,它会崩溃并显示 错误:无法将 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 真的很困惑

【问题讨论】:

  • 你的问题是什么?如何解析 json,如何从数据库中读取值,如何计算平均值???
  • 我想计算平均值,然后以某种方式显示它。但我不知道如何读取每个位置的所有评分值,以便计算平均@GhostCat
  • 你已经说过了。但具体是哪一步。您放置 JSON 示例数据。你有这些数据,并且想要解析它吗?再说一遍:我们这里只有你写的。到目前为止,还不清楚你采取了哪些具体步骤,以及你在哪里被阻止。
  • 对不起,我真的不知道 parse 是什么意思。我英语不太好。而且我不知道怎么说,但我在数据库中有所有这些数据,我只想检索评级节点中的值列表并计算平均值。但我觉得这又是我已经说过的那句话,我根本没有帮助。 @鬼猫
  • 正如我在您之前的相同和封闭问题中所建议的,请包含您尝试过的代码。我之前还提到过,您有多种获取平均值的选择;要么读取位置节点并遍历子节点以获取值,然后创建平均值使用 child_add 一次读取一个节点,然后创建平均值。您将需要展示您尝试过的内容;我建议查看 Working with Lists 上的 Firebase 指南,看看你能想出什么。

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


【解决方案1】:

您将除以每次迭代的结果数,从而得出移动平均线。假设您有 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() 获取子节点的计数,而不是在循环中计算它们。

【讨论】:

    【解决方案2】:

    在您的节点中创建新评级时使用 Firebase 函数进行侦听

    对于每一个新的评分,您都会计算评分的平均值和数量 并像这样保存到父节点中..希望对您有所帮助

    "location" : {
        "location1" : {
          "Title" : "location1",
          "UserID" : "EuvmA4ep8jV87qC9Y3suouoGENI2",
          "latitude" : 63.326310173826165,
          "longitude" : 33.58473535627127,
          "ratingAvg" : 3,
          "numOfrating" : 2,
          "rating" : {
            "EuvmA4ep8jV87qC9Y3suouoGENI2" : {
              "Rating" : 1
            },
            "bLpa0j4RDqfBcMQ5agWAi1zxJyD3" : {
              "Rating" : 5
            }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多