如何在Android Studio中从Firebase Firestore获取所有用户数据及关联工单信息?
能否通过UID获取用户全部信息及其关联的工单信息?
问题背景
我的Firebase Firestore包含三个集合:admin集合、users集合和ticket_information集合。其中:
admin集合用于存储管理员注册后的信息users集合用于存储用户注册后的信息,每个用户的信息存储在以其UID命名的文档中ticket_information集合用于存储用户申请的工单信息,每个工单信息同样存储在对应用户UID命名的文档中
我当前使用以下代码从Firestore获取单个用户数据:
//get data from firestore DocumentReference documentReference = fStore.collection("users").document(userID); documentReference.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() { @Override public void onSuccess(DocumentSnapshot documentSnapshot) { if(documentSnapshot.exists()) { profile_username.setText(documentSnapshot.getString("fName")); profile_email.setText(documentSnapshot.getString("email")); } else{ Toast.makeText(UserProfile.this, "Record not found.", Toast.LENGTH_SHORT).show(); } } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { Toast.makeText(UserProfile.this, "Failed to fetch data.", Toast.LENGTH_SHORT).show(); } });
我想确认是否可以通过UID获取所有用户的全部信息以及其关联的工单信息?
解答
当然可以!通过用户UID来获取其全部信息以及关联的工单信息是完全可行的,下面结合你的Firestore结构给出几种实用的实现方案:
1. 分两次顺序查询(逻辑直观易维护)
这种方式和你当前获取用户数据的逻辑一致,先拿到用户基础信息,再去ticket_information集合查询对应用户的工单数据:
// 第一步:获取用户基础信息 DocumentReference userRef = fStore.collection("users").document(userID); userRef.get().addOnSuccessListener(userDocSnapshot -> { if (userDocSnapshot.exists()) { // 填充用户信息到UI组件 profile_username.setText(userDocSnapshot.getString("fName")); profile_email.setText(userDocSnapshot.getString("email")); // 第二步:获取该用户的关联工单信息 DocumentReference ticketRef = fStore.collection("ticket_information").document(userID); ticketRef.get().addOnSuccessListener(ticketDocSnapshot -> { if (ticketDocSnapshot.exists()) { // 根据你的工单结构解析数据,比如假设工单存在`tickets`数组中 List<Map<String, Object>> userTickets = (List<Map<String, Object>>) ticketDocSnapshot.get("tickets"); // 这里可以添加工单信息的展示逻辑,比如遍历数组渲染列表 } else { Toast.makeText(UserProfile.this, "该用户暂无工单记录", Toast.LENGTH_SHORT).show(); } }).addOnFailureListener(e -> { Toast.makeText(UserProfile.this, "获取工单信息失败", Toast.LENGTH_SHORT).show(); }); } else { Toast.makeText(UserProfile.this, "用户记录不存在", Toast.LENGTH_SHORT).show(); } }).addOnFailureListener(e -> { Toast.makeText(UserProfile.this, "获取用户信息失败", Toast.LENGTH_SHORT).show(); });
2. 使用批量读取优化请求效率
如果希望减少网络请求次数,可以使用Firestore的批量读取功能,一次性获取用户信息和工单信息两个文档:
import java.util.Arrays; import java.util.List; // 准备需要读取的两个文档引用 List<DocumentReference> targetDocs = Arrays.asList( fStore.collection("users").document(userID), fStore.collection("ticket_information").document(userID) ); // 执行批量读取 fStore.getAll(targetDocs).addOnSuccessListener(docSnapshots -> { // 第一个快照对应用户信息 DocumentSnapshot userDoc = docSnapshots.get(0); if (userDoc.exists()) { profile_username.setText(userDoc.getString("fName")); profile_email.setText(userDoc.getString("email")); } else { Toast.makeText(UserProfile.this, "用户记录不存在", Toast.LENGTH_SHORT).show(); } // 第二个快照对应工单信息 DocumentSnapshot ticketDoc = docSnapshots.get(1); if (ticketDoc.exists()) { // 解析工单数据 List<Map<String, Object>> userTickets = (List<Map<String, Object>>) ticketDoc.get("tickets"); // 处理工单展示逻辑 } else { Toast.makeText(UserProfile.this, "该用户暂无工单记录", Toast.LENGTH_SHORT).show(); } }).addOnFailureListener(e -> { Toast.makeText(UserProfile.this, "数据获取失败", Toast.LENGTH_SHORT).show(); });
额外说明(针对工单结构变种)
如果你的ticket_information集合是每个工单作为独立文档(而非存在单个UID命名的文档中),比如每个工单文档都包含userId字段关联用户,那你需要用条件查询来获取该用户的所有工单:
fStore.collection("ticket_information") .whereEqualTo("userId", userID) .get() .addOnSuccessListener(querySnapshot -> { for (DocumentSnapshot ticketDoc : querySnapshot) { // 遍历每个工单文档,提取所需字段 String ticketTitle = ticketDoc.getString("title"); String ticketStatus = ticketDoc.getString("status"); // ...处理工单数据 } }).addOnFailureListener(e -> { Toast.makeText(UserProfile.this, "获取工单列表失败", Toast.LENGTH_SHORT).show(); });
安全提示
记得配置Firestore安全规则,确保用户只能读取自己UID对应的文档,避免敏感数据泄露,比如:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { allow read, write: if request.auth != null && request.auth.uid == userId; } match /ticket_information/{userId} { allow read, write: if request.auth != null && request.auth.uid == userId; } } }
内容的提问来源于stack exchange,提问作者Zi Zian Yeo
相关产品推荐
相关产品推荐

