Flutter Firebase认证中GoogleSignInAccount?赋值非可空类型错误解决
问题场景
在集成Google登录与Firebase认证时,尝试将GoogleSignIn().signIn()的结果赋值给GoogleSignInAccount类型变量,遇到类型不匹配错误,Flutter提示:
A value of type 'GoogleSignInAccount?' can't be assigned to a variable of type 'GoogleSignInAccount'.
Try changing the type of the variable, or casting the right-hand type to 'GoogleSignInAccount'.
相关代码如下:
// ignore: import_of_legacy_library_into_null_safe import 'package:google_sign_in/google_sign_in.dart'; import 'package:firebase_auth/firebase_auth.dart'; Future<Map<String, dynamic>> signInWithGoogle() async { final GoogleSignInAccount googleUser = await GoogleSignIn().signIn(); final GoogleSignInAuthentication googleAuth = await googleUser.authentication; final credential = GoogleAuthProvider.credential( accessToken: googleAuth.accessToken, idToken: googleAuth.idToken, ); return { "email": googleUser.email, "photoUrl": googleUser.photoUrl, "credentials": await FirebaseAuth.instance.signInWithCredential(credential), }; } Future<bool> signInWithEmail(String email, String password) async { try { FirebaseAuth.instance. signInWithEmailAndPassword(email: email, password: password); return true; } on FirebaseAuthException catch(e){ print(e.code); return false; } } Future<bool> signUpWithEmail(String email, String password) async { try { FirebaseAuth.instance. createUserWithEmailAndPassword(email: email, password: password); return true; } on FirebaseAuthException catch(e){ print(e.code); return false; } }
问题原因
这是Flutter空安全机制导致的:GoogleSignIn().signIn()方法返回的是Future<GoogleSignInAccount?>,即用户可能取消登录操作,返回结果可能为null,因此不能直接赋值给非可空的GoogleSignInAccount类型变量,强制类型转换会在用户取消登录时触发空指针异常。
正确解决方案
1. 处理可空类型,判断用户是否取消登录
先将结果赋值给可空类型变量,然后判断是否为null,处理用户取消登录的场景,再继续后续流程:
Future<Map<String, dynamic>?> signInWithGoogle() async { // 接收可空类型的登录结果 final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn(); // 用户取消登录时,返回null或根据业务抛出异常 if (googleUser == null) { return null; } final GoogleSignInAuthentication googleAuth = await googleUser.authentication; final credential = GoogleAuthProvider.credential( accessToken: googleAuth.accessToken, idToken: googleAuth.idToken, ); final authResult = await FirebaseAuth.instance.signInWithCredential(credential); return { "email": googleUser.email, "photoUrl": googleUser.photoUrl, "credentials": authResult, }; }
2. 补充修复其他代码问题
你的邮箱登录/注册方法中缺少await,会导致方法提前返回true,但认证操作可能还未完成,需要加上await:
修复后的邮箱登录方法
Future<bool> signInWithEmail(String email, String password) async { try { await FirebaseAuth.instance.signInWithEmailAndPassword( email: email, password: password ); return true; } on FirebaseAuthException catch(e){ print(e.code); return false; } }
修复后的邮箱注册方法
Future<bool> signUpWithEmail(String email, String password) async { try { await FirebaseAuth.instance.createUserWithEmailAndPassword( email: email, password: password ); return true; } on FirebaseAuthException catch(e){ print(e.code); return false; } }
注意:不推荐直接使用
!进行null断言(比如GoogleSignInAccount googleUser = await GoogleSignIn().signIn()!;),除非你能100%保证用户不会取消登录,否则会引发运行时异常。
内容的提问来源于stack exchange,提问作者pomoworko.com

