修改Firebase用户账户关联选项后Google登录无法获取用户邮箱
问题描述
我修改了Firebase Authentication的用户账户关联设置,选择了“为每个身份提供商创建多个账户”选项。现在用户通过Google登录时,无法获取user.email字段,但user.displayName、user.photoURL等其他用户信息都能正常获取。以下是我的实现代码:
void signUpWithGoogle(context) async { try { showDialog( context: context, builder: (context) => Container( color: Colors.black, child: const Center( child: CircularProgressIndicator( color: Colors.white, ), ), ), ); final GoogleSignInAccount? googleSignInAccount = await googleSignIn.signIn(); final GoogleSignInAuthentication googleSignInAuthentication = await googleSignInAccount!.authentication; // provider.setCustomParameters({}); final AuthCredential authCredential = GoogleAuthProvider.credential( idToken: googleSignInAuthentication.idToken, accessToken: googleSignInAuthentication.accessToken); UserCredential result = await fireAuth.signInWithCredential(authCredential); globals.user = result.user; if(!await UserData().isUserExists(FirebaseAuth.instance.currentUser!.uid)) { debugPrint("_-_-_-_-_-_ NEW USER _-_-_-_-_-_\n ${result.user} \n ${globals.user.email}\n ${globals.user.displayName}\n ${globals.user.photoURL}"); UserData(true, globals.user.email, globals.user.displayName, globals.user.photoURL).addUser(FirebaseAuth.instance.currentUser!.uid); } else { debugPrint("_-_-_-_-_-_ USER ALREADY EXISTS _-_-_-_-_-_"); } if(result != null) { Navigator.of(context).pushAndRemoveUntil( // MaterialPageRoute(builder: (context) => const HomeScreen()),(Route<dynamic> route) => false PageRouteBuilder( pageBuilder: (_, __, ___) => const HomeScreen(), transitionDuration: const Duration(milliseconds: 1500), transitionsBuilder: (_, a, __, c) => FadeTransition( opacity: a, child: c, )), (Route<dynamic> route) => false ); } else { debugPrint(" RESULT USER IS NULL =>=>=> "); } } catch (exception) { if(exception is PlatformException) { if(exception.code == GoogleSignIn.kNetworkError) { showAlert(context, "You have Poor Connectivity."); } else { debugPrint("YOU HAVE EXCEPTION IN GOOGLE SIGN IN ${exception.code}"); } } debugPrint("YOU HAVE PROBLEM IN GOOGLE SIGN IN $exception"); } }
解决方案
原因分析
选择“为每个身份提供商创建多个账户”后,Firebase不会自动合并不同提供商的权限请求。Google登录时,邮箱属于需要明确请求的权限字段,而displayName、photoURL是默认公开的基础信息,所以会被正常返回。
解决步骤
添加Google登录的邮箱权限
初始化GoogleSignIn时,指定scopes参数明确请求邮箱权限:final GoogleSignIn googleSignIn = GoogleSignIn( scopes: [ 'email', 'profile', // 可选,确保获取基础用户信息 ], );从GoogleSignInAccount直接提取邮箱
即使Firebase User对象的email为空,也可以直接从GoogleSignInAccount中获取邮箱,再同步到全局变量或Firebase用户信息:final GoogleSignInAccount? googleSignInAccount = await googleSignIn.signIn(); if (googleSignInAccount != null) { String? userEmail = googleSignInAccount.email; // 若Firebase User的email为空,手动补全 if (globals.user?.email == null && userEmail != null) { globals.user = globals.user?.copyWith(email: userEmail); } }确认Firebase控制台设置
进入Firebase控制台 → Authentication → 登录方法 → Google,检查“获取用户的电子邮件地址”选项是否已启用(默认开启,建议确认)。
修改后的代码示例
// 初始化GoogleSignIn时添加权限 final GoogleSignIn googleSignIn = GoogleSignIn( scopes: ['email', 'profile'], ); void signUpWithGoogle(context) async { try { showDialog( context: context, builder: (context) => Container( color: Colors.black, child: const Center( child: CircularProgressIndicator(color: Colors.white), ), ), ); final GoogleSignInAccount? googleSignInAccount = await googleSignIn.signIn(); if (googleSignInAccount == null) { Navigator.of(context).pop(); return; } final GoogleSignInAuthentication googleSignInAuthentication = await googleSignInAccount.authentication; final AuthCredential authCredential = GoogleAuthProvider.credential( idToken: googleSignInAuthentication.idToken, accessToken: googleSignInAuthentication.accessToken); UserCredential result = await fireAuth.signInWithCredential(authCredential); globals.user = result.user; // 从Google账户获取邮箱并补全 String? userEmail = googleSignInAccount.email; if (globals.user?.email == null && userEmail != null) { globals.user = globals.user?.copyWith(email: userEmail); } if(!await UserData().isUserExists(FirebaseAuth.instance.currentUser!.uid)) { debugPrint("_-_-_-_-_-_ NEW USER _-_-_-_-_-_\n ${result.user} \n ${globals.user?.email}\n ${globals.user?.displayName}\n ${globals.user?.photoURL}"); UserData(true, globals.user?.email, globals.user?.displayName, globals.user?.photoURL).addUser(FirebaseAuth.instance.currentUser!.uid); } else { debugPrint("_-_-_-_-_-_ USER ALREADY EXISTS _-_-_-_-_-_"); } Navigator.of(context).pushAndRemoveUntil( PageRouteBuilder( pageBuilder: (_, __, ___) => const HomeScreen(), transitionDuration: const Duration(milliseconds: 1500), transitionsBuilder: (_, a, __, c) => FadeTransition(opacity: a, child: c)), (Route<dynamic> route) => false ); } catch (exception) { if(exception is PlatformException) { if(exception.code == GoogleSignIn.kNetworkError) { showAlert(context, "网络连接不佳。"); } else { debugPrint("Google登录异常:${exception.code}"); } } debugPrint("Google登录出错:$exception"); } }
内容的提问来源于stack exchange,提问作者Dhanrajsinh Parmar
相关产品推荐
相关产品推荐

