查询FirebaseFirestore时异步函数无法执行完成的问题
问题分析与解决
你的代码中第二个print语句不执行,核心原因是第二个Firestore查询抛出了未被捕获的异常,导致异步函数提前终止。
常见异常原因
whereNotIn的数量限制:Firebase Firestore的whereNotIn查询最多支持传入10个元素。如果partyIdsUserSwipesOn的长度超过10,查询会直接失败并抛出异常。currentUser强制解包风险:FirebaseAuth.instance.currentUser!使用了!强制解包,如果用户未登录,这里会先抛出空指针异常,直接终止函数。
修复步骤
第一步:捕获异常定位问题
先给整个函数加上try-catch块,打印具体错误信息,确认异常原因:
Future<void> populate() async { try { final userId = FirebaseAuth.instance.currentUser?.uid; if (userId == null) { print('User not logged in'); return; } final db = FirebaseFirestore.instance; // 获取用户已滑动的party ID列表 var snapshot1 = await db .collection("partiers_swipes") .where('userId', isEqualTo: userId) .get(); var partyIdsUserSwipesOn = <String>[]; if (snapshot1.size > 0) { partyIdsUserSwipesOn = snapshot1.docs .map((doc) => doc.data()['partyId'] as String) .toList(); } var snapshot2 = await db .collection("parties") .where(FieldPath.documentId, whereNotIn: partyIdsUserSwipesOn) .get(); print('This should execute now if no error'); } catch (e) { print('Error details: $e'); } }
第二步:处理whereNotIn的数量限制
如果确认是列表长度超过10导致的异常,需要拆分查询并合并结果:
// 辅助函数:将列表拆分为多个不超过10个元素的子列表 List<List<String>> splitIntoChunks(List<String> list, int chunkSize) { final chunks = <List<String>>[]; for (var i = 0; i < list.length; i += chunkSize) { final end = i + chunkSize > list.length ? list.length : i + chunkSize; chunks.add(list.sublist(i, end)); } return chunks; } Future<void> populate() async { try { final userId = FirebaseAuth.instance.currentUser?.uid; if (userId == null) { print('User not logged in'); return; } final db = FirebaseFirestore.instance; var snapshot1 = await db .collection("partiers_swipes") .where('userId', isEqualTo: userId) .get(); var partyIdsUserSwipesOn = <String>[]; if (snapshot1.size > 0) { partyIdsUserSwipesOn = snapshot1.docs .map((doc) => doc.data()['partyId'] as String) .toList(); } List<DocumentSnapshot> allUnswipedParties = []; if (partyIdsUserSwipesOn.isEmpty) { // 没有已滑动记录,直接查询所有party final snap = await db.collection("parties").get(); allUnswipedParties.addAll(snap.docs); } else { // 拆分列表为多个10元素以内的子列表,分别查询 final chunks = splitIntoChunks(partyIdsUserSwipesOn, 10); for (final chunk in chunks) { final snap = await db .collection("parties") .where(FieldPath.documentId, whereNotIn: chunk) .get(); allUnswipedParties.addAll(snap.docs); } // 去重:多次查询可能返回相同的未滑动party allUnswipedParties = allUnswipedParties.toSet().toList(); } print('Fetched ${allUnswipedParties.length} unswiped parties'); print('This executes now'); } catch (e) { print('Error details: $e'); } }
内容的提问来源于stack exchange,提问作者Joel Castro
相关产品推荐
相关产品推荐

