0

如何从 Firebase 数据库中的所有用户中获取名称和 userScore 的前三个用户(可能在 HashMap 中)?HashMap 必须按 userScore 排序。或者ArrayList<User> usersList通过 userScore 获得三个排序的用户。 数据库

{"top_clicker_db" : { 
    "total_clicks" : 3401,
    "user" : {
      "-KkePRVzO_lLLgp7fqX0" : {
        "name" : "fly",
        "userScore" : 2000
      },
      "-KkjWk0L2lR8RwUXF2Bd" : {
        "name" : "lg",
        "userScore" : 24
      },
      "-KkjjxNw8fj_XG9uUPEg" : {
        "name" : "fjfg",
        "userScore" : 304
      },
      "-KkjoakdLIjYlBEM1pkq" : {
        "name" : "Geny",
        "userScore" : 100
      },
      "-KklVAOkk2WJaRmH9cKk" : {
        "name" : "fly",
        "userScore" : 941
      }
    }
  }
}

我需要:

fly=2000;
fly=941;
fjfg=304;
4

3 回答 3

0

你说你不能在@alex-mamo 的回答中的评论中改变你的数据库结构,但是添加一个新节点怎么样?

如果可以的话,非规范化数据也可能是一个很好的解决方案。 https://firebase.google.com/docs/database/web/structure-data

"total_clicks" : 3401,
"user" : {
  "-KkePRVzO_lLLgp7fqX0" : {
    "name" : "fly",
    "userScore" : 2000
  },
  "-KkjWk0L2lR8RwUXF2Bd" : {
    "name" : "lg",
    "userScore" : 24
  ...
},
"scores" : {
  "-KkePRVzO_lLLgp7fqX0" : {
    "fly" : 2000
  },
  "-KkjWk0L2lR8RwUXF2Bd" : {
    "lg" : 24
  },
  ...
}
于 2017-05-24T10:57:30.097 回答
0

我解决了这个问题。但现在我想我怎么能限制我list只供 3 个用户使用。

userRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                getTopThreeUsers((Map<String, Object>) dataSnapshot.getValue());
            }

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

private void getTopThreeUsers(Map<String, Object> users) {
        HashMap<String, Long> namesAndScores = new HashMap<>();
        for (Map.Entry<String, Object> entry : users.entrySet()) {
            Map singleUser = (Map) entry.getValue();
            namesAndScores.put((String) singleUser.get("name"), (Long) singleUser.get("userScore"));
        }
        Set<Map.Entry<String, Long>> set = namesAndScores.entrySet();
        List<Map.Entry<String, Long>> list = new ArrayList<>(set);
        Collections.sort(list, new Comparator<Map.Entry<String, Long>>() {
            public int compare(Map.Entry<String, Long> o1, Map.Entry<String, Long> o2) {
                return (o2.getValue()).compareTo(o1.getValue());
            }
        });

        topName1.setText(list.get(0).getKey());
        topName2.setText(list.get(1).getKey());
        topName3.setText(list.get(2).getKey());

        topScore1.setText(String.valueOf(list.get(0).getValue()));
        topScore2.setText(String.valueOf(list.get(1).getValue()));
        topScore3.setText(String.valueOf(list.get(2).getValue()));
    }
于 2017-05-24T13:07:47.707 回答
0

为了以最简单的方式解决问题,我建议您更改数据库结构,如下所示:

{"top_clicker_db" : { 
    "total_clicks" : 3401,
    "user" : {
      "-KkePRVzO_lLLgp7fqX0" : {
        "fly" : 2000
      },
      "-KkjWk0L2lR8RwUXF2Bd" : {
        "lg" : 24
      },
      "-KkjjxNw8fj_XG9uUPEg" : {
        "fjfg" : 304
      },
      "-KkjoakdLIjYlBEM1pkq" : {
        "Geny" : 100
      },
      "-KklVAOkk2WJaRmH9cKk" : {
        "fly" : 941
      }
    }
  }
}

您需要一个带有the user name as the keyand的孩子the score as the value。这种结构的好处是您只需要查询一次。为此,请使用以下代码:

DatabaseReference yourRef = FirebaseDatabase.getInstance().getReference().child("top_clicker_db").child("user").child(userId);
Query query = yourRef.child(userName).orderByValue().limitToFirst(3);
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        Log.d("TAG", dataSnapshot.getKey() + "=" + dataSnapshot.getValue());
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
query.addListenerForSingleValueEvent(eventListener);

希望能帮助到你。

于 2017-05-24T09:25:49.813 回答