Flutter登录后获取Firestore数据完成前暂不展示HomeScreen问题
问题核心原因
- 你在
GoogleSignInProvider的getUserData方法中错误使用了FutureBuilder:FutureBuilder是Flutter的视图组件,仅能在Widget树的build方法中使用,你在逻辑层返回的FutureBuilder不会被框架执行,因此首次创建用户文档后,读取数据并存入UserManager的逻辑根本没有运行,首页读取空的UserManager.userdata就会报错。热重载后数据已经写入Firestore,其他位置的读取逻辑触发后才会正常加载。 FutureBuilder的状态判断逻辑写错:你用userDataSnapshot.data == ConnectionState.done判断状态是完全错误的,ConnectionState需要从userDataSnapshot.connectionState获取。- 登录按钮调用异步方法
googleLogin时没有加await,可能登录和数据加载流程未完成就跳转首页。
修复方案
1. 重构getUserData方法,移除逻辑层的Widget代码
直接用异步await完成用户存在判断、文档创建、数据读取存储的全流程:
Future<void> getUserData() async { final myUser = FirebaseAuth.instance.currentUser; if (myUser == null) return; bool userExist = await checkIfUserExists(myUser.uid); if (!userExist) { print('User dont exist'); await FirebaseFirestore.instance.collection('users').doc(myUser.uid).set({ "email": myUser.email, "plans": [], "userScore": "100", }); } else { print('User exist'); } // 直接await读取文档数据,存入静态类 final userDoc = await FirebaseFirestore.instance.collection('users').doc(myUser.uid).get(); UserManager.userdata = userDoc.data(); }
2. 调整googleLogin的通知时机
确保所有异步逻辑执行完成后再通知监听者刷新:
Future googleLogin() async { try { final googleUser = await googleSignIn.signIn(); if (googleUser == null) return; _user = googleUser; final googleAuth = await googleUser.authentication; final credential = GoogleAuthProvider.credential( accessToken: googleAuth.accessToken, idToken: googleAuth.idToken, ); await FirebaseAuth.instance.signInWithCredential(credential); // 等待用户数据全部加载完成 await getUserData(); // 加载完成后再通知刷新 notifyListeners(); // 这里可以加跳转首页的逻辑,或者等上层监听登录状态后跳转 } catch (e) { print(e.toString()); // 出错也要通知,处理错误提示 notifyListeners(); } }
3. 修改登录按钮点击逻辑
异步调用登录方法,可增加加载态防止重复点击:
ElevatedButton.icon( onPressed: () async { // 可选:弹出加载对话框 showDialog(context: context, barrierDismissible: false, builder: (ctx)=> AlertDialog(content: LinearProgressIndicator())); final provider = Provider.of<GoogleSignInProvider>(context, listen: false); await provider.googleLogin(); // 关闭加载对话框 Navigator.pop(context); // 登录成功后跳转首页 if (FirebaseAuth.instance.currentUser != null) { Navigator.pushReplacement(context, MaterialPageRoute(builder: (ctx)=> HomeScreen())); } }, icon: Icon(MdiIcons.google), label: Text( 'Sign In with Google', style: TextStyle(fontSize: 16), ), ),
4. 可选优化:首页直接用StreamBuilder监听用户文档
避免静态类数据更新不及时的问题,稳定性更高:
StreamBuilder<DocumentSnapshot>( stream: FirebaseFirestore.instance.collection('users').doc(FirebaseAuth.instance.currentUser.uid).snapshots(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); } if (snapshot.hasError || !snapshot.hasData) { return Center(child: Text('加载用户数据失败')); } final userData = snapshot.data.data() as Map<String,dynamic>; // 用userData渲染页面 return ...; } )
内容的提问来源于stack exchange,提问作者Dalon
相关产品推荐
相关产品推荐

