Flutter 从Cloud Firestore读取嵌套Map转自定义Map<String,Quantity>方案
解决方法
你遇到的类型错误本质是Firestore返回的字段值是Map<String, dynamic>类型,无法直接赋值给声明为Map<String, Quantity>的参数,需要手动把Map的value从动态类型转换为你自定义的Quantity类实例。
步骤1:可选优化(推荐)
先给Quantity类增加fromMap工厂构造方法,方便后续复用转换逻辑:
class Quantity { final double amount; final String unit; const Quantity({ required this.amount, required this.unit, }); // 新增工厂方法 factory Quantity.fromMap(Map<String, dynamic> map) { return Quantity( // 兼容Firestore返回int/double两种数值类型,避免类型转换报错 amount: (map['amount'] as num).toDouble(), unit: map['unit'] as String, ); } String toString() => '$amount $unit'; }
步骤2:修改ingredients字段读取逻辑
把你原来Medium构造函数中ingredients参数的占位代码替换为如下转换逻辑即可:
Medium md = Medium( initials: docs[i].get('initials'), longName: docs[i].get('longName'), // 替换原来的ingredients占位代码 ingredients: (docs[i].get('ingredients') as Map<String, dynamic>).map( (ingredientName, rawQuantity) => MapEntry( ingredientName, Quantity.fromMap(rawQuantity), ), ), steps: docs[i].get('steps').cast<String>(), // 其余参数保持不变 mediumState: PhysicalState.values.elementAt( docs[i].get('mediumState'), ), reference: docs[i].data().containsKey('reference') ? docs[i].get('reference') : '', isComplement: docs[i].data().containsKey('isComplement') ? docs[i].get('isComplement') : false, ps: docs[i].data().containsKey('ps') ? docs[i].get('ps') : '', );
说明
- 该转换逻辑不限制
ingredients的键值对数量,不管有多少种配料都能正常解析 - 数值转换时使用
(map['amount'] as num).toDouble()兼容Firestore中存储的整数、浮点数两种格式,避免出现int cannot be cast to double的类型错误 - 如果你不想给Quantity加工厂方法,也可以直接把转换逻辑写在map函数里,效果完全一致。
内容的提问来源于stack exchange,提问作者Rodrigo
相关产品推荐
相关产品推荐

