将Firebase自动生成的文档ID添加到对象时数据为null是什么原因
问题根因
- 第一个问题是
ProductModel.fromJson构造方法出现变量遮蔽:构造参数名id和类的成员变量id重名,你写的id = id实际是给参数自身赋值,完全没有把传入的文档ID赋值给类的成员变量,所以ProductModel实例的id字段始终为空,自然无法正常渲染。 - 第二个
data != null断言错误有两个常见诱因:- 高版本cloud_firestore依赖中,
element.data()返回Map<String, dynamic>?可空类型,你未做非空判断直接传入构造方法,遇到空值时触发空安全断言 - ProductModel的非空类型成员变量未在构造阶段完成初始化,使用时触发空校验
- 高版本cloud_firestore依赖中,
修复方案
- 修正构造方法的赋值逻辑,用
this.明确指向类成员变量,避免变量遮蔽:
class ProductModel { // 确认成员变量定义正确 String id; String description; String flavor; String name; int price; String imageurl; // 修正后的命名构造方法 ProductModel.fromJson( Map<String, dynamic> prod, String id, ) : this.id = id, description = prod['description'] ?? 'Classic macaron', flavor = prod['flavor'] ?? 'Chocolate', name = prod["name"] ?? 'empty', price = prod["price"] ?? 5, imageurl = prod["imageurl"] ?? 'www.google.com'; }
你也可以在构造方法体内写this.id = id实现相同效果,使用初始化列表写法更符合Dart规范。
- 修正数据流方法,对文档数据做非空判断,避免空值传入:
Stream<List<ProductModel>> getprod() { return _firestore .collection('macarons') .snapshots() .map((QuerySnapshot query) { List<ProductModel> retVal = []; for (var element in query.docs) { final prodData = element.data() as Map<String, dynamic>?; // 仅当数据不为空时才实例化模型 if (prodData != null) { retVal.add(ProductModel.fromJson(prodData, element.id)); } } return retVal; }); }
- 如果你使用
StreamBuilder渲染组件,需要确保快照状态判断逻辑正确,仅在snapshot.hasData返回true、且快照数据不为空时再渲染列表内容,避免访问空数据触发断言。
内容的提问来源于stack exchange,提问作者dit0m
相关产品推荐
相关产品推荐

