Flutter Bloc How to emit inside a listener

535

I have a solution/workaround for this case.
Let's make an (for example) AuthEvent.onUserDataUpdated(User) event, in the stream listener you have to call add() with this event and create a handler for it (on<...>(...)) to emit new AuthState.

Share:
535
Millenial2020
Author by

Millenial2020

Updated on December 16, 2022

Comments

  • Millenial2020
    Millenial2020 over 1 year

    I have wanted to set up authentication using Firebase. I have this auth repository that has this method that gets the current user.

    @override
    Stream<User?> get user => _firebaseAuth.userChanges();
    

    Inside my bloc, I Have this constructor.

    class AuthBloc extends Bloc<AuthEvent, AuthState> {
      final AuthRepository _authRepository;
      late StreamSubscription<User?> _authSubscription;
    
      AuthBloc(AuthRepository authRepository)
          : _authRepository = authRepository,
            super(const AuthState.initial()) {
        on<AuthStarted>(_onUserChanged);
      }
    
      void _onUserChanged(AuthStarted event, Emitter<AuthState> emit) {
        _authSubscription = _authRepository.user.listen((user) async {
          if (user != null) {
            emit(AuthState.authenticated(user));
          } else {
            const AuthState.unauthenticated();
          }
        });
      }
    }
    

    When my app starts, I'm calling this on my main class.

     BlocProvider<AuthBloc>(
                create: (context) => AuthBloc(context.read<AuthRepository>())
                  ..add(const AuthEvent.started()),
              ),
    

    This is how my state looks like

    part of 'auth_bloc.dart';
    
    @freezed
    class AuthState with _$AuthState {
      const factory AuthState.initial() = _initial;
      const factory AuthState.authenticated(User user) = _Authenticated;
      const factory AuthState.unauthenticated() = _Unauthenticated;
    }
    

    Now I have this on my UI depending on the state of my app. I want to render different views.

        return state.when(
          initial: () => _buildInitial(context),
          authenticated: (user) => _buildAuthenticated(),
          unauthenticated: () => _buildUnauthenticated(),
        );
    

    I'm getting the following error on my bloc.

    enter image description here

    This line right here is triggering the error.

    enter image description here

    I'm using the freezed package to generate Union, and using Bloc 8.0.

    • Arti Scream
      Arti Scream over 2 years
      Error says you need to make _onUserChange async function like Future<void> _onUserChanged(AuthStarted event, Emitter<AuthState> emit) async { ...
    • Millenial2020
      Millenial2020 over 2 years
      Yeah but don't know how to await a stream.