如何使用Flutter Firestore过滤获取每个集合votes最大值对应获胜用户数据
Flutter 实现Firestore各集合取votes最大值对应数据方案
前置准备
首先在pubspec.yaml中添加Firestore依赖:
dependencies: flutter: sdk: flutter cloud_firestore: ^4.15.8 # 替换为当前最新版本
完成后执行flutter pub get,并确保项目已经完成Firebase的初始化配置。
实现逻辑
- 首先要获取所有日期格式的根集合ID:Firebase客户端SDK不支持直接列举所有根集合,推荐两种方案:
- 提前维护所有日期集合的列表,存储在一个固定的文档中(例如
meta/collection_list下的dates数组字段) - 如果你明确知道日期的时间范围,可以直接在代码中生成对应格式的日期字符串作为集合ID
- 提前维护所有日期集合的列表,存储在一个固定的文档中(例如
- 遍历每个日期集合,对集合内的文档按
votes字段降序排序,取第一条即为当前集合votes最高的获胜用户 - 汇总所有集合的获胜用户数据,组装为你需要的输出格式
完整代码示例
import 'package:cloud_firestore/cloud_firestore.dart'; Future<Map<String, dynamic>> getWinUserList() async { final FirebaseFirestore db = FirebaseFirestore.instance; Map<String, dynamic> winList = {}; // 方案1:已知日期范围直接生成集合ID List<String> dateCollections = [ "2020-08-01", "2020-08-02", "2020-08-03" ]; // 方案2:从预先维护的meta文档中读取日期集合列表,替换上面的dateCollections即可 // DocumentSnapshot metaDoc = await db.collection("meta").doc("collection_list").get(); // List<String> dateCollections = List<String>.from(metaDoc.get("dates")); for (String dateId in dateCollections) { // 查询当前日期集合下votes最高的1个用户 QuerySnapshot querySnapshot = await db .collection(dateId) .orderBy("votes", descending: true) .limit(1) .get(); if (querySnapshot.docs.isNotEmpty) { DocumentSnapshot winDoc = querySnapshot.docs.first; String userId = winDoc.id; // 替换为你实际存储用户数据的字段名 dynamic userData = winDoc.get("data"); winList[userId] = userData; } } return winList; } // 调用示例 void testFetch() async { Map<String, dynamic> myWinList = await getWinUserList(); print("My_win_list: $myWinList"); }
注意事项
- 首次运行如果出现索引错误,按照错误提示中的指引创建Firestore索引即可,创建完成后等待几分钟生效
- 如果同一个日期集合下存在多个用户votes同为最大值的情况,去掉
.limit(1),遍历所有查询结果筛选出所有votes等于最大值的用户加入列表即可 - 如果数据量较大,建议将该逻辑移至云函数实现,减少客户端的请求压力和权限暴露风险
内容的提问来源于stack exchange,提问作者Nitneuq
相关产品推荐
相关产品推荐

