Flutter Firebase注册后跳转MainPage时displayName返回null报错如何解决
问题核心原因
你遇到的问题是authStateChanges()流的触发机制限制导致的:
authStateChanges()仅会在用户登录状态发生切换(登录成功、登出、用户token过期刷新)时才会推送新的用户事件- 你调用
updateDisplayName修改用户资料、再调用reload刷新本地用户信息的操作,不会触发authStateChanges()产生新事件 - 你注册流程执行顺序是:调用
createUserWithEmailAndPassword成功 →authStateChanges立刻推送了刚创建、还没更新displayName的用户对象到全局 → 你再执行updateDisplayName+reload更新了本地用户信息,但全局监听的流没有收到新事件,所以MainPage读取到的还是旧的空displayName的用户数据 - 重载应用或者重新登录时,Firebase会重新拉取最新的用户完整信息,所以此时
displayName读取正常
解决方案
方案1(最简单,推荐):替换流监听方法
把authStateChanges替换为Firebase Auth提供的userChanges()方法,该方法除了监听登录状态变化外,还会监听用户资料的更新事件,修改后你更新displayName的操作会自动触发流推送新的用户数据:
// 原代码 Stream<UserModel?>? get user { return _firebaseAuth.authStateChanges().map(_userFromFirebase); } // 修改后 Stream<UserModel?>? get user { return _firebaseAuth.userChanges().map(_userFromFirebase); }
方案2:注册完成后手动传值
因为你的createUserWithEmailAndPassword方法最终返回的已经是更新完displayName的正确UserModel对象,你可以在注册成功跳转MainPage时,直接把这个返回的UserModel作为参数传递给MainPage使用,不需要依赖全局流的初始值。
方案3:在Provider内手动维护用户状态
在你的AuthServiceProvider中新增本地用户状态变量,更新完用户资料后手动更新状态并通知监听:
class AuthServiceProvider extends ChangeNotifier { final auth.FirebaseAuth _firebaseAuth = auth.FirebaseAuth.instance; final googleSingIn = GoogleSignIn(); // 新增本地用户状态缓存 UserModel? _currentUser; UserModel? _userFromFirebase(auth.User? user) { if (user == null) { return null; } return UserModel( user.displayName, user.uid, user.email, ); } Stream<UserModel?>? get user { return _firebaseAuth.authStateChanges().map((user) { _currentUser = _userFromFirebase(user); return _currentUser; }); } Future<UserModel?> createUserWithEmailAndPassword( String name, String email, String password, ) async { try { final userCred = await _firebaseAuth.createUserWithEmailAndPassword( email: email, password: password, ); auth.User? firebaseUser = _firebaseAuth.currentUser; if (firebaseUser != null) { await firebaseUser.updateDisplayName(name); await firebaseUser.reload(); firebaseUser = _firebaseAuth.currentUser; // 手动更新本地状态并通知监听 _currentUser = _userFromFirebase(firebaseUser); notifyListeners(); } print('FIREBASE USER IS $firebaseUser'); return _currentUser; } catch (e) { print(e.toString()); return null; } } }
内容的提问来源于stack exchange,提问作者TonyWyomy
相关产品推荐
相关产品推荐

