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

查询FirebaseFirestore时异步函数无法执行完成的问题

问题分析与解决

你的代码中第二个print语句不执行,核心原因是第二个Firestore查询抛出了未被捕获的异常,导致异步函数提前终止。

常见异常原因

  1. whereNotIn的数量限制:Firebase Firestore的whereNotIn查询最多支持传入10个元素。如果partyIdsUserSwipesOn的长度超过10,查询会直接失败并抛出异常。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 13:16:02