You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 01:42:38