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

Flutter自定义模型返回Null及List<dynamic>与List<String>类型不匹配报错

问题排查与解决步骤

1 核心问题定位

你遇到的type 'Null' is not a subtype of type 'Product'报错本质是返回的Future实际触发了异常,没有返回非空的Product对象。注释info、imageUrl赋值逻辑后程序正常运行,说明问题出在这两个字段的类型转换/空值处理上,具体有两个常见原因:

  • Firestore对应文档的info/imageUrl字段不存在,或者值为Null
  • 从Firestore读出的列表默认是List<dynamic>类型,没有显式转换为List<String>,导致类型不匹配抛出异常

2 具体修复方案

2.1 修复字段类型转换与空值处理

修改getbyId方法中两个列表字段的赋值逻辑,做空值兜底和类型转换:

Future<Product> getbyId(String id) async {
  var snapshot =
    await firestore.collection('products').where('id', isEqualTo: id).get();
  // 先判空,避免文档不存在的情况
  if (snapshot.docs.isEmpty) throw Exception("未找到对应产品");
  Map<String, dynamic> data = snapshot.docs[0].data();
  return Product(
    id: data['id'],
    title: data['title'],
    price: data['price']?.toDouble(), // 顺便处理数字类型可能的int转double问题
    seller: data['seller'],
    category: data['category'],
    discription: data['discription'],
    // 处理imageUrl:空值兜底+类型转换
    imageUrl: data['imageUrl'] != null 
        ? List<String>.from(data['imageUrl']) 
        : <String>[], // 业务允许空值的话也可以赋值null
    // 处理info:逻辑同上
    info: data['info'] != null 
        ? List<String>.from(data['info']) 
        : <String>[],
    offPerCent: data['offPerCent'],
  );
}

2.2 可选:完善Product类的空安全校验

你当前用的@required是旧版本的注解,没有强制非空校验,如果你的业务要求info/imageUrl必须非空,可改成空安全版本的required,编译阶段就能发现空值问题:

class Product {
  final String? id;
  final String? title;
  final String? discription;
  final double? price;
  // 字段必须传的话用required关键字修饰
  required final List<String> info;
  required final List<String> imageUrl;
  final String? category;
  final dynamic offPerCent; // 建议也给这个字段明确类型
  final String? seller;

  Product({
    this.id,
    this.discription,
    required this.info,
    required this.imageUrl,
    this.price,
    this.seller,
    this.title,
    this.category,
    this.offPerCent
  });
}

2.3 给FutureBuilder添加异常捕获

避免Future执行异常直接抛出报错,在FutureBuilder里处理加载和错误状态:

FutureBuilder<Product>(
  future: getbyId("你的产品id"),
  builder: (context, snapshot) {
    if (snapshot.hasError) {
      return Text("加载出错:${snapshot.error}");
    }
    if (snapshot.connectionState == ConnectionState.done) {
      return 你的产品展示组件(snapshot.data!);
    }
    return const CircularProgressIndicator();
  },
)

内容的提问来源于stack exchange,提问作者Fasal Rahman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 07:45:01