使用Firebase Auth登出触发权限拒绝错误的解决求助
Firebase Auth登出后触发Firebase Database权限拒绝错误的解决方法
我在使用Firebase Auth执行登出操作时遇到了权限拒绝错误,相关代码及错误信息如下:
登出代码
onPressed: () async { await FirebaseAuth.instance.signOut(); await widget.checkLogin(); },
CheckLogin函数
checkLogin() async { if (FirebaseAuth.instance.currentUser != null) { login = true; setState(() {}); } else { login = false; setState(() {}); } }
错误信息
Unhandled Exception: [firebase_database/permission-denied] Client doesn't have permission to access the desired data.
经过排查,问题出在以下代码片段,但我不知道如何修复:
if (FirebaseAuth.instance.currentUser != null) { WidgetsBinding.instance.addPostFrameCallback((_) async { DatabaseReference ref = FirebaseDatabase.instance.ref("temp"); if (FirebaseAuth.instance.currentUser != null) { ref.onValue.listen((DatabaseEvent event) { final snapshot = event.snapshot.value; if (snapshot != null) { Object? temp = snapshot; if (mounted) { setState(() {}); } } }); } }); }
问题根源
你添加的ref.onValue.listen是一个实时监听,用户登出后这个监听并不会自动停止。当Firebase Auth身份凭证失效后,监听仍会尝试请求temp节点数据,触发数据库权限校验,最终导致权限拒绝错误。
修复步骤
- 保存监听订阅对象:创建监听时,把返回的
StreamSubscription对象保存下来,用于后续取消操作。 - 登出时主动取消监听:执行
signOut前先取消监听,避免无权限请求继续发送。 - 组件销毁时取消监听:防止内存泄漏,同时避免组件销毁后监听仍运行引发错误。
修改后的代码示例
首先在State类中添加订阅变量:
StreamSubscription<DatabaseEvent>? _tempSubscription;
修改监听代码,保存订阅对象:
if (FirebaseAuth.instance.currentUser != null) { WidgetsBinding.instance.addPostFrameCallback((_) async { DatabaseReference ref = FirebaseDatabase.instance.ref("temp"); if (FirebaseAuth.instance.currentUser != null) { _tempSubscription = ref.onValue.listen((DatabaseEvent event) { final snapshot = event.snapshot.value; if (snapshot != null) { Object? temp = snapshot; if (mounted) { setState(() {}); } } }); } }); }
更新登出方法,先取消监听:
onPressed: () async { _tempSubscription?.cancel(); _tempSubscription = null; await FirebaseAuth.instance.signOut(); await widget.checkLogin(); },
最后在组件销毁时补充取消逻辑(推荐):
@override void dispose() { _tempSubscription?.cancel(); super.dispose(); }
额外提示
- 你的数据库规则限制认证用户访问
temp节点是合理的安全设置,无需修改规则。 - 不要仅依赖
currentUser != null的判断避免错误,异步场景下身份状态可能在判断后变化,主动取消监听才是可靠方案。
内容的提问来源于stack exchange,提问作者Jonathan
相关产品推荐
相关产品推荐

