Flutter结合MultiProvider与StreamProvider时出现Provider找不到报错
Error: Could not find the correct Provider
above this MyApp Widget
问题复现涉及的代码
main.dart
class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { final provider = Provider.of<SignInProvider>(context, listen: false); return MultiProvider( providers: [ StreamProvider<UserModel>.value(value: provider.authStateChange()) ], child: MaterialApp( title: 'Flutter Demo', theme: ThemeData( primaryColor: primaryColor, accentColor: secondaryColor, textTheme: customTextTheme ), home: AuthHandler() ), ); } } class AuthHandler extends StatelessWidget { @override Widget build(BuildContext context) { UserModel _userModel = Provider.of<UserModel>(context); return (_userModel != null) ? HomeScreen() : LoginScreen(); } }
user_model.dart
class UserModel { String uid; String displayName; String photoURL; String email; UserModel({ this.uid, this.displayName, this.photoURL, this.email, }); }
signin_provider.dart
Stream<UserModel> authStateChange() { return firebaseAuth.authStateChanges().map((User user) => (user != null) ? UserModel(uid: user.uid) : null); }
问题根因
- 依赖查找顺序完全倒置:在
MyApp的build阶段直接调用Provider.of<SignInProvider>(context)查找依赖,但此时SignInProvider还没有被注入到Widget树中,查找必然失败。 - 方法定义位置错误:
authStateChange()目前是独立的全局函数,没有挂载在SignInProvider类内部,就算Provider注入逻辑正常,也无法通过SignInProvider的实例调用这个方法。 - 缺少SignInProvider本身的注入逻辑:当前MultiProvider的配置列表里根本没有注册
SignInProvider的条目,整个Widget树中不存在这个类型的Provider实例。
修复步骤
- 第一步:补全
SignInProvider类定义,把原本独立的authStateChange()方法移到类内部,作为类的成员方法:
// signin_provider.dart 修正后的基础结构 class SignInProvider { // 初始化Firebase实例 final FirebaseAuth firebaseAuth = FirebaseAuth.instance; Stream<UserModel> authStateChange() { return firebaseAuth.authStateChanges().map((User user) => (user != null) ? UserModel(uid: user.uid) : null ); } }
- 第二步:调整Provider注入顺序,先把所有依赖注册到MultiProvider的providers列表中,再在子组件内查找依赖,不要在顶层根组件的build方法里查找还未注入的依赖。
- 第三步:给
StreamProvider补充initialData参数,避免初始化阶段空值报错。
修正后的main.dart参考实现:
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MultiProvider( providers: [ // 先注册SignInProvider本身 ChangeNotifierProvider(create: (_) => SignInProvider()), // 基于SignInProvider实例生成对应的登录状态流 StreamProvider<UserModel>( create: (context) => Provider.of<SignInProvider>(context, listen: false).authStateChange(), initialData: null, ), ], child: MaterialApp( title: 'Flutter Demo', theme: ThemeData( primaryColor: primaryColor, accentColor: secondaryColor, textTheme: customTextTheme ), home: AuthHandler(), ), ); } } class AuthHandler extends StatelessWidget { @override Widget build(BuildContext context) { // 从StreamProvider中读取登录状态 UserModel? _userModel = Provider.of<UserModel>(context); return (_userModel != null) ? HomeScreen() : LoginScreen(); } }
内容的提问来源于stack exchange,提问作者user15103024
相关产品推荐
相关产品推荐

