如何从 Firebase 数据库中获取排序后的数据?
How to get sorted data from Firebase Database?
如何从 Firebase 数据库中的所有用户中获取具有名称和 userScore 的 前三名 用户(可能在 HashMap 中)? HashMap 必须按 userScore 排序。或者得到 ArrayList<User> usersList
三个按 userScore 排序的用户。
database
{"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;
为了尽可能以最简单的方式解决问题,我建议您像这样更改数据库结构:
{"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 key
和 the score as the value
的 child。这种结构的好处是你只需要查询一次。为此,请使用以下代码:
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);
希望对您有所帮助。
你在@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
},
...
}
我解决了这个问题。但现在我想我如何才能将我的 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()));
}
如何从 Firebase 数据库中的所有用户中获取具有名称和 userScore 的 前三名 用户(可能在 HashMap 中)? HashMap 必须按 userScore 排序。或者得到 ArrayList<User> usersList
三个按 userScore 排序的用户。
database
{"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;
为了尽可能以最简单的方式解决问题,我建议您像这样更改数据库结构:
{"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 key
和 the score as the value
的 child。这种结构的好处是你只需要查询一次。为此,请使用以下代码:
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);
希望对您有所帮助。
你在@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
},
...
}
我解决了这个问题。但现在我想我如何才能将我的 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()));
}