手动删除Firebase用户账户后,重启应用仍存旧数据如何解决?
解决Firebase Phone Auth删除账户后本地仍保留用户信息的问题
问题场景
使用flutter_bloc结合Firebase实现手机认证(phone auth)功能时,遇到异常:手动在Firebase Auth后台删除用户账户后,重启应用时FirebaseAuth.instance.currentUser仍返回已删除的用户信息,而Firebase后台已无该用户记录。
相关代码
class AuthCubit extends Cubit<AuthState> { final FirebaseAuth _auth = FirebaseAuth.instance; AuthCubit() : super(AuthInitialState()) { User? currentUser = _auth.currentUser; print("The current user is $currentUser"); print("the current user's uid is : ${currentUser?.uid}"); print("The current user is ${currentUser?.phoneNumber}"); } }
运行输出
I/flutter (11633): The current user is User(displayName: , email: , emailVerified: false, isAnonymous: false, metadata: UserMetadata(creationTime: 2023-01-21 06:10:04.712Z, lastSignInTime: 2023-01-21 06:10:04.713Z), phoneNumber: +919535334951, photoURL: null, providerData, [UserInfo(displayName: , email: , phoneNumber: +91XXXXXXXX, photoURL: null, providerId: phone, uid: )], refreshToken: , tenantId: null, uid: JhSqO5pZsMbp3vgZA6s1WqjKTU63) I/flutter (11633): the current user's uid is : JhSqO5pZsMbp3vgZA6s1WqjKTU63 I/flutter (11633): The current user is +91XXXXXXXX
解决方案
这是因为Firebase Auth会在本地缓存用户会话信息,后台删除用户后本地缓存不会自动同步失效状态,需主动验证用户有效性:
1. 启动时强制刷新用户状态验证
获取currentUser后,调用reload()强制从服务器拉取最新用户状态,若用户已被删除,该方法会抛出异常,此时清除本地会话:
class AuthCubit extends Cubit<AuthState> { final FirebaseAuth _auth = FirebaseAuth.instance; AuthCubit() : super(AuthInitialState()) { _checkCurrentUser(); } Future<void> _checkCurrentUser() async { User? currentUser = _auth.currentUser; if (currentUser != null) { try { // 强制从服务器刷新用户信息 await currentUser.reload(); // 重新获取刷新后的用户数据 currentUser = _auth.currentUser; if (currentUser == null) { emit(AuthUnauthenticatedState()); } else { emit(AuthenticatedState(user: currentUser)); } } catch (e) { // 刷新失败,说明用户已被删除,登出清除本地缓存 await _auth.signOut(); emit(AuthUnauthenticatedState()); } } else { emit(AuthUnauthenticatedState()); } } }
2. 监听Auth状态实时同步
通过authStateChanges()或idTokenChanges()监听用户状态变化,后台用户被删除时本地会及时收到状态更新:
class AuthCubit extends Cubit<AuthState> { final FirebaseAuth _auth = FirebaseAuth.instance; StreamSubscription? _authSubscription; AuthCubit() : super(AuthInitialState()) { _listenToAuthChanges(); } void _listenToAuthChanges() { _authSubscription = _auth.authStateChanges().listen((User? user) { if (user != null) { _verifyUserValidity(user); } else { emit(AuthUnauthenticatedState()); } }); } Future<void> _verifyUserValidity(User user) async { try { await user.reload(); final refreshedUser = _auth.currentUser; if (refreshedUser == null) { emit(AuthUnauthenticatedState()); } else { emit(AuthenticatedState(user: refreshedUser)); } } catch (e) { await _auth.signOut(); emit(AuthUnauthenticatedState()); } } @override Future<void> close() { _authSubscription?.cancel(); return super.close(); } }
3. 强制刷新ID令牌验证
使用getIdToken(true)强制刷新令牌,若用户已被删除,该方法会抛出异常,以此判断用户有效性:
Future<bool> _isUserValid(User user) async { try { await user.getIdToken(true); return true; } catch (e) { return false; } }
启动时调用此方法,返回false则执行signOut()清除本地缓存。
内容的提问来源于stack exchange,提问作者Master Techie
相关产品推荐
相关产品推荐

