【问题标题】:StreamProvider: Error: Could not find the correct Provider<User> above this App WidgetStreamProvider:错误:在此 App Widget 上方找不到正确的 Provider<User>
【发布时间】:2021-12-19 03:27:35
【问题描述】:

我在我的 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 中 StreamProvider 和 Provider.of 的相同“用户”类的用户,层次结构/范围在我的代码中似乎也是正确的,但它不起作用。 有谁知道我的错误是什么?非常感谢。

【问题讨论】:

    标签: flutter stream provider


    【解决方案1】:

    在这个link 关于runApp 它说:

    再次调用 runApp 将从 屏幕并在其位置附加给定的小部件。

    因此,您只需要删除第二个runApp,因为无论如何都会从StreamProvider 调用App:child: App(),

    解决方案:

    void main() {
      WidgetsFlutterBinding.ensureInitialized();
      runApp(FirebaseWrapper());
      runApp(App()); //*** Remove this line ***///
    }
    

    【讨论】:

    • 这是一个复制粘贴错误,我没有注意到,非常感谢!
    • 如果它解决了您的问题,请考虑接受答案。这可能对面临相同问题的其他人有用。
    猜你喜欢
    • 2020-11-28
    • 2021-02-04
    • 2021-10-27
    • 2021-04-29
    • 2021-09-29
    • 1970-01-01
    • 2021-02-07
    • 2023-04-01
    • 2021-01-31
    相关资源
    最近更新 更多