如何用Java从Firestore获取多值字段数据并整合为单表
Firestore多用户数组数据整合到单表解决方案
问题场景
使用Java操作Firebase Firestore时,需要获取多个用户的测试数据:每个用户文档包含dwell time、flight time 2、flight time 3三个数组类型字段(每个数组存储该用户的多项测试值),以及用户名称nom。需要将所有用户的测试数据整合为扁平化的单表结构(每条测试记录对应一个用户名称)。
用户最初的代码仅支持获取单个值类型字段,修改后的代码存在两个问题:仅能获取第一个用户的文档数据,且用户名称与测试数据无法一一对应。
问题分析
- 变量名错误:循环遍历文档时,循环变量为
document,但代码中错误使用doc.getString("nom"),导致编译/运行异常,代码执行到第一个文档就终止,无法处理后续用户。 - 数据结构匹配错误:仅将用户名称添加一次,却将整个测试数组全部加入数据列表,导致名称列表长度远小于数据列表长度,无法对应每条测试数据所属用户。
解决方案
1. 定义测试数据实体类
创建实体类存储单条测试记录的完整信息:
public class TestData { private String userName; private long dwellTime; private long flightTime2; private long flightTime3; public TestData(String userName, long dwellTime, long flightTime2, long flightTime3) { this.userName = userName; this.dwellTime = dwellTime; this.flightTime2 = flightTime2; this.flightTime3 = flightTime3; } // 按需添加getter/setter方法 public String getUserName() { return userName; } public long getDwellTime() { return dwellTime; } public long getFlightTime2() { return flightTime2; } public long getFlightTime3() { return flightTime3; } }
2. 正确获取并整合数据
遍历每个用户文档,对数组的每个索引位置,将对应测试值与用户名称绑定,形成单条记录:
// 存储所有扁平化的测试数据 List<TestData> allTestData = new ArrayList<>(); for (QueryDocumentSnapshot document : task.getResult()) { // 修正变量名,获取当前用户名称 String userName = document.getString("nom"); // 获取三个测试数据数组(使用List避免类型转换异常) List<Long> dwellTimes = (List<Long>) document.get("dwell time"); List<Long> flightTimes2 = (List<Long>) document.get("flight time 2"); List<Long> flightTimes3 = (List<Long>) document.get("flight time 3"); // 校验数组合法性:非空且长度一致 if (dwellTimes != null && flightTimes2 != null && flightTimes3 != null && dwellTimes.size() == flightTimes2.size() && flightTimes2.size() == flightTimes3.size()) { // 遍历数组,将每组测试值与用户名称绑定 for (int i = 0; i < dwellTimes.size(); i++) { long dwell = dwellTimes.get(i); long ft2 = flightTimes2.get(i); long ft3 = flightTimes3.get(i); allTestData.add(new TestData(userName, dwell, ft2, ft3)); } } else { Log.w("getdata1", "用户[" + userName + "]的测试数据数组为空或长度不一致"); } }
注意事项
- 确保Firestore中每个用户的三个测试数组长度一致,否则会出现数据对应错误,代码中已添加长度校验。
- 类型转换时使用
List<Long>而非ArrayList<Long>,因为Firestore返回的数组可能是其他List实现类,避免类型转换异常。
内容的提问来源于stack exchange,提问作者michamicha
相关产品推荐
相关产品推荐

