Flutter中Firebase用户空值判断及加载状态异常问题排查
问题分析与解决方案
核心问题
login函数无返回值:你的login函数没有返回用户对象,导致User? user = await _auth.login(...)始终为null,因此setState会一直把loading设为false。- 跳转时机错误:登录成功后直接在
login函数内跳转页面,当前页面的setState根本没有执行机会。 - loading状态更新时机颠倒:应该在发起登录请求前就显示加载指示器,请求结束后再隐藏。
修复步骤
1. 修正login函数,添加返回值
修改login函数,成功时返回用户对象,失败时返回null,并移除内部的跳转逻辑:
Future<User?> login(String email, String password, BuildContext context) async { try { final userCredential = await _auth.signInWithEmailAndPassword( email: email, password: password, ); return userCredential.user; } on FirebaseAuthException catch (error) { String message = ''; switch (error.code) { case 'user-not-found': message = '用户不存在'; break; case 'wrong-password': message = '密码错误'; break; default: message = '登录失败:${error.message}'; } ScaffoldMessenger.of(context).showSnackBar( CustomSnackBar(message, context), ); return null; } catch (e) { ScaffoldMessenger.of(context).showSnackBar( CustomSnackBar('登录出错,请稍后重试', context), ); return null; } }
2. 调整登录按钮的onPressed逻辑
在发起请求前设置loading为true,请求完成后再设置为false,并在登录成功后跳转页面:
TextButton( onPressed: () async { if (_key.currentState!.validate()) { // 发起请求前显示加载 setState(() => loading = true); final email = _emailController.text; final password = _passwordController.text; final User? user = await _auth.login(email, password, context); // 请求结束后隐藏加载 setState(() => loading = false); // 登录成功才跳转 if (user != null) { Navigator.pushNamed(context, DiscoverPage.id); } print(loading); // 此时会正确输出false,因为请求已完成 } }, child: loading ? const CircularProgressIndicator() : const Text('登录'), ),
3. 额外检查
确保loading是当前State类的成员变量,初始值为false:
bool loading = false;
内容的提问来源于stack exchange,提问作者leuji
相关产品推荐
相关产品推荐

