This is more of design question than an issue but have spent quite a bit of time, any ideas how to resolve this will help. The functionality I am trying to get is after a user signs in, one should not be able to go back to the previous screen( the Signin screen). I am using pushNamedAndRemoveUntil() to reset the navigation but it also remove the widget that has the authBloc listener from the tree. So any further changes in the authentication state does not work.
Here is a sample project with the problem
https://github.com/mzafer/MyFlutterBloc
In main.dart, I create the authbloc and initialize it with the AppStarted event.
void main() {
runApp(
MultiBlocProvider(
providers: [
BlocProvider<AuthBloc>(
create: (context) =>
AuthBloc()
..add(AuthEvent_AppStarted())
),
],
child: MyApp())
);
}
The Start.dart is the first screen and has the BlocListener with the routing logic.
@override
Widget build(BuildContext context) {
return BlocListener<AuthBloc, AuthState>(
listener: ( context, state) {
if (state is AuthState_Unauthenticated) {
print('Route to Sign In');
//Navigator.of(context).pushNamedAndRemoveUntil('/signIn', (route) => false);
Navigator.of(context).pushNamed('/signIn');
} else if (state is AuthState_Authenticated) {
print('Route to Home');
//Navigator.of(context).pushNamedAndRemoveUntil('/home', (route) => false);
Navigator.of(context).pushNamed('/home');
}
},
child:Splash()
);
}
Using pushNamed here for routing allows any future AuthState changes to be listened and trigger appropriate actions but it also lets one to click on the back button and goto the previous screen. But using pushNamedAndRemoveUntil here fixes the back button issue but break the listener.
Hi @mzafer 馃憤
Thanks for opening an issue!
I've opened a pull request with suggestions for how to simplify the navigation and achieve the desired outcome. Hope that helps!
Closing for now but feel free to comment with additional questions and I'm happy to continue the conversation 馃憤
Hi @felangel ,
Thanks for your response. The changes you recommended is where I started based on your various examples. But overtime my app has grown big and complex, so had to make some changes, 1) Moved all routing logic to it own service class, 2) Introduced fluro to manage routing. If I were to go back per your recommendation above it would bloat my Main.dart file. Any other alternative to accompalish this without moving the routing to the Main.dart ?
@mzafer you can extract the routing table to it's own file if you'd like
// routes.dart
final routes = {
'/': (_) => Splash(),
'/signIn': (_) => SignIn(),
'/home': (_) => Home(),
};'
Then import routes in your app like:
Widget build(BuildContext context) {
return MaterialApp(
routes: routes,
...
);
}
In terms of the routing logic I don't think it should grow because it should be scoped to just authentication related routing changes at the root. You can always decompose further into more widgets as needed though 馃憤
Thanks @felangel , did that and am good for now.
Most helpful comment
Thanks @felangel , did that and am good for now.