在BlocListener发生之前,Flutter中的状态已更新

iszxjhcz  于 2022-12-14  发布在  Flutter
关注(0)|答案(1)|浏览(135)

在小部件树的顶部,我有一个带有“lazy:False”参数(authCubit),使用该参数,我可以立即监听auth更改。
我也有一个登录页面,它使用的正是BlocListener。问题是,首先状态从firebase auth返回false(用户为null),然后它将返回true(用户为firebase用户)。因此,BlocListener不监听状态,什么也不做。我试图用“listenWhen”属性捕捉它,但我做不到。
我还检查了当应用程序重新启动时,用户不为空,它作为FirebaseUser出现。
在具有相关blocListener的landingPage中,我尝试使用WidgetsBinding.instance.addPostFrameCallback来控制状态,但我无法处理它。

late StreamSubscription<AuthUserModel>? _authUserSubscription;

_authUserSubscription = _authService.authStateChanges.listen(_listenAuthStateChangesStream);

  Future<void> _listenAuthStateChangesStream(AuthUserModel authUser) async {
    emit(state.copyWith(isInProgress: true));

    if (AuthUserModel.empty() == authUser) {
      emit(
        state.copyWith(
          authUser: authUser,
          isUserLoggedIn: false,
          isInProgress: false,
        ),
      );
    } else {
      await _chatService.connectTheCurrentUser();

      emit(
        state.copyWith(
          authUser: authUser,
          isUserLoggedIn: true,
          isInProgress: false,
        ),
      );
    }
  }

以及我的基础架构层,

@override
  Stream<AuthUserModel> get authStateChanges {
    return _firebaseAuth.authStateChanges().map(
      (User? user) {
        if (user == null) {
          return AuthUserModel.empty();
        } else {
          return user.toDomain();
        }
      },
    );
  }

所以,你可以问你如何使用blocProvider和bloclistener。
小部件树顶部的BlocProvider:

BlocProvider(
          lazy: false,
          create: (context) => getIt<AuthCubit>(),
          
      
      child: Listener(
        onPointerUp: (_) {
          if (Platform.isIOS) {
            final FocusScopeNode currentFocus = FocusScope.of(context);
            if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
              FocusManager.instance.primaryFocus!.unfocus();
            }
          }
        },
        child: MaterialApp.router(...

最后,在这里使用BlocListener:

@override
  Widget build(BuildContext context) {
    return BlocListener<AuthCubit, AuthState>(
      listener: (context, state) {
        if (state.isUserLoggedIn) {
          context.go(context.namedLocation("channels_page"));
        } else {
          context.go(context.namedLocation("sign_in_page"));
        }
      },
      child: const Scaffold(
        body: Center(
          child: CustomProgressIndicator(
            progressIndicatorColor: Colors.black,
          ),
        ),
      ),
    );
6kkfgxo0

6kkfgxo01#

我刚刚检查了用户是否从auth服务进行了检查。这样,由于我们在BlocListener之前更新了我们的状态,我们可以在BlocListener之后检查我们的状态是什么。然后,我们可以使用BlocListener发生之前和发生之后的确切状态信息来做一些事情。

listenWhen: (p, c) =>
      p.isUserCheckedFromAuthService != c.isUserCheckedFromAuthService &&
      c.isUserCheckedFromAuthService,

所以,相关函数是这样的:

Future<void> _listenAuthStateChangesStream(AuthUserModel authUser) async {
    emit(
      state.copyWith(
        isInProgress: true,
        authUser: authUser,
        isUserCheckedFromAuthService: true,
      ),
    );

    if (state.isLoggedIn) {
      await _chatService.connectTheCurrentUser();

      emit(
        state.copyWith(
          authUser: authUser,
          isInProgress: false,
        ),
      );
    }
  }

相关问题