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

使用Riverpod与IsarDB初始化本地数据库时遇类型转换错误求助

问题根源

错误type 'Null' is not a subtype of type 'User' in type cast的核心原因:

  • 首次启动时Isar数据库为空,isar.users.where().findFirst()返回null,但Data2的build方法声明返回FutureOr<User>,无法将null强制转换为非空的User类型。
  • 你注释掉的null处理逻辑是正确方向,但未启用;同时save方法里的writeTxn没有用await,会导致写操作未完成就尝试读取数据。
修复方案

1. 启用并完善Null处理逻辑

在build方法中检测到数据库无数据时,先调用save写入数据,等待完成后再读取返回,确保返回值为有效User对象。

2. 等待写事务完成

save方法里的isar.writeTxn必须添加await,保证数据完全写入数据库后再执行后续逻辑。

3. 优化UI层状态判断

移除多余的setState(Riverpod会自动触发UI更新),简化when方法的分支逻辑。


修改后的代码

data2_provider.dart

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:isar/isar.dart';
import 'package:asyncronize_sample/user.dart';
import 'package:asyncronize_sample/isar_provider.dart';
import 'package:flutter/services.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'data2_provider.g.dart';

@Riverpod(keepAlive: true)
class Data2 extends _$Data2 {
  @override
  FutureOr<User> build() async {
    final isar = await ref.read(isarProvider.future);
    final user = await isar.users.where().findFirst();
    
    if (user == null) {
      await save(); // 等待数据写入完成
      final savedUser = await isar.users.where().findFirst();
      return savedUser!; // 写入后必然存在数据,非空断言安全
    }
    return user;
  }

  Future<void> save() async {
    final json = await rootBundle.loadString('assets/data2.json').then((value) => jsonDecode(value) as Map<String, dynamic>);
    final user = User()
      ..name = json['name']
      ..age = json['age'];
    final isar = await ref.read(isarProvider.future);
    // await写事务,确保数据完全写入
    await isar.writeTxn(() async {
      await isar.users.put(user);
      print("Finish user writeTxn");
    });
  }
}

main.dart(HomeView2部分)

class _HomeView2State extends ConsumerState<HomeView2> {
  @override
  Widget build(BuildContext context) {
    final userAsync = ref.watch(data2Provider);
    return Scaffold(
      body: Center(
        child: userAsync.when(
          data: (userData) {
            debugPrint('user: ${userData.name}');
            return Text(userData.name);
          },
          error: (error, stackTrace) {
            debugPrint('Error: ${error.toString()}');
            debugPrint(stackTrace.toString());
            return const Text('加载失败');
          },
          loading: () => const CircularProgressIndicator(),
        ),
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:46:12