Flutter切换账号后UserProvider未根据pending值更新UI问题
问题原因
- UserProvider中userid未动态更新:
String userid = Auth().currentUser!.uid;是在类实例化时赋值的,切换账号后这个值不会自动更新为新用户的UID,导致fetchUser仍获取旧用户的数据。 - 注销后状态未重置:注销账号时,UserProvider的
_user没有被重置为null,UI仍会显示旧用户的pending状态。 - 新登录后未触发数据刷新:切换账号登录后,没有主动调用
fetchUser获取新用户的Firestore数据。
解决方案
1. 修改UserProvider代码
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; import 'package:our_voice/modules/user.dart'; import 'package:our_voice/services/auth.dart'; class UserProvider extends ChangeNotifier { User? _user; User? get user => _user; // 改为动态获取当前用户UID String get userid => Auth().currentUser?.uid ?? ''; Future<void> fetchUser() async { if (userid.isEmpty) return; final snapshot = await FirebaseFirestore.instance.collection('users').doc(userid).get(); _user = User.fromFirestore(snapshot); notifyListeners(); } // 添加重置用户状态的方法,注销时调用 void resetUser() { _user = null; notifyListeners(); } }
2. 处理注销逻辑
在执行注销操作的地方,调用UserProvider的resetUser方法:
// 示例注销按钮逻辑 ElevatedButton( onPressed: () async { await Auth().signOut(); // 获取UserProvider实例并重置状态 Provider.of<UserProvider>(context, listen: false).resetUser(); // 跳转到登录页等后续操作 }, child: const Text('注销'), )
3. 新登录后触发数据刷新
在登录成功后,调用fetchUser获取新用户数据:
// 示例登录成功后的逻辑 await Auth().signInWithEmailAndPassword(email, password); // 获取UserProvider实例并刷新用户数据 Provider.of<UserProvider>(context, listen: false).fetchUser(); // 跳转到MainPage
4. 可选优化:监听Auth状态自动刷新
如果希望自动监听用户登录/注销状态并更新数据,可以在UserProvider中添加监听:
class UserProvider extends ChangeNotifier { User? _user; User? get user => _user; StreamSubscription? _authSubscription; UserProvider() { // 监听Auth状态变化,自动更新用户数据 _authSubscription = Auth().authStateChanges.listen((firebaseUser) { if (firebaseUser != null) { fetchUser(); } else { resetUser(); } }); } @override void dispose() { _authSubscription?.cancel(); super.dispose(); } Future<void> fetchUser() async { final uid = Auth().currentUser?.uid; if (uid == null) return; final snapshot = await FirebaseFirestore.instance.collection('users').doc(uid).get(); _user = User.fromFirestore(snapshot); notifyListeners(); } void resetUser() { _user = null; notifyListeners(); } }
添加此监听后,用户登录/注销时,UserProvider会自动触发数据刷新,无需手动调用fetchUser或resetUser。
验证效果
- 注销账号:UserProvider的
_user被重置为null,MainPage的悬浮按钮会显示空Container。 - 用另一个账号登录:UserProvider会获取新用户的Firestore数据,
pending值更新后,UI会根据新值渲染对应的悬浮按钮。
内容的提问来源于stack exchange,提问作者Aymen Ziouche
相关产品推荐
相关产品推荐

