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

使用FlutterData的save()时出现model.key为空的空值检查异常

问题

使用flutter_data包将API获取的数据本地存储时,调用remoteAdapter.save()触发Unhandled Exception: Null check operator used on a null value异常,异常出现在await localAdapter.save(model._key!, model)这一行的空值检查上。

相关代码实现如下:

遍历API返回结果调用save:

res.results.forEach((element) {
      element.save(element, remote: false);
});

异常触发位置(flutter_data内部代码):

// ensure model is saved
 await localAdapter.save(model._key!, model); // 触发空值检查异常

自定义的PlaceAdapter:

mixin PlaceAdapter<T extends DataModelMixin<T>> on RemoteAdapter<T> {

  @override
  Future<T> save(
    model, {
    bool? remote,
    Map<String, dynamic>? params,
    Map<String, String>? headers,
    Object? onSuccess,
    Object? onError,
    DataRequestLabel? label,
  }) {
    return super.save(model, remote: false);
  }
}

Place模型类:

@freezed
@DataRepository([PlaceAdapter])
class Place with DataModelMixin<Place>, _$Place {
  Place._();

  factory Place({
    required String id,
    required String name,
    required String address,
  }) = _Place;

  factory Place.fromJson(Map<String, Object?> json) => _$PlaceFromJson(json);
}

应用入口配置:

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ProviderScope(
      overrides: [
        configureRepositoryLocalStorage(
          baseDirFn: () async => getApplicationDocumentsDirectory().then((dir) => dir.path),
        ),
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        navigatorKey: StackedService.navigatorKey,
        onGenerateRoute: StackedRouter().onGenerateRoute,
        home: Splashscreen(),
      ),
    );
  }
}
分析与解决

核心问题

异常根源是model._key为null,flutter_data内部用!空值检查导致崩溃。_key是框架为模型生成的本地存储标识,由框架自动管理,你的代码存在两处关键错误:

  1. save方法调用传参错误
    save是DataModelMixin的扩展方法,无需传入模型本身,你当前的调用element.save(element, remote: false)会导致框架无法正确识别实例,进而无法生成或关联_key。

  2. 自定义Adapter泛型声明错误
    PlaceAdapter的泛型写成T extends DataModelMixin<T>,但实际应绑定到具体的Place类型,错误泛型会导致框架处理模型元数据时异常,无法初始化_key。

修复步骤

  • 修正save调用方式:
    res.results.forEach((element) {
          element.save(remote: false);
    });
    
  • 修正PlaceAdapter的泛型与参数类型:
    mixin PlaceAdapter on RemoteAdapter<Place> {
    
      @override
      Future<Place> save(
        Place model, {
        bool? remote,
        Map<String, dynamic>? params,
        Map<String, String>? headers,
        Object? onSuccess,
        Object? onError,
        DataRequestLabel? label,
      }) {
        return super.save(model, remote: false);
      }
    }
    
  • (可选)如果API返回的主键字段不是id,需在模型字段上添加@DataKey()注解指定主键,确保框架能正确关联模型标识。

额外说明

flutter_data的DataModelMixin会自动为模型实例注入_key,前提是实例通过框架规范方式创建(比如Place.fromJson解析、repository获取),不要手动修改_key相关内部字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:12:57