Flutter:如何过滤List<Map<String, dynamic>>及SkillsCard列表的completedBy字段
解决方案
1. 在getData中安全处理类型并完成过滤
Firestore返回的e["completedBy"]是dynamic类型,直接调用contains会报错,先做类型校验与转换,确保它是List<String>后再执行过滤逻辑:
Future<List<Map<String, dynamic>>> getData({required bool completed, required String userEmail}) async { QuerySnapshot snapshot = await FirebaseFirestore.instance.collection('your_collection').get(); return snapshot.docs.map((doc) => doc.data() as Map<String, dynamic>) .where((item) { // 安全转换字段类型,避免类型错误 final completedBy = item["completedBy"]; if (completedBy is! List<String>) return false; // 根据参数过滤数据 return completed ? completedBy.contains(userEmail) : !completedBy.contains(userEmail); }) .toList(); }
2. 修复readData的返回类型不匹配问题
readData需要返回Future<List<SkillsCard>>,先获取过滤后的Map列表,再逐个转换为SkillsCard对象:
Future<List<SkillsCard>> readData({required bool completed, required String userEmail}) async { // 获取已过滤的原始数据 final filteredMaps = await getData(completed: completed, userEmail: userEmail); // 转换为SkillsCard列表,假设SkillsCard有对应构造方法 return filteredMaps.map((map) => SkillsCard( id: map["id"], title: map["title"], completedBy: map["completedBy"] as List<String>, // 补充其他字段 )).toList(); }
额外优化建议
- 若Firestore中
completedBy可能存在非字符串元素,可增加一层校验:final completedBy = (item["completedBy"] as List).where((element) => element is String).cast<String>().toList(); - 若必须在
readData内过滤,需确保SkillsCard的completedBy是List<String>类型:
这里要求Future<List<SkillsCard>> readData({required bool completed, required String userEmail}) async { final rawMaps = await getData(); // 未过滤的原始数据方法 final cards = rawMaps.map((map) => SkillsCard.fromMap(map)).toList(); return cards.where((card) => completed ? card.completedBy.contains(userEmail) : !card.completedBy.contains(userEmail) ).toList(); }SkillsCard实现fromMap构造方法,将Map转为实体类。
内容的提问来源于stack exchange,提问作者FlutterBuilder
相关产品推荐
相关产品推荐

