Is there any Solution to keep user login state persistent in Flutter app using auto router?

100 views Asked by At

Hello Flutter experts,

I am currently working on a Flutter application and following the clean architecture pattern. I have successfully implemented user authentication using Bloc, and I'm using the auto_router package for routing in my application. However, I'm facing a challenge with keeping the user logged in after authentication.

Here's how to keep user login state persistent using the onGenerateRoute

return MultiBlocProvider(
    providers: [
        BlocProvider(create: (_) => di.sl<AuthCubit>()..appStarted(context)),
        BlocProvider(create: (_) => di.sl<CredentialCubit>()),
        BlocProvider(create: (_) => di.sl<UserCubit>()),
        BlocProvider(create: (_) => di.sl<GetSingleUserCubit>()),
        BlocProvider(create: (_) => di.sl<GetSingleOtherUserCubit>()),
    ],
    child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: "Instagram Clone",
        darkTheme: ThemeData.dark(),
        onGenerateRoute: OnGenerateRoute.route,
        initialRoute: "/",
        routes: {
            "/": (context) {
                return BlocBuilder<AuthCubit, AuthState>(
                    builder: (context, authState) {
                        if (authState is Authenticated) {
                            return MainScreen(uid: authState.uid,);
                        } else {
                            return SignInPage();
                        }
                    },
                );
            }
        },
    ),
);

Now, my main question is, how can I ensure that the user remains logged in to the application using the auto_router package? auto_router doesn't provide a built-in mechanism for handling persistent login state, and my attempt to use AutoRouterGuard didn't yield the expected results.

The solution I tried, which isn't optimal, is as follows:

MultiBlocProvider(
    providers: [
        BlocProvider<AuthCubit>(
            create: (context) => di.sl<AuthCubit>()..appStarted(),
        ),
        BlocProvider<CredentialCubit>(
            create: (context) => di.sl<CredentialCubit>(),
        ),
    ],
    child: BlocListener<AuthCubit, AuthState>(
        listener: (context, state) {
            if (state is Authenticated) {
                _appRouter.replace(MainRoute(index: 0, uid: state.uid));
            } else {
                _appRouter.replace(const SplashScreen());
            }
        },
        child: MaterialApp.router(
            debugShowCheckedModeBanner: false,
            routerDelegate: _appRouter.delegate(),
            routeInformationParser: _appRouter.defaultRouteParser(),
            theme: ThemeData(
                colorScheme: const ColorScheme.light(
                    primary: primaryColor129C52,
                ),
                appBarTheme: const AppBarTheme(
                    color: secondaryColorWhiteFFFFFF,
                    surfaceTintColor: Colors.transparent,
                ),
                useMaterial3: true,
            ),
            title: 'Plant Port',
        ),
    ),
);

I also implemented an AuthGuard, but it doesn't seem to work as expected:

class AuthGuard extends AutoRouteGuard {
    @override
    void onNavigation(NavigationResolver resolver, StackRouter router) {
        final AuthCubit authCubit = di.sl<AuthCubit>();

        // Assuming AuthCubit has a synchronous way to check the current state
        final currentState = authCubit.state;

        if (currentState is Authenticated) {
            // If the user is authenticated, proceed with the navigation
            resolver.next(true);
        } else {
            // If the user is not authenticated, resolve the current navigation
            // and push the SignUpPage onto the stack
            resolver.next(false);
        }
    }
}

I'm looking for a more effective and cleaner way to handle persistent user login with the auto_router package. If you have any insights or solutions, I would greatly appreciate your guidance.

Thank you!

0

There are 0 answers