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

使用Riverpod与mongo_dart连接MongoDB Atlas时遇状态错误求助

解决方案:MongoDB连接状态错误 + Riverpod正确用法

问题根源

你调用db.open()时没有添加await,导致数据库还处于OPENING状态,就把未完成连接的Db实例传给了Provider,后续代码使用这个实例时触发了状态错误。


方案1:修正main函数,等待连接完成后再注入Provider

直接在main函数里等待数据库连接建立完成,再把就绪的Db实例传给Provider:

final dataProvider = Provider<Db>((ref) => throw 'Database Not Initialized');

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  var db = Db.create('mongo-srv-string');
  // 必须await,等待连接完全建立
  await db.open();

  runApp(
    ProviderScope(
      // 注意:这里不能加const,因为override的是动态创建的Db实例
      overrides: [
        dataProvider.overrideWithValue(db),
      ],
      child: const Application(),
    ),
  );
}

方案2:使用FutureProvider(更符合Riverpod异步管理规范)

推荐用FutureProvider来管理异步的数据库连接,它会自动处理加载、错误状态,还能帮你自动释放资源:

// 定义FutureProvider管理Db实例
final dbProvider = FutureProvider<Db>((ref) async {
  final db = Db.create('mongo-srv-string');
  await db.open();
  // 当Provider销毁时自动关闭数据库连接,避免资源泄漏
  ref.onDispose(() => db.close());
  return db;
});

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(
    const ProviderScope(
      child: Application(),
    ),
  );
}

在Widget中使用时,通过AsyncValue处理不同状态:

class YourWidget extends ConsumerWidget {
  const YourWidget({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final dbAsync = ref.watch(dbProvider);
    return dbAsync.when(
      loading: () => const CircularProgressIndicator(), // 加载中状态
      error: (error, stackTrace) => Text('连接失败:$error'), // 错误状态
      data: (db) {
        // 这里使用已就绪的Db实例
        return const Text('数据库连接成功');
      },
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 16:42:20