Flutter中initState读取Firestore数据延迟导致管理员校验跳转错误
问题原因
checkIfAdmin是异步方法,执行时不会阻塞页面渲染流程,页面初始化时isAdmin默认值为false,因此第一帧必然会渲染notAdmin组件,等Firestore查询完成触发setState后才会重新渲染为HomeScreen,就出现了先跳错页再切回的问题。
解决方法
新增一个加载状态标识,权限校验未完成时先渲染加载占位组件,等校验结束后再渲染对应页面,同时补充边界情况处理避免崩溃,修改后的代码如下:
class AdminCheck extends StatefulWidget { const AdminCheck({Key? key}) : super(key: key); @override State<AdminCheck> createState() => _AdminCheckState(); } class _AdminCheckState extends State<AdminCheck> { User? user = FirebaseAuth.instance.currentUser; bool isAdmin = false; // 新增加载状态标识,默认处于校验中 bool _isCheckingPermission = true; @override void initState() { checkIfAdmin(); super.initState(); } @override Widget build(BuildContext context) { // 校验未完成时返回加载组件,避免闪错页 if (_isCheckingPermission) { return const Scaffold( body: Center(child: CircularProgressIndicator()), ); } if (isAdmin) { countDocuments(); return const HomeScreen(); } else { return const NotAdmin(); } } Future<void> checkIfAdmin() async { // 处理用户未登录的边界情况,避免空值崩溃 if (user == null) { setState(() => _isCheckingPermission = false); return; } try { DocumentSnapshot currentUser = await FirebaseFirestore.instance .collection('Administrator') .doc(user!.email) .get(); if (currentUser.exists) { print("当前用户是管理员"); setState(() => isAdmin = true); } else { print("当前用户不是管理员"); } } catch (e) { // 可自行扩展异常处理逻辑,比如网络错误提示 print("权限校验失败: $e"); } finally { // 无论校验成功失败,都结束加载状态 setState(() => _isCheckingPermission = false); } } }
额外优化建议
- 按照Dart官方规范,类名统一使用大驼峰命名,建议将你原有的
adminCheck、notAdmin等类名调整为AdminCheck、NotAdmin - 如果不想显示加载指示器,可以在用户登录成功后就提前发起管理员权限校验,把结果存在全局状态(比如Provider、GetX)里,跳转当前页面时直接读取缓存的状态,就不会有等待延迟
内容的提问来源于stack exchange,提问作者Cypher
相关产品推荐
相关产品推荐

