更新身份验证状态时未调用 Bloc 侦听器?
Posted
技术标签:
【中文标题】更新身份验证状态时未调用 Bloc 侦听器?【英文标题】:Bloc listener not called when authentication state is updated? 【发布时间】: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!");
,
);
【问题讨论】:
【参考方案1】:更新:没有找到问题所在,所以我改变了我的解决方案,但不得不为此做出一些牺牲。
我将 SplashPage 转换为 Stateful 小部件,从 SignUpPage 中删除事件并将事件 authCheckRequested 放入 SplashPage init() 方法中,因此每次初始化 SplashPage 时,它都会执行检查并推送到相应的屏幕。
【讨论】:
以上是关于更新身份验证状态时未调用 Bloc 侦听器?的主要内容,如果未能解决你的问题,请参考以下文章
在块中调用时未发出 CLLocationManager 身份验证请求
Flutter Bloc 状态更改未使用 get_it 更新 UI
使用 BLoC 进行 Flutter Firebase 电话身份验证