登出时如何销毁StreamBuilder的值,保证各登录用户仅查看自身专属资料
问题核心原因
你现在的故障是两个错误共同导致的:
- 你提前将
uid和对应的Firestore查询Stream定义为了固定的final常量,这两个值只会在页面第一次初始化的时候赋值一次,后续切换账号重新进入页面时,不会重新获取新登录用户的uid生成新的查询流,导致要么继续监听旧用户的数据流,要么缓存的旧数据没有被清除。 - 登出逻辑没有清空路由栈和Firestore本地缓存,旧的页面实例和缓存数据会残留,导致新用户登录后仍然读取到旧数据。
解决步骤
1. 调整Stream的生成逻辑
不需要手动销毁StreamBuilder内部的值,你只要把固定的Stream改为动态生成即可:StreamBuilder会自动检测到stream参数变化,自动销毁旧的流订阅、监听新的流。
不要提前定义固定的db Stream变量,每次构建StreamBuilder时根据当前最新的登录用户动态生成查询流,修改后的代码示例:
Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('First name'), SizedBox(width: 40), StreamBuilder<DocumentSnapshot>( // 动态根据当前登录用户生成stream,不要用提前定义的固定db变量 stream: FirebaseAuth.instance.currentUser == null ? const Stream.empty() : FirebaseFirestore .instance .collection('users') .doc(FirebaseAuth.instance.currentUser!.uid) .collection('Profile') .doc('Personal details') .snapshots(), builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) { if (snapshot.hasError) return Text('Something went wrong'); if (snapshot.connectionState == ConnectionState.waiting || !snapshot.hasData) { return CircularProgressIndicator(); } dynamic data = snapshot.data!.data(); return Text(data['First name']); }, ), ] )
另一个显示Last name的StreamBuilder做同样的修改即可。
2. 优化登出逻辑
修改登出代码,增加清空Firestore本地缓存、清空路由栈的逻辑,避免旧数据和旧页面残留:
onPressed: () async { try { await FirebaseAuth.instance.signOut(); // 清空Firestore本地缓存,删除旧用户的本地数据副本 await FirebaseFirestore.instance.clearPersistence(); errorMessage = ''; } on FirebaseAuthException catch (error) { errorMessage = error.message!; } // 清空所有旧路由,直接回到登录页,避免旧页面残留 Navigator.of(context).pushNamedAndRemoveUntil('/signIn', (route) => false); }
内容的提问来源于stack exchange,提问作者reeco
相关产品推荐
相关产品推荐

