颤振应用程序组侦听器未接收状态更新



我使用flutter Bloc将用户导航到登录页面或主屏幕,具体取决于他们是否经过身份验证。但是,在初始状态更改之后,当我更改身份验证状态时,侦听器不会触发。

侦听器:

Widget build(BuildContext context) {
return BlocListener<AuthenticationBloc, AuthenticationState>(
listener: (context, state) {
// Listener never gets called on statechange after the initial app startup
// navigation based on authentication 
}
},
child: SplashPage(),
);
}

提供者在父小部件中初始化:

AuthenticationRepository authRepo = AuthenticationRepository();
Widget build(BuildContext context) {
return MultiBlocProvider(
providers: [
BlocProvider<AuthenticationBloc>(
create: (BuildContext context) =>
AuthenticationBloc(authenticationRepository: authRepo),
),
/*
Other Providers
*/
],
child: MaterialApp(
title: 'myApp',
home: StartUpPage(),
),
);

当用户登录mapEventState在AuthenticationBloc中被调用时:

class AuthenticationBloc
extends Bloc<AuthenticationEvent, AuthenticationState> {
AuthenticationBloc({
@required AuthenticationRepository authenticationRepository,
})  : assert(authenticationRepository != null),
_authenticationRepository = authenticationRepository,
super(const AuthenticationState.unknown()) {
_userSubscription = _authenticationRepository.userStream.listen(
(user) => add(AuthenticationUserChanged(user)),
);
}
final AuthenticationRepository _authenticationRepository;
StreamSubscription<User> _userSubscription;
@override
Stream<AuthenticationState> mapEventToState(
AuthenticationEvent event,
) async* {
if (event is AuthenticationUserChanged) {
yield _mapAuthenticationUserChangedToState(event);
} else if (event is AuthenticationLogoutRequested) {
unawaited(_authenticationRepository.logOut());
}
}
@override
Future<void> close() {
_userSubscription?.cancel();
return super.close();
}
AuthenticationState _mapAuthenticationUserChangedToState(
AuthenticationUserChanged event,
) =>
event.user != User.empty
? AuthenticationState.authenticated(event.user)
: const AuthenticationState.unauthenticated();
}

我希望侦听器在用户登录和AuthenticationState更改时触发。如果有人知道我做错了什么,或者我错过了什么,我很乐意听到。

编辑08-02-2021:

我再次检查如果状态改变后登录使用一个简单的按钮。这样,我就可以确认状态确实发生了变化,并保留了正确的用户数据和身份验证状态。我确认的另一件事是使用blocbuilderauthenticationbloc authenticationstate的BlocBuilder;当用户登录时正确更新

编辑10-02-2021:

整个认证状态:

enum AuthenticationStatus { authenticated, unauthenticated, unknown }
class AuthenticationState extends Equatable {
const AuthenticationState._({
this.status = AuthenticationStatus.unknown,
this.user = User.empty,
});
const AuthenticationState.unknown() : this._();
const AuthenticationState.authenticated(User user)
: this._(status: AuthenticationStatus.authenticated, user: user);
const AuthenticationState.unauthenticated()
: this._(status: AuthenticationStatus.unauthenticated, user: User.empty);
final AuthenticationStatus status;
final User user;
@override
List<Object> get props => [status, user];
}

编辑12-02-2021:

删除不相关代码

编辑15-02-2021:

添加了整个Authentication BloC

您可以列出您的整个小部件树吗?

我想知道如果你的第一个小部件(一个包含Listener)实际上并没有被渲染(说,因为你有一个if/else在树的某个地方,这意味着它实际上并没有显示在事件被触发)。

您可以使用Flutter检查器检查这一点。否则,它是否在相同的BuildContext中运行?

如果您显示了整个小部件树,这将更容易诊断。

在没有看到BLoC的情况下很难判断,但是否有可能在发出状态之后创建侦听器。请记住,Listener不会触发最后一个状态,只会触发创建侦听器后发出的状态。

请分享BLoC代码。

看起来您的AuthenticationRepository发送AuthenticationEvent监听_authenticationRepository.userStream。我认为问题在于您创建了AuthenticationRepository的实例之前的AuthenticationBloc,这可能导致AuthenticationStatus在集团开始听它之前改变它

如果你能提供AuthenticationRepository就更好了代码。

最新更新