Flutter Provider登出切换账号后显示旧用户名问题求助
Flutter切换账号后AppBar用户名不更新的解决方案
问题根源
- 登出后
UserProvider中的用户状态未重置,新登录时残留旧数据 - 仅依赖
HomePage的initState调用refreshUser,页面未完全重建时无法触发更新 - 若
FirestoreService.getUserInfo未正确获取当前登录用户的UID,会查询到旧用户的数据
解决方案
1. 修复FirestoreService的用户信息查询逻辑
确保getUserInfo基于当前登录用户的UID查询Firestore:
class FirestoreService { Future<UserModel> getUserInfo() async { final currentUser = FirebaseAuth.instance.currentUser; if (currentUser == null) { return UserModel(uid: "", name: "", username: "", imageUrl: ""); } final userDoc = await FirebaseFirestore.instance .collection('users') .doc(currentUser.uid) .get(); return userDoc.exists ? UserModel.fromMap(userDoc.data()!) : UserModel(uid: currentUser.uid, name: "", username: "", imageUrl: ""); } }
2. 让UserProvider自动监听Auth状态变化
在UserProvider中监听Firebase的authStateChanges,自动处理登录/登出的用户数据更新,无需依赖页面生命周期:
class UserProvider with ChangeNotifier { UserModel _user = UserModel(uid: "", name: "", username: "", imageUrl: ""); final FirestoreService _firestoreService = FirestoreService(); StreamSubscription? _authSubscription; UserProvider() { // 监听登录状态变化 _authSubscription = FirebaseAuth.instance.authStateChanges().listen((authUser) async { if (authUser != null) { await refreshUser(); } else { // 登出时重置用户状态 _user = UserModel(uid: "", name: "", username: "", imageUrl: ""); notifyListeners(); } }); } @override void dispose() { _authSubscription?.cancel(); super.dispose(); } UserModel get user => _user; Future<void> refreshUser() async { _user = await _firestoreService.getUserInfo(); notifyListeners(); } }
3. 简化HomePage代码
移除initState中的refreshUser调用,因为UserProvider已自动处理数据更新:
class _HomePageState extends State<HomePage> { final _authService = AuthService(); void logOut() async { await _authService.signOut(); } @override Widget build(BuildContext context) { var user = Provider.of<UserProvider>(context).user; return Scaffold( appBar: CustomAppBar( centerTitle: false, title: Text(user.name.isNotEmpty ? "Hi, ${user.name}" : "Loading..."), leading: UserPic(user: user, radius: 30.0, withStatus: false), leadingWidth: 30.0, actions: [ IconButton( splashRadius: 15.0, onPressed: logOut, icon: const Icon(Icons.search_rounded) ) ], ), ); } }
4. 确保main.dart中的页面正确重建
避免使用const修饰HomePage,保证Auth状态变化时页面能重新初始化:
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (context) => UserProvider(), child: MaterialApp( home: StreamBuilder<User?>( stream: FirebaseAuth.instance.authStateChanges(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const SplashScreen(); } return snapshot.hasData ? HomePage() : AuthPage(); }, ), ), ); } }
内容的提问来源于stack exchange,提问作者BlackCult666
相关产品推荐
相关产品推荐

