Firestore多集合查询返回错误数据,寻求排查思路
Firestore查询集合数据返回错误结果的问题
我正在使用Firestore数据库,通过集合名称数组获取对应集合的数据,但发现返回了其他集合的错误结果。调用db.collection(collectionName).get()查询时,打印的结果并不属于目标集合,检查循环和集合返回值后没发现问题,请问可能的问题出在哪里?
代码示例
private String[] collections = {"appetizers", "breakfast", "indian", "lunch", "noodles", "salad", "trending"}; private int n = 0; FirebaseFirestore db = FirebaseFirestore.getInstance(); for (int i = 0; i < collections.length; i++) { db.collection(collections[i]) .get() .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { if (task.isSuccessful()) { resultList = new ArrayList<>(); for (QueryDocumentSnapshot document : task.getResult()) { Map<String, Object> data = document.getData(); System.out.println(collections[DashBoardActivity.this.n] + " collection " + (String) data.get("data_name")); } DashBoardActivity.this.recipesMap.put(collections[DashBoardActivity.this.n], resultList); DashBoardActivity.this.n++; } else { System.out.println("Task not successful fire"); } } });
补充信息
数据库截图:
问题原因及解决方法
核心问题出在异步回调的执行顺序与全局变量n的同步冲突:
- Firestore的
get()是异步方法,循环会快速遍历所有集合发起请求,但回调函数仅在请求完成后执行,且执行顺序无法保证(可能后发起的请求先完成)。 - 你用全局变量
n标记当前要存入的集合索引,但n仅在回调完成后递增,这会导致:- 若某集合请求先完成,此时
n的数值还未对应到该集合的索引,结果会被错误存入其他集合的键下; - 后续回调继续递增
n,最终所有集合的结果对应关系完全混乱。
- 若某集合请求先完成,此时
修复代码
直接在循环中捕获当前的集合名称,彻底摆脱对全局变量n的依赖:
private String[] collections = {"appetizers", "breakfast", "indian", "lunch", "noodles", "salad", "trending"}; FirebaseFirestore db = FirebaseFirestore.getInstance(); for (int i = 0; i < collections.length; i++) { // 捕获当前循环的集合名称,避免异步回调时索引混乱 final String currentCollection = collections[i]; db.collection(currentCollection) .get() .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { if (task.isSuccessful()) { List<Map<String, Object>> resultList = new ArrayList<>(); for (QueryDocumentSnapshot document : task.getResult()) { Map<String, Object> data = document.getData(); System.out.println(currentCollection + " collection " + (String) data.get("data_name")); resultList.add(data); // 补充原代码遗漏的添加数据逻辑 } DashBoardActivity.this.recipesMap.put(currentCollection, resultList); } else { System.out.println("Task not successful fire"); } } });
注意:原代码中resultList初始化后未添加任何数据,修复代码已补上这一逻辑,避免存入空列表。
内容的提问来源于stack exchange,提问作者mikegrep
相关产品推荐
相关产品推荐

