I have a log-in screen with a home screen. Once a user logs in, it redirects the user to the home screen. However, I have a bloc which checks if user was authenticated before, if yes, it redirects the user straight to the home screen.
However, it doesn't work as intended. The "isLoggedIn" bool value changes, but the UI doesn't react. How to solve this?
Here's the code
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:harnasik/core/router/app_router.gr.dart';
import 'package:harnasik/core/style/custom_colors.dart';
import 'package:harnasik/features/authorization/presentation/blocs/log_in/log_in_bloc.dart';
import 'package:harnasik/generated/l10n.dart';
import 'package:harnasik/injection_container.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await InjectionContainer().init();
runApp(const HarnasikApp());
}
class HarnasikApp extends StatefulWidget {
const HarnasikApp({Key? key}) : super(key: key);
@override
_HarnasikAppState createState() => _HarnasikAppState();
}
class _HarnasikAppState extends State<HarnasikApp> {
late final LogInBloc logInBloc;
late bool isLoggedIn;
final AppRouter _appRouter = sl();
@override
void initState() {
logInBloc = sl();
super.initState();
isLoggedIn = false;
logInBloc..add(CheckIfUserLoggedInEvent());
}
@override
void dispose() {
logInBloc.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return BlocListener(
bloc: logInBloc,
listener: (context, state) {
if (state is LoggedInState) {
isLoggedIn = true;
} else if (state is LogInErrorState) {
print('Error'); // For tests only
}
},
child: MaterialApp.router(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primaryColor: CustomColors.blue,
fontFamily: 'Lato',
),
routerDelegate: _appRouter.delegate(
initialRoutes: [
if (!isLoggedIn) const LogInScreen() else const HomeScreen(),
],
),
routeInformationParser: _appRouter.defaultRouteParser(),
localizationsDelegates: const [
S.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate
],
supportedLocales: S.delegate.supportedLocales,
),
);
}
}
I solved this same problem using an auto_route guard like this:
/// An auto_route guard object that routes the user to our landing page if
/// signed in and to the home page if not signed in
class GetInitialRoute extends AutoRouteGuard {
@override
void onNavigation(NavigationResolver resolver, StackRouter router) {
// Here we check if the user is logged in using FirebaseAuth (not currentUser -->
// not logged in)
if (FirebaseAuth.instance.currentUser == null) {
// if we do not have a user yet, we resume navigation to the sign in page
// with path: '/'
resolver.next(true);
} else {
// if we already have a logged in user, we push them to our home page
router.push(const HomeRoute());
}
}
}
Please read this article on authentication in auto_route LINK and this article on route_guards LINK to learn more. These articles also explain how to apply a guard to your routes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With