How to update nested screens based on riverpods streamProvider?

Viewed 457

Imagine there are three screens. main.dart, home.dart & signIn.dart I have the code, shown below. When I'm in the homescreen and the streamProvider(firebaseAuthStateProvider) changes, I will get automatically back to the main.dart screen. After that, the if-query sends me right to the signIn.dart screen. Just like expected. But when I create a new nested screen and the streamProvider changes its value, the "root" screen (home.dart) doesn't send me back to the signIn screen. So I imagine it only works for the first child and not the nested ones.

Is it possible to have just one query to check for a streamProvider in the root screen or do i have to put a query in every single screen to check the value?

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();
      }
      //...
1 Answers

As long as the highest widget is the one listening to the auth state changes, all of the children will be subject to the change in screens. The below code is something I found on GitHub a while ago and has been my goto in all my Flutter projects.

AuthHome() is my top level widget that is the parent to the rest of my application

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);
  }
}

where NavBase() is where the rest of the authenticated portion of the app lives

Related