I am trying to implement redirection in my GoRouter so that if it finds the user is not authenticated then it will direct them to a login page otherwise proceed as-is.
My implementation works fine for when the user needs to be redirected to login, however when the user has successfully logged in and the redirect method successfully runs and reads the new login state- my UI does not get redirected to the original path that I navigated to before I got redirected to the login.
Below is my implementation.
final routerProvider = Provider<GoRouter>((ref) {
return GoRouter(
initialLocation: Routes.home.toPath(),
refreshListenable: ref.read(authenticationListener),
redirect: (context, state) {
final authState = ref.read(authenticationListener).value;
final isAuthenticated = authState != null;
final isRegistering =
state.subloc == p.join(Routes.login.toPath(), Routes.signUp.toPath());
Routes.signUp.toPath();
final isLoggingIn = state.subloc == Routes.login.toPath();
if (!isAuthenticated && (isRegistering || isLoggingIn)) return null;
if (authState == null) return Routes.login.toPath();
return null;
},
routes: [
GoRoute(
path: Routes.login.toPath(),
name: Routes.login.name,
builder: (context, state) => const Login(),
routes: [
GoRoute(
path: Routes.signUp.toPath(),
name: Routes.signUp.name,
builder: (context, state) => const SignUp(),
)
]),
GoRoute(
path: Routes.home.toPath(),
name: Routes.home.name,
builder: (context, state) => const Home(),
),
],
);
});
Below are my routes.
enum Routes { login, home, signUp }
extension RouteExtension on Routes {
String toPath() {
switch (this) {
case Routes.login:
return '/login';
case Routes.home:
return '/';
case Routes.signUp:
return 'sign-up';
}
}
}
Here's my listenable which wraps around a StateNotifier. It seems to be working fine.
final authenticationListener = Provider<ValueNotifier<sp.AuthResponse?>>((ref) {
final notifier = ValueNotifier<sp.AuthResponse?>(null);
ref.listen(AuthenticationController.provider, (previous, next) {
notifier.value = next;
});
return notifier;
});