Flutter空安全迁移后Firebase登录报空检查运算符空值异常
问题根因
你的代码存在4处核心错误,直接导致空安全报错、登录后用户属性全为null:
- 初始化逻辑空断言滥用:
_initializeFirebase()方法中,App冷启动未登录状态下FirebaseAuth.instance.currentUser本就是null,你直接加!强制非空,会第一时间触发Null check operator used on a null value异常,打断初始化流程。 - 状态变量类型定义错误:你把
_currentUser定义为布尔类型,只存储了邮箱验证状态,完全没有持有登录后返回的User实例,后续自然读不到用户的邮箱、昵称等属性。 - 登录状态判断逻辑错误:按钮点击事件中用
_currentUser==false判断是否未登录,和实际存储的布尔值、User对象类型完全不匹配,可能导致登录逻辑根本不执行,或者执行后状态不更新。 - 登录成功后状态未同步:
signInUsingEmailPassword方法返回登录成功的User对象后,你没有把它赋值给全局的用户变量,后续读取用户属性时拿到的还是未登录状态的null值。另外方法开头在未执行登录逻辑时就打印未赋值的user变量,本身拿到的就必然是null,无实际调试意义。
修复方案
1. 修正全局状态声明与Firebase初始化逻辑
替换原有初始化相关代码,去掉不合理的空断言,正确区分用户对象和邮箱验证状态:
// 正确声明状态变量,不要用布尔值存储用户对象 User? _currentUser; bool _isEmailVerified = false; Future<FirebaseApp> _initializeFirebase() async { FirebaseApp firebaseApp = await Firebase.initializeApp(); // 先判空再取值,禁止对未确认非空的对象加! User? user = FirebaseAuth.instance.currentUser; if (user != null) { _currentUser = user; _isEmailVerified = user.emailVerified; } return firebaseApp; }
2. 修正登录按钮点击逻辑,登录成功后同步状态
替换原有RaisedButton的onPressed逻辑,修正状态判断,登录成功后同步更新全局用户状态:
onPressed: () async{ _focusEmail.unfocus(); _focusPassword.unfocus(); // 未登录状态下_currentUser为null,原布尔值判断逻辑完全错误 if(_currentUser == null){ if (_formKey.currentState!.validate()) { setState(() { _isProcessing = true; }); User? user = await signInUsingEmailPassword( // 用trim()替代全量替换空格,避免误删密码中合法的中间空格 email: _emailTextController.text.trim(), password: _passwordTextController.text.trim(), ); // 登录成功后同步更新全局状态 if (user != null) { setState(() { _currentUser = user; _isEmailVerified = user.emailVerified; }); // 此时打印用户属性可正常拿到值 print("${_currentUser?.email}"); print("${_currentUser?.displayName}"); print("${_currentUser?.emailVerified}"); } setState(() { _isProcessing = false; }); } } },
3. 修正登录方法的空安全处理
替换原有登录方法,补上必填参数标记、通用异常兜底,删除无意义的提前打印:
// 入参标记为required,不需要在方法内再做强制非空断言 Future<User?> signInUsingEmailPassword({ required String email, required String password, }) async { FirebaseAuth auth = FirebaseAuth.instance; User? user; try { UserCredential userCredential = await auth.signInWithEmailAndPassword( email: email, password: password, ); user = userCredential.user; } on FirebaseAuthException catch (e) { if (e.code == 'user-not-found') { print('No user found for that email.'); showDialog( context: context, builder: (context) { return AlertDialog( title: Text('Erreur'), content: Text("Email incorrect"), ); }); } else if (e.code == 'wrong-password') { print('Erreur de mot de passe.'); showDialog( context: context, builder: (context) { return AlertDialog( title: Text('Erreur'), content: Text("Mot de passe incorrect"), ); }); } } catch (e) { // 补上通用异常捕获,避免未捕获错误导致闪退 print("登录流程未知错误:$e"); } return user; }
注意:如果登录后
displayName仍然为null,属于正常现象——邮箱密码注册流程默认不会给用户设置displayName,需要你在注册/登录成功后主动调用user.updateDisplayName()方法设置昵称后才能读取到值。
内容的提问来源于stack exchange,提问作者Nitneuq
相关产品推荐
相关产品推荐

