Flutter Firestore布尔值校验:登录后按用户资料状态跳转页面
解决Firestore用户资料校验及跳转逻辑问题
报错原因分析
出现external static Never _throw(Object error, StackTrace stackTrace);错误的核心原因:
- 直接将异步查询返回的
Future<bool>赋值给变量,在同步上下文里使用异步结果,导致未处理的异步异常 - 强制解包
currentUser!,若登录状态切换时出现短暂null会触发崩溃 - 未处理Firestore查询异常(如网络失败、目标文档不存在)
- 大概率存在集合名称笔误:
usersdData应为usersData
解决方案
1. 修正Firestore字段查询逻辑
封装异步查询方法,加入异常捕获与空安全处理,避免类型不安全的强转:
Future<bool> checkProfileComplete() async { try { final user = FirebaseAuth.instance.currentUser; if (user == null) return false; final doc = await FirebaseFirestore.instance .collection('usersData') // 修正集合名称 .doc(user.uid) .get(); // 文档不存在时默认视为资料未完成 if (!doc.exists) return false; // 类型安全的取值方式,不存在则返回false return doc.data()?['complete'] ?? false; } catch (e) { print('查询用户资料状态失败: $e'); return false; } }
2. 修改MainPage的StreamBuilder逻辑
在监听Auth状态的StreamBuilder中嵌套FutureBuilder,根据查询结果跳转对应页面:
class MainPage extends StatelessWidget { @override Widget build(BuildContext context) { return StreamBuilder<User?>( stream: FirebaseAuth.instance.authStateChanges(), builder: (context, authSnapshot) { if (authSnapshot.connectionState == ConnectionState.waiting) { return const Scaffold(body: Center(child: CircularProgressIndicator())); } final user = authSnapshot.data; if (user == null) { return LoginPage(); // 未登录返回登录页 } // 已登录后查询资料完成状态 return FutureBuilder<bool>( future: checkProfileComplete(), builder: (context, profileSnapshot) { if (profileSnapshot.connectionState == ConnectionState.waiting) { return const Scaffold(body: Center(child: CircularProgressIndicator())); } final isComplete = profileSnapshot.data ?? false; return isComplete ? DashboardPage() : CreateProfile1Page(); }, ); }, ); } }
3. 额外优化建议
- 确保在
CreateProfile1页面完成资料后,正确将Firestore文档的complete字段更新为true - 可为FutureBuilder添加错误分支,查询失败时显示重试按钮
- 避免在build方法中直接调用
checkProfileComplete(),可使用FutureProvider或StatefulWidget缓存Future,防止重复触发查询
内容的提问来源于stack exchange,提问作者Maniak
相关产品推荐
相关产品推荐

