【问题标题】:Bloc listener not called when authentication state is updated?更新身份验证状态时未调用 Bloc 侦听器?
【发布时间】:2021-04-26 21:45:00
【问题描述】:

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

在注册页面内,如果我成功注册 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!");
        }
      },
    );
  }

【问题讨论】:

    标签: flutter dart bloc flutter-bloc


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 2021-05-10
      • 1970-01-01
      • 1970-01-01
      • 2012-09-15
      • 2018-10-17
      • 2021-03-19
      • 1970-01-01
      • 2017-11-04
      • 1970-01-01
      相关资源
      最近更新 更多