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

合并两个Firebase Firestore的Future<QuerySnapshot>失败,求解决方案

问题原因

你代码里的query1.docs是不可修改的List,调用addAll不会改变原有的文档列表,所以返回的还是仅包含query1结果的QuerySnapshot。

解决方案

方案一:使用Firestore原生OR查询(推荐)

Firestore支持复合OR查询,直接把两个玩家名称的条件合并成一个查询,减少网络请求次数,且结果自动排序:

Future<QuerySnapshot> mergeQueries() async {
  return FirebaseFirestore.instance
      .collection('practice')
      .orderBy('timeStamp', descending: true)
      .where('teamId', isEqualTo: widget.teamId)
      .where('checkSinglesDoubles', isEqualTo: dropDownType)
      .where(Filter.or(
        Filter('player1name', isEqualTo: playerNameFilter),
        Filter('player2name', isEqualTo: playerNameFilter),
      ))
      .get();
}

注意:首次运行会触发Firestore的索引创建提示,按照控制台指引创建复合索引即可。

方案二:手动合并查询结果(兼容旧版本或特殊场景)

如果必须保留两次查询,需要手动合并文档列表,再构造新的QuerySnapshot返回:

Future<QuerySnapshot> mergeQueries() async {
  final query1 = await FirebaseFirestore.instance
      .collection('practice')
      .orderBy('timeStamp', descending: true)
      .where('teamId', isEqualTo: widget.teamId)
      .where('checkSinglesDoubles', isEqualTo: dropDownType)
      .where('player1name', isEqualTo: playerNameFilter)
      .get();

  final query2 = await FirebaseFirestore.instance
      .collection('practice')
      .orderBy('timeStamp', descending: true)
      .where('teamId', isEqualTo: widget.teamId)
      .where('checkSinglesDoubles', isEqualTo: dropDownType)
      .where('player2name', isEqualTo: playerNameFilter)
      .get();

  // 合并文档并去重(避免同一文档被两个查询同时命中)
  final mergedDocs = {...query1.docs, ...query2.docs}.toList();
  // 重新按timeStamp降序排序
  mergedDocs.sort((a, b) => (b['timeStamp'] as Timestamp).compareTo(a['timeStamp'] as Timestamp));

  // 构造新的QuerySnapshot返回
  return QuerySnapshot(
    query: query1.query,
    docs: mergedDocs,
    metadata: query1.metadata,
  );
}

如果业务允许,更建议直接返回Future<List<DocumentSnapshot>>,省去构造QuerySnapshot的麻烦:

Future<List<DocumentSnapshot>> mergeQueries() async {
  final query1 = await FirebaseFirestore.instance
      .collection('practice')
      .orderBy('timeStamp', descending: true)
      .where('teamId', isEqualTo: widget.teamId)
      .where('checkSinglesDoubles', isEqualTo: dropDownType)
      .where('player1name', isEqualTo: playerNameFilter)
      .get();

  final query2 = await FirebaseFirestore.instance
      .collection('practice')
      .orderBy('timeStamp', descending: true)
      .where('teamId', isEqualTo: widget.teamId)
      .where('checkSinglesDoubles', isEqualTo: dropDownType)
      .where('player2name', isEqualTo: playerNameFilter)
      .get();

  final mergedDocs = {...query1.docs, ...query2.docs}.toList();
  mergedDocs.sort((a, b) => (b['timeStamp'] as Timestamp).compareTo(a['timeStamp'] as Timestamp));
  
  return mergedDocs;
}

内容的提问来源于stack exchange,提问作者Joao Paulo Carvalho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 06:27:40