更新身份验证状态时未调用 Bloc 侦听器?

时间:2021-01-22 12:08:52

标签: flutter dart bloc flutter-bloc

任何帮助将不胜感激,我不知道问题出在哪里。我有一个基于 AuthCheckState 的启动页面,如果用户已注册,他将被推送到主屏幕或注册/欢迎屏幕。

在 SignUp 页面内时,如果我成功注册 Firebase,我的 SignInForm 侦听器将被触发,并且用户会被推回到 SplashScreen 并且一个新的 authCheckEvent 被发送到我的 AuthCheck 块。

我的 AuthCheck 块然后产生更新的状态(已验证),但不会调用 SplashPage 内的侦听器。

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!");
        }
      },
    );
  }

1 个答案:

答案 0 :(得分:0)

更新:没有找到问题出在哪里,所以我改变了我的解决方案,但不得不为此做出一些牺牲。

我将 SplashPage 转换为有状态小部件,从 SignUpPage 中删除事件并将事件 authCheckRequested 放在 SplashPage init() 方法中,因此每次我的 SplashPage 初始化时,它都会执行检查并推送到适当的屏幕。