StreamProvider: Error: Could not find the correct Provider<User> above this App Widget
StreamProvider: Error: Could not find the correct Provider<User> above this App Widget
我在我的 flutter-firebase 应用程序中使用提供程序包中的 StreamProvider 来实现身份验证功能,就像本教程中解释的那样 https://www.youtube.com/watch?v=j_SJ7XmT2MM&list=PL4cUxeGkcC9j--TKIdkb3ISfRbJeJYQwC&index=9。
当尝试 运行 我的应用程序时,我收到一条错误消息,并提供了如何正确执行的建议,但我的代码是按照建议的方式编写的。
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(FirebaseWrapper());
runApp(App());
}
class FirebaseWrapper extends StatelessWidget {
// Create the initialization Future outside of build():
final Future<FirebaseApp> _initialization = Firebase.initializeApp();
// final Future<void> _initSharedPrefs = SharedPrefsHelper().initSharedPrefsInstance();
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
return FutureBuilder(
// from: https://firebase.flutter.dev/docs/overview/#initializing-flutterfire
future: _initialization,
// future: Future.wait([_initialization, _initSharedPrefs]),
builder: (context, snapshot) {
if (snapshot.hasError) return ErrorPage(); //TODO better error pages
if (snapshot.connectionState == ConnectionState.done) return FirebaseAuthWrapper();
return Loading(); //waiting
},
);
}
}
class FirebaseAuthWrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider<User>.value(
value: Auth().userStream,
initialData: null,
child: App(),
);
}
}
class App extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
@override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
print('yeet');
return MaterialApp(
key: UniqueKey(),
title: 'Wanderapp',
theme: ThemeData(primarySwatch: Colors.blue),
initialRoute: (user == null) ? '/signIn' : '/',
routes: (user == null)
? {
'/signIn': (context) => SignIn(),
'/register': (context) => Register(),
// '/forgotPassword': (context) => ForgotPassword(),
}
: {
'/': (context) => Home(),
//...
},
);
}
}
错误信息:
Error: Could not find the correct Provider<User> above this App Widget
This happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:
- You added a new provider in your `main.dart` and performed a hot-reload.
To fix, perform a hot-restart.
- The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.
- You used a `BuildContext` that is an ancestor of the provider you are trying to read.
Make sure that App is under your MultiProvider/Provider<User>.
This usually happens when you are creating a provider and trying to read it immediately.
For example, instead of:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>()),
),
}
```
consider using `builder` like so:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the provider
builder: (context) {
// No longer throws
return Text(context.watch<Example>()),
}
),
}
```
我是来自 Firebase for StreamProvider 和 Provider.of 的同一个“用户”class,hierarchy/scope 在我的代码中似乎也是正确的,但事实并非如此工作。
有谁知道我的错误是什么?非常感谢。
在关于 runApp
的 link 中,它说:
Calling runApp again will detach the previous root widget from the
screen and attach the given widget in its place.
因此,您只需要删除第二个 runApp
,因为无论如何都会从 StreamProvider
调用应用程序:child: App(),
.
解法:
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(FirebaseWrapper());
runApp(App()); //*** Remove this line ***///
}
我在我的 flutter-firebase 应用程序中使用提供程序包中的 StreamProvider 来实现身份验证功能,就像本教程中解释的那样 https://www.youtube.com/watch?v=j_SJ7XmT2MM&list=PL4cUxeGkcC9j--TKIdkb3ISfRbJeJYQwC&index=9。
当尝试 运行 我的应用程序时,我收到一条错误消息,并提供了如何正确执行的建议,但我的代码是按照建议的方式编写的。
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(FirebaseWrapper());
runApp(App());
}
class FirebaseWrapper extends StatelessWidget {
// Create the initialization Future outside of build():
final Future<FirebaseApp> _initialization = Firebase.initializeApp();
// final Future<void> _initSharedPrefs = SharedPrefsHelper().initSharedPrefsInstance();
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
return FutureBuilder(
// from: https://firebase.flutter.dev/docs/overview/#initializing-flutterfire
future: _initialization,
// future: Future.wait([_initialization, _initSharedPrefs]),
builder: (context, snapshot) {
if (snapshot.hasError) return ErrorPage(); //TODO better error pages
if (snapshot.connectionState == ConnectionState.done) return FirebaseAuthWrapper();
return Loading(); //waiting
},
);
}
}
class FirebaseAuthWrapper extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamProvider<User>.value(
value: Auth().userStream,
initialData: null,
child: App(),
);
}
}
class App extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
@override
Widget build(BuildContext context) {
final user = Provider.of<User>(context);
print('yeet');
return MaterialApp(
key: UniqueKey(),
title: 'Wanderapp',
theme: ThemeData(primarySwatch: Colors.blue),
initialRoute: (user == null) ? '/signIn' : '/',
routes: (user == null)
? {
'/signIn': (context) => SignIn(),
'/register': (context) => Register(),
// '/forgotPassword': (context) => ForgotPassword(),
}
: {
'/': (context) => Home(),
//...
},
);
}
}
错误信息:
Error: Could not find the correct Provider<User> above this App Widget
This happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:
- You added a new provider in your `main.dart` and performed a hot-reload.
To fix, perform a hot-restart.
- The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.
- You used a `BuildContext` that is an ancestor of the provider you are trying to read.
Make sure that App is under your MultiProvider/Provider<User>.
This usually happens when you are creating a provider and trying to read it immediately.
For example, instead of:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// Will throw a ProviderNotFoundError, because `context` is associated
// to the widget that is the parent of `Provider<Example>`
child: Text(context.watch<Example>()),
),
}
```
consider using `builder` like so:
```
Widget build(BuildContext context) {
return Provider<Example>(
create: (_) => Example(),
// we use `builder` to obtain a new `BuildContext` that has access to the provider
builder: (context) {
// No longer throws
return Text(context.watch<Example>()),
}
),
}
```
我是来自 Firebase for StreamProvider 和 Provider.of 的同一个“用户”class,hierarchy/scope 在我的代码中似乎也是正确的,但事实并非如此工作。 有谁知道我的错误是什么?非常感谢。
在关于 runApp
的 link 中,它说:
Calling runApp again will detach the previous root widget from the screen and attach the given widget in its place.
因此,您只需要删除第二个 runApp
,因为无论如何都会从 StreamProvider
调用应用程序:child: App(),
.
解法:
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(FirebaseWrapper());
runApp(App()); //*** Remove this line ***///
}