【问题标题】:How to update nested screens based on riverpods streamProvider?如何根据riverpods streamProvider 更新嵌套屏幕?
【发布时间】:2021-07-02 07:26:31
【问题描述】:

假设有三个屏幕。 main.dart、home.dart 和 signIn.dart 我有代码,如下所示。当我在主屏幕中并且 streamProvider(firebaseAuthStateProvider) 发生变化时,我将自动返回 main.dart 屏幕。之后,if 查询将我直接发送到 signIn.dart 屏幕。正如预期的那样。但是,当我创建一个新的嵌套屏幕并且 streamProvider 更改其值时,“根”屏幕 (home.dart) 不会将我发送回登录屏幕。所以我想它只适用于第一个孩子而不是嵌套的孩子。

是否可以在根屏幕中只使用一个查询来检查 streamProvider,还是我必须在每个屏幕中都放置一个查询来检查值?

class SignInCheck extends ConsumerWidget {
  @override
  Widget build(BuildContext context, ScopedReader scopedReader) {
    final _authState = scopedReader(firebaseAuthStateProvider); //
    return _authState.when(data: (value) {
      if (value != null) {
        return HomeScreen();
      } else {
        return SignIn();
      }
      //...

【问题讨论】:

    标签: firebase flutter firebase-authentication provider riverpod


    【解决方案1】:

    只要最高级的小部件是监听身份验证状态变化的小部件,所有的孩子都会受到屏幕变化的影响。下面的代码是我不久前在 GitHub 上找到的,并且一直是我所有 Flutter 项目中的 goto。

    AuthHome() 是我的顶级小部件,它是我的应用程序其余部分的父级

    auth_home.dart:

    class AuthHome extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return AuthWidget(
              signedInBuilder: (context) => NavBase(),
              signedOutBuilder: (context) => Login());
      }
    }
    

    auth_widget.dart:

    class AuthWidget extends ConsumerWidget {
      AuthWidget(
          {required this.signedInBuilder,
          required this.signedOutBuilder});
      final WidgetBuilder signedInBuilder;
      final WidgetBuilder signedOutBuilder;
      
    
      @override
      Widget build(BuildContext context, watch) {
        final authStateChanges = watch(authStateChangesProvider);
        return authStateChanges.when(
          data: (user) => _data(context, user),
          loading: () => const Scaffold(
            body: Center(
              child: CircularProgressIndicator(),
            ),
          ),
          error: (err, __) {
            print(err);
            return Scaffold(
              body: EmptyContent(
                title: 'Something went wrong',
                message: 'Can\'t load data right now.',
              ),
            );
          },
        );
      }
    
      Widget _data(BuildContext context, User? user) {
        if (user != null) {
          return signedInBuilder(context);
        }
        return signedOutBuilder(context);
      }
    }
    

    NavBase() 是应用的其余已验证部分所在的位置

    【讨论】:

    • 谢谢,我试过你的代码,效果很好。然而,最初的问题仍然存在。我发现,它只发生在我使用路由并通过 .pushNamed("routeName") 切换页面时。路由可能是问题吗?
    • 没有完整地看到您的实现,我无法进一步阐明可能导致问题的原因。如果代码在 GitHub 上,我可以查看。根据您所说的,如果您推送的路由不是小部件监控身份验证的后代,那么问题将持续存在。
    猜你喜欢
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-19
    • 2020-02-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多