So i will provide my code as it is the simplest way of understanding my problem. I started with my UserService class that creates a stream which receives data continuously whenever the AuthStateChanges (from FirebaseAuth) stream triggers
enum AuthEventEnum { authenticated, unauthenticated }
class UserService {
StreamController<AuthEventEnum> controller =
StreamController<AuthEventEnum>();
late final StreamSubscription _subscription;
StreamSubscription get subscription => _subscription;
UserService() {
final StreamSubscription _subscription =
FirebaseAuth.instance.authStateChanges().listen(
(User? user) {
print(user);
if (user == null) {
controller.sink.add(AuthEventEnum.unauthenticated);
} else if (user != null) {
controller.sink.add(AuthEventEnum.authenticated);
}
},
);
}
}
now i tried to connect to my AuthBloc (which i am pretty sure the errors comes from here... but i dont know how to fix it)
class AuthBloc extends Bloc<AuthEventEnum, AuthState> {
final UserService _userService;
late final _addEvents;
AuthBloc(this._userService) : super(AuthInitial()) {
_addEvents = _userService.controller.stream.listen(
(event) {
if (event == AuthEventEnum.authenticated) {
mapEventToState(AuthEventEnum.authenticated);
} else if (event == AuthEventEnum.unauthenticated) {
mapEventToState(AuthEventEnum.authenticated);
}
},
);
}
@override
Stream<AuthState> mapEventToState(AuthEventEnum event) async* {
if (event == AuthEventEnum.authenticated) {
yield AuthAuthenticatedState();
} else if (event == AuthEventEnum.unauthenticated) {
yield AuthUnauthenticatedState();
}
}
}
now the end goal was to redirect users to to different routes according to their AuthStatus...
class AppRouter {
AuthBloc authBloc;
late final GoRouter routes;
AppRouter({required this.authBloc}) {
routes = GoRouter(
initialLocation: '/home',
redirect: (context, state) {
if (authBloc.state is AuthInitial) {
return '/register';
} else if (authBloc.state is AuthAuthenticatedState) {
return '/app';
} else if (authBloc.state is AuthUnauthenticatedState) {
return '/register';
}
},
routes: [
GoRoute(
path: '/home',
builder: (context, state) => const HomePage(),
),
GoRoute(
path: '/login',
builder: (context, state) => const LoginPage(),
),
GoRoute(
path: '/register',
builder: (context, state) => const RegisterPage(),
),
GoRoute(
path: '/app',
builder: (context, state) => const AppPage(),
),
],
);
}
}
in case main function is relevant here it is:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
final authService = UserService();
final authBloc = AuthBloc(authService);
runApp(
BlocProvider.value(
value: authBloc,
child: MaterialApp.router(
title: 'flutter demo',
theme: ThemeData(primarySwatch: Colors.blue),
routerConfig: AppRouter(authBloc: authBloc).routes,
),
),
);
}
Learn more about how Bloc works with streams and how can a bloc listen to other streams and add events to itself