You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 03:06:01