Flutter Riverpod项目中ConsumerWidget无法检测登录状态变更
问题原因分析
核心问题是登录/登出操作完成后,手动将state设置为AsyncValue.data(null),覆盖了Firebase Auth状态流触发的正确用户状态更新:
- 点击登录后,
signIn方法先将state设为AsyncLoading(),随后通过AsyncValue.guard执行登录逻辑,最后返回null,导致state被强制设置为AsyncValue.data(null)。 - 与此同时,Firebase Auth的
authUserProvider状态流会因登录成功更新为已登录用户,但signIn方法的最后一步直接覆盖了这个正确的状态更新,所以页面回到登录表单。 - 重启应用时,
build方法(或构造函数)会监听authUserProvider,此时Firebase Auth已持久化登录状态,状态流直接发出已登录用户,页面因此正常显示。
修复方案
移除signIn和signOut方法中手动设置state的逻辑,让authUserProvider的状态流自动驱动state更新即可。以下是针对AsyncNotifier版本的修改:
/// サインインする Future<void> signIn({ required String email, required String password, }) async { final authRepository = ref.watch(authRepositoryImplProvider); try { await authRepository.signIn( email: email, password: password, ); } on FirebaseAuthException catch (e) { debugPrint(e.code); // 如需处理错误,可在这里更新state为错误状态 state = AsyncValue.error(e, StackTrace.current); } } Future<void> signOut() async { final authRepository = ref.watch(authRepositoryImplProvider); try { await authRepository.signOut(); } on FirebaseAuthException catch (e) { debugPrint(e.code); state = AsyncValue.error(e, StackTrace.current); } }
原理说明
登录/登出操作只需调用Firebase Auth的API,authUserProvider会自动监听Firebase Auth的状态变化并更新。AppUserInfoModelNotifier通过ref.listen监听authUserProvider,当Firebase Auth状态变化时,会自动更新state,从而驱动UI刷新。
若需要在登录过程中显示loading状态,可直接监听authUserProvider的loading状态,无需手动设置state。
内容的提问来源于stack exchange,提问作者tbt
相关产品推荐
相关产品推荐

