0

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;
});
Saqlain
  • 191
  • 1
  • 8

1 Answers1

-1

Why you are declaring GoRoute as a Provider. it is better to put globally. btw how you are declaring it in main function

imran
  • 49
  • 1
  • 8
  • Please ask questions via a comment instead of as an answer. I have wrapped GoRouter into a provider to access a ref from the provider. Below is how I am accessing the router. MaterialApp.router( routerDelegate: ref.read(routerProvider).routerDelegate, routeInformationParser: ref.read(routerProvider).routeInformationParser, routeInformationProvider: ref.read(routerProvider).routeInformationProvider, ); – Saqlain Jan 23 '23 at 20:56
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 27 '23 at 05:14