Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

flutter - Bloc listener not called when authentication state is updated?

Any help would be grateful, I have no idea where is the issue. I have a splash page where based on AuthCheckState, if the user is registered he gets pushed to the HomeScreen or to the SignUp/Welcome screen.

When inside the SignUp page, If I successfully register with Firebase, my SignInForm listener is triggered and the user is pushed back to the SplashScreen and a new authCheckEvent is sent to my AuthCheck bloc.

My AuthCheck bloc then yields the updated state (authenticated), but the listener inside the SplashPage is not called.

class SplashPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocListener<AuthCheckBloc, AuthCheckState>(
      listener: (context, state) {
        state.map(
          initial: (_) {
            print("Inital STate");
          },
          authenticated: (_) {
            print("Authenticated STate");
            Navigator.of(context).pushReplacement(
              MaterialPageRoute(
                builder: (context) => HomePage(),
              ),
            );
          },
          unauthenticated: (_) {
            print("Unathenticated state STate");
            Navigator.of(context).pushReplacement(
              MaterialPageRoute(
                builder: (context) => WelcomePage(),
              ),
            );
          },
        );
      },
      child: SafeArea(
        child: Scaffold(
          body: Center(
            child: Column(
              children: [
                Spacer(),
                Padding(
                  padding: const EdgeInsets.symmetric(vertical: 20.0),
                  child: Image.asset(
                    "assets/logo.PNG",
                    width: MediaQuery.of(context).size.width * 0.5,
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.symmetric(vertical: 20.0),
                  child: CircularProgressIndicator(),
                ),
                Padding(
                  padding: const EdgeInsets.symmetric(vertical: 20.0),
                  child: const Text("Loading..."),
                ),
                Spacer(),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class SignUpPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: BlocConsumer<SignInFormBloc, SignInFormState>(
          listener: (context, state) {
            if (state.errorMessage.isNotEmpty) {
              Scaffold.of(context).showSnackBar(
                SnackBar(
                  content: Text(state.errorMessage),
                  duration: Duration(seconds: 1),
                ),
              );
            }
            if (state.isAuthStateChanged) {
              Navigator.of(context).pushReplacement(
                MaterialPageRoute(
                  builder: (context) => SplashPage(),
                ),
              );
              //Add email verification? Show snackbar, asking to verify email, so that they can log in?
              //Send back to WelcomeScreen, or send back to a temp screen where it waits for email verification?
              context.read<AuthCheckBloc>().add(
                    const AuthCheckEvent.authCheckRequested(),
                  );
            }
          },
builder: //Sign Form UI here...
class AuthCheckBloc extends Bloc<AuthCheckEvent, AuthCheckState> {
  final AuthRepository _authRepository;

  AuthCheckBloc(this._authRepository) : super(const AuthCheckState.initial());

  @override
  Stream<AuthCheckState> mapEventToState(
    AuthCheckEvent event,
  ) async* {
    yield* event.map(
      authCheckRequested: (e) async* {
        print("auth check CALLLED");
        final bool = _authRepository.isUserSignedIn();
        if (bool) {
          yield const AuthCheckState.authenticated();
          print("yielded authenticated");
        } else {
          yield const AuthCheckState.unauthenticated();
        }
      },
      signOutPressed: (e) async* {
        String returnValue = await _authRepository.signOut();
        if (returnValue == kSuccess) {
          yield const AuthCheckState.unauthenticated();
        } else {
          print("There was an error signing out!");
        }
      },
    );
  }
question from:https://stackoverflow.com/questions/65844920/bloc-listener-not-called-when-authentication-state-is-updated

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Update: Didn't find where the issue was, so I changed my solution, had to make some sacrifices for it though.

I converted SplashPage to a Stateful widget, removed the event from SignUpPage and put the event authCheckRequested inside the SplashPage init() method, so every time my SplashPage is initialized it will perform a check and push to the appropriate screen.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...