【问题标题】:How to find the greatest value among players uploaded data如何在玩家上传的数据中找到最大的价值
【发布时间】:2019-09-05 13:12:50
【问题描述】:

我正在尝试为我的应用程序制作一个高分类型的工具,所以我正在玩一些代码,无法弄清楚搜索多个节点以找到最大价值。问题似乎是 DataSnapshot 将节点作为 HashMap 读取,并且在将值转换为 int 时没有问题。 如何阅读信息(球员姓名和球员得分),让 DataSnapshot 识别最大值并将电视设置为该值?

我尝试过的代码如下。我还将添加我的 Firebase 外观的屏幕截图,以使其在视觉上更容易理解

我的 WriteToFirebase 活动

public void gFirebase(View view){

        int score = (int) (Math.random() * ((50)+1));
        Player p1 = new Player();
        p1.setName("Player 1");
        p1.setScore(score);

        DatabaseReference roofRef = FirebaseDatabase.getInstance().getReference();
        DatabaseReference gameInfoRef = roofRef.child("hiscore").child("player_name").push();

        gameInfoRef.setValue(p1);

    }

    public void lFirebase(View view){

        int score = (int) (Math.random() * ((50)+1));
        Player p2 = new Player();
        p2.setName("Player 2");
        p2.setScore(score);

        DatabaseReference roofRef = FirebaseDatabase.getInstance().getReference();
        DatabaseReference gameInfoRef = roofRef.child("hiscore").child("player_name").push();

        gameInfoRef.setValue(p2);

    }

    public void sFirebase(View view){

        int score = (int) (Math.random() * ((50)+1));
        Player p3 = new Player();
        p3.setName("Player 3");
        p3.setScore(score);

        DatabaseReference roofRef = FirebaseDatabase.getInstance().getReference();
        DatabaseReference gameInfoRef = roofRef.child("hiscore").child("player_name").push();

        gameInfoRef.setValue(p3);


    }

我的 ReadFromFirebase 活动

public void readFromFirebase(View view) {

        DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
        DatabaseReference hiscoreRef = rootRef.child("hiscore").child("player_name");
        ValueEventListener eventListener = new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                int hiscore = 0;
                for (DataSnapshot ds : dataSnapshot.getChildren()) {
                    int value = ds.getValue(Integer.class);
                    if (hiscore < value) {

                        hiscore = value;

                    }
                    Log.d("TAG", String.valueOf(hiscore));
                    ChangeMe.setText(hiscore);
                }
            }

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

            }

        };
        hiscoreRef.addListenerForSingleValueEvent(eventListener);
}

预期结果是我屏幕上的文本视图更改为我的 Firebase 系统中的最高数字(最高分)

我的数据库的 JSON 树

{
  "hiscore" : {
    "player_name" : {
      "-Lo0W8ks7WCEsrym5Qpl" : {
        "name" : "Player 3",
        "score" : 24
      },
      "-Lo0W92WqeUMdq_y7J8M" : {
        "name" : "Player 2",
        "score" : 42
      },
      "-Lo0W9KjzXE_XCU4K8MN" : {
        "name" : "Player 1",
        "score" : 43
      }
    }
  }
}

【问题讨论】:

  • 您能否编辑您的问题以包含来自数据库相关部分的 JSON 的 sn-p(作为文本,请不要截图)?您可以通过单击 Firebase Database console 的溢出菜单 (⠇) 中的“导出 JSON”链接来获取此信息。
  • 请将您的数据库结构添加为 JSON 文件或至少作为屏幕截图。也请回复@AlexMamo
  • 我现在已经这样做了。 @AlexMamo
  • 所以基本上你想从这三个对象中获得最高分,即 43,对吧?
  • 是的,正确的。阅读这些值并确定最高分,即 43。

标签: java android firebase firebase-realtime-database


【解决方案1】:

您可以为此使用 Firebase 查询。这将使服务器执行检查,而不必在您自己的代码中执行此操作:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference hiscoreRef = rootRef.child("hiscore").child("player_name");
Query hiscoreQuery = hiscoreRef.orderByChild("score").limitToLast(1);
hiscoreQuery.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        int hiscore = 0;
        for (DataSnapshot ds: dataSnapshot.getChildren()) {
            hiscore = ds.child("score").getValue(Integer.class);
        }
        Log.d("TAG", String.valueOf(hiscore));
        ChangeMe.setText(hiscore);
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        throw databaseError.toException(); // never ignore errors
    }

});

您可能会收到有关需要定义索引的警告,在这种情况下,您可以将其添加到您的 Firebase 安全规则中:

"hiscore": {
  "player_name": {
    ".indexOn": "score"
  }
}

【讨论】:

  • 您好弗兰克,感谢您的回答。此代码似乎还向我提供了错误“无法将 java.util.HashMap 类型的值转换为 int”。这是因为 Firebase 安全规则吗?该代码只是使应用程序崩溃。 @FrankvanPuffelen
  • 糟糕...好点,它读取了错误的字段。我更新了代码来解决这个问题。
  • 谢谢弗兰克。这解决了我的问题!我已将此添加为解决方案。如果我想找到得分最高的玩家的名字,这个查询会不会有很大不同?
  • 要获取名称,也在循环中执行此操作:ds.child("name").getValue(String.class)
  • 嘿弗兰克。我正在阅读文档并更好地理解您的答案,但我无法弄清楚如何循环遍历 dataSnaphshot 并从 limittolast 或 limittofirst 中提取比第一个值更多的数据。为此,您使用监听器吗?如果数据存在?
猜你喜欢
  • 2019-05-03
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-11
  • 2014-08-04
  • 1970-01-01
相关资源
最近更新 更多