Firebase中如何获取所有用户ID下的数据?现有代码返回NaN问题排查
解决Firebase获取所有用户Rating数据显示NaN的问题
看起来你在获取Firebase中所有用户的评分数据时遇到了NaN的问题,我来帮你分析下问题所在并给出解决方案。
原代码的核心问题
首先看你写的代码,有两个关键问题导致了NaN的出现:
- 错误定位节点:你用了
ratingRef.child(RandomID),这会让你只读取单个特定用户的数据,而不是遍历所有用户的节点,这和你要获取所有用户ID下数据的需求完全不符。 - 循环逻辑混乱:你尝试遍历
ds.child("rating").getChildren(),但rating本身是一个数值类型的字段,并不是子节点集合,这个循环根本不会执行有效逻辑。反而当ds指向Name或Password这类节点时,你调用ds.child("rating").getValue()会因为该字段不存在而返回NaN。
修正后的代码(获取所有用户的Rating)
下面是能正确遍历所有用户、读取有效评分数据的代码:
final DatabaseReference customerRef = FirebaseDatabase.getInstance().getReference("Customer"); customerRef.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { // 遍历Firebase中所有用户的ID节点 for (DataSnapshot userSnapshot : snapshot.getChildren()) { // 遍历当前用户下的所有子节点(包括基础信息和带评分的UUID节点) for (DataSnapshot childSnapshot : userSnapshot.getChildren()) { // 检查当前子节点是否包含rating字段,避免读取无效节点 if (childSnapshot.hasChild("rating")) { Double rating = childSnapshot.child("rating").getValue(Double.class); if (rating != null) { Toast.makeText(RibsAndPowerboats.this, "用户ID: " + userSnapshot.getKey() + " 的评分是: " + rating, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(RibsAndPowerboats.this, "该用户的评分为空", Toast.LENGTH_SHORT).show(); } } } } } @Override public void onCancelled(@NonNull DatabaseError error) { // 别忘了处理读取失败的情况 Toast.makeText(RibsAndPowerboats.this, "读取数据失败: " + error.getMessage(), Toast.LENGTH_SHORT).show(); } });
代码说明
- 监听根节点:直接监听
Customer节点,这样能一次性获取所有用户的完整数据。 - 双层遍历:第一层遍历每个用户的ID节点,第二层遍历用户下的所有子节点,通过
hasChild("rating")筛选出包含评分的节点。 - 明确类型转换:用
getValue(Double.class)直接获取数值类型,避免因类型不匹配导致的NaN问题。 - 错误处理:添加
onCancelled方法处理数据库读取失败的情况,让你的代码更健壮。
优化版代码(针对性处理UUID节点)
如果你能确定用户下带评分的节点都是UUID格式(包含连字符),可以跳过Name和Password这类固定字段,直接处理目标节点,提升效率:
final DatabaseReference customerRef = FirebaseDatabase.getInstance().getReference("Customer"); customerRef.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { for (DataSnapshot userSnapshot : snapshot.getChildren()) { for (DataSnapshot childSnapshot : userSnapshot.getChildren()) { String nodeKey = childSnapshot.getKey(); // 通过连字符判断是否为UUID格式的评分节点 if (nodeKey != null && nodeKey.contains("-")) { Double rating = childSnapshot.child("rating").getValue(Double.class); if (rating != null) { Toast.makeText(RibsAndPowerboats.this, "用户 " + userSnapshot.child("Name").getValue(String.class) + " 的评分: " + rating, Toast.LENGTH_SHORT).show(); } } } } } @Override public void onCancelled(@NonNull DatabaseError error) { Toast.makeText(RibsAndPowerboats.this, "读取数据失败: " + error.getMessage(), Toast.LENGTH_SHORT).show(); } });
这样不仅能正确获取评分,还能同时显示用户名称,让Toast的信息更清晰。
内容的提问来源于stack exchange,提问作者user15965834
相关产品推荐
相关产品推荐

