Flutter Firebase Firestore切换登录用户后无法获取新用户文档
问题分析
你遇到的核心问题是:初始创建的Firestore流只绑定了第一个登录用户的文档,用户切换登录状态后,流没有自动切换到新用户的文档。
原代码的问题在于:getCurrentUserMap()方法仅在被调用时获取一次_auth.currentUser,之后生成的流会一直监听该用户的文档,完全没有响应后续的Auth状态变化。你尝试的authStateChanges用法也不正确——listen是异步操作,返回流时currUser还是旧值,且没有实现流的切换逻辑。
解决方案
核心思路是用switchMap将Auth状态流转换成Firestore用户文档流:当Auth状态变化(用户登录/注销/切换)时,自动取消旧的Firestore流,创建并监听新用户的文档流。
1. 修正UserModel的流生成逻辑
class UserModel { final FirebaseFirestore _db = FirebaseFirestore.instance; final FirebaseAuth _auth = FirebaseAuth.instance; Stream<Map<String, dynamic>?> getCurrentUserMap() { // 监听Auth状态变化,自动切换Firestore流 return _auth.authStateChanges().switchMap((User? user) { if (user == null) { // 用户注销时,返回空值流 return Stream.value(null); } else { // 用户登录时,返回该用户的文档快照流 return _db.collection('users').doc(user.uid).snapshots().map((docSnap) { return docSnap.data(); }); } }); } }
switchMap的作用:每当authStateChanges发出新的用户(或null),会立即取消之前的Firestore流,生成并返回新的流,实现自动切换监听目标。- 移除了强制解包操作,避免空指针异常,同时处理了用户未登录的场景。
2. 调整StreamProvider配置
StreamProvider<Map<String, dynamic>?>( create: (context) => UserModel().getCurrentUserMap(), initialData: null, // 或根据需求设为const {} )
- 泛型改为
Map<String, dynamic>?,匹配流的返回类型,兼容用户未登录的状态。
关键注意点
- 确保Firebase Auth的状态监听正常工作:用户登录/注销/切换账号时,
authStateChanges必须能触发新的事件。 - 在UI层消费Provider时,要处理
null的情况(比如用户未登录时显示登录界面)。 - 如果需要监听用户文档的实时更新,当前的
snapshots()已经满足需求,无需额外修改。
内容的提问来源于stack exchange,提问作者burgerboy
相关产品推荐
相关产品推荐

