Android中如何从Firebase实时数据库获取键值并用于Firestore查询
问题解决:异步操作顺序错误导致
recentUserId为空 你的问题核心是Firebase异步操作的执行顺序问题:实时数据库的get()方法是异步执行的,你的Firestore查询代码会先于实时数据库的onSuccess回调执行,此时recentUserId还没被赋值,自然是空值。另外,你的代码里在循环中每次覆盖recentUserId,最后只能拿到最后一个userId,也不符合需求。
解决方案步骤
- 将Firestore查询逻辑移到实时数据库的
onSuccess回调内部,确保只有拿到userId后才执行查询。 - 收集所有需要的userId:用
List<String>存储Recent_Chats下的所有用户ID,而不是只保留最后一个。 - 优化Firestore查询:使用
whereIn批量查询多个userId,减少网络请求次数。
修改后的代码示例
方案1:批量查询所有用户ID对应的Firestore数据
// 定义集合存储所有最近聊天的用户ID List<String> recentUserIds = new ArrayList<>(); // 从实时数据库获取所有用户ID firebaseDatabase.getReference().child("Recent_Chats").child(auth.getUid()).get().addOnSuccessListener(new OnSuccessListener<DataSnapshot>() { @Override public void onSuccess(DataSnapshot dataSnapshot) { // 遍历所有子节点,收集用户ID for (DataSnapshot snapshot1 : dataSnapshot.getChildren()) { String userId = snapshot1.getKey(); recentUserIds.add(userId); Toast.makeText(getContext(), "获取到用户ID:" + userId, Toast.LENGTH_SHORT).show(); } // 确保有用户ID再执行Firestore查询 if (!recentUserIds.isEmpty()) { // 批量查询多个用户ID对应的文档 Query query = firebaseFirestore.collection("Users").whereIn("uid", recentUserIds); query.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() { @Override public void onSuccess(QuerySnapshot queryDocumentSnapshots) { userArrayList.clear(); // 先清空旧数据 for (DocumentSnapshot d : queryDocumentSnapshots.getDocuments()) { User obj = d.toObject(User.class); if (obj != null) { // 避免空指针 userArrayList.add(obj); } } adapter.notifyDataSetChanged(); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // 处理查询失败的情况 Toast.makeText(getContext(), "查询用户数据失败:" + e.getMessage(), Toast.LENGTH_SHORT).show(); } }); } } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // 处理实时数据库查询失败的情况 Toast.makeText(getContext(), "获取最近聊天列表失败:" + e.getMessage(), Toast.LENGTH_SHORT).show(); } });
方案2:逐个查询每个用户ID(适合需要单独处理每个用户的场景)
如果需要对每个用户ID单独做处理,可以在遍历实时数据库子节点时直接发起Firestore查询:
firebaseDatabase.getReference().child("Recent_Chats").child(auth.getUid()).get().addOnSuccessListener(new OnSuccessListener<DataSnapshot>() { @Override public void onSuccess(DataSnapshot dataSnapshot) { userArrayList.clear(); // 清空旧数据 for (DataSnapshot snapshot1 : dataSnapshot.getChildren()) { String recentUserId = snapshot1.getKey(); // 对每个用户ID单独发起Firestore查询 firebaseFirestore.collection("Users").whereEqualTo("uid", recentUserId).get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() { @Override public void onSuccess(QuerySnapshot queryDocumentSnapshots) { for (DocumentSnapshot d : queryDocumentSnapshots.getDocuments()) { User obj = d.toObject(User.class); if (obj != null) { userArrayList.add(obj); } } adapter.notifyDataSetChanged(); // 每次添加数据后更新适配器 } }); } } });
关键注意点
- 异步操作的顺序:Firebase的数据库/存储操作都是异步的,所有依赖异步结果的逻辑必须放在对应的回调方法内部。
- 批量查询限制:Firestore的
whereIn方法最多支持查询10个值,如果你的Recent_Chats下的用户ID超过10个,需要拆分多次查询。 - 空值处理:转换
User对象时要做非空判断,避免空指针异常;同时要处理查询失败的情况,提升用户体验。
内容的提问来源于stack exchange,提问作者Puru Chaudhary
相关产品推荐
相关产品推荐

