在此主页小部件上方找不到正确的提供程序<FirebaseUser>

Could not find the correct Provider<FirebaseUser> above this HomePage Widget

我刚开始使用提供程序包重构我的应用程序结构。现在我得到了上面的错误,即使我在下一个 BuildContext.widget 树中向下调用提供者。 知道什么可能导致错误吗?据我了解,错误消息中解释的常见错误情况不应该适用于我。 Widget tree

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        Provider(create: (_) => FirebaseAuth.instance.onAuthStateChanged)
      ],
      child: MaterialApp(
          title: "My App",
          home: HomePage()),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return _getLandingPage(Provider.of<FirebaseUser>(context), context);
  }

  Widget _getLandingPage(FirebaseUser firebaseUser, context) {
    if (firebaseUser != null) {
        return CreateProfileFlow();

    } else {
      return PhoneNrInput();
    }
  }
}

错误:

Error: Could not find the correct Provider<FirebaseUser> above this HomePage Widget

This likely happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:

- 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 HomePage is under your MultiProvider/Provider<FirebaseUser>.
  This usually happen when you are creating a provider and trying to read it immediatly.

  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
      builer: (context) {
        // No longer throws
        return Text(context.watch<Example>()),
      }
    ),
  }
  ```

If none of these solutions work, consider asking for help on Whosebug:
https://whosebug.com/questions/tagged/flutter

FirebaseAuth.instance.onAuthStateChangedStream,但您使用 Provider 而不是 StreamProvider 来公开值。

因此,如果你想读取这个值,你有两个选择:

  • 使用StreamProvider代替Provider

    StreamProvider(
      create: (_) => FirebaseAuth.instance.onAuthStateChanged,
    ),
    
  • 继续使用Provider,获取流context.watch<Stream<FirebaseUser>>:

    StreamBuilder(
      stream: context.watch<Stream<FirebaseUser>>(),
      builder: (context, snapshot) {
        ...
      },
    );
    

每当状态发生变化时,使用 StreamBuilder 检查用户数据。

class AuthenticationWrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<User>(
      stream: FirebaseAuth.instance.authStateChanges(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.active) {
          User user = snapshot.data;
          if (user == null) {
            return LoginPage();
          }
          return HomePage();
        } else {
          return Scaffold(
            body: Center(
              child: CircularProgressIndicator(),
            ),
          );
        }
      },
    );
  }
}