Flutter接入Firebase Facebook登录返回空邮箱 控制台存下划线如何解决
问题1:Facebook登录返回邮箱为null的故障原因及修复
- 登录用的Facebook账号本身未绑定有效邮箱(比如仅用手机号注册),或是用户在授权时手动拒绝了邮箱权限申请,这种属于正常场景,返回邮箱天然为null,Firebase会自动填充下划线作为占位符。
- 仅从Firebase的
UserCredential对象中取邮箱是错误的,Facebook的全量用户信息不会自动同步到Firebase User对象中,需要用拿到的access token主动调用Facebook的用户信息接口拉取邮箱。 - Facebook应用状态限制:如果应用还处于开发模式,只能用测试用户、应用管理员/开发者的Facebook账号测试,普通账号的邮箱权限默认不开放;如果要上线面向所有用户使用,需要去Facebook开发者后台提交
email权限的使用申请,审核通过后普通用户才能正常授权邮箱。 - iOS端配置错误:检查Info.plist中是否正确配置了FacebookAppID、FacebookDisplayName,以及LSApplicationQueriesSchemes列表中是否添加了fbapi、fb-messenger-share-api等必填项,核对所有配置项的拼写是否正确。
问题2:首次登录提示“此前已经使用Facebook账号登录过该应用”的说明与修复
- 该提示是Facebook的正常机制:你之前用同一个Facebook账号登录过一次该应用,哪怕后续卸载应用、清除本地缓存,Facebook后台已经记录了该账号和应用的授权绑定关系,所以再次触发登录时就会弹出该提示,不属于代码bug。
- 调用登录前执行的
await signOutFacebook();仅会清除应用本地的Facebook登录状态,不会清除Facebook后台的绑定关系。如果需要测试首次登录的效果,可登录对应的Facebook账号,进入「设置和隐私」-「设置」-「应用和网站」,找到你的应用点击移除,之后再测试就不会弹出该提示。 - 开发阶段测试首次登录逻辑,建议直接使用Facebook开发者后台创建的测试账号,无需每次手动解绑现有账号。
修改后的参考代码
// Sign in with Facebook. static Future<Map<String, dynamic>> signInWithFacebook({bool isSignUp}) async { try { await signOutFacebook(); UserCredential userCredential; // Trigger the sign-in flow List<String> permissions = ['email', 'public_profile']; final LoginResult loginResult = await FacebookAuth.instance.login(permissions: permissions); // 先校验登录状态 if (loginResult.status != LoginStatus.success) { return {'success': false, 'message': "Facebook登录被取消或发生异常"}; } // 主动拉取Facebook侧的用户全量信息 final facebookUserInfo = await FacebookAuth.instance.getUserData(fields: "email,name,id"); print("Facebook返回的邮箱为 ${facebookUserInfo['email']}"); // 此处可拿到正确邮箱 // Create a credential from the access token final OAuthCredential facebookAuthCredential = FacebookAuthProvider.credential(loginResult.accessToken.token); // Once signed in, return the UserCredential userCredential = await FirebaseAuth.instance.signInWithCredential(facebookAuthCredential); final User user = userCredential.user; // 若Firebase用户对象邮箱为空,主动用Facebook拉取的邮箱更新 if (user.email == null && facebookUserInfo['email'] != null) { await user.updateEmail(facebookUserInfo['email']); await user.reload(); } print("User info after facebook login ${user.providerData[0].email} ${user.uid}"); if (isSignUp) { Map<String, dynamic> resultOfSaveSocialUserToDatabase = await saveSocialUserToDatabase(user, 'facebook'); return resultOfSaveSocialUserToDatabase; } else { Map<String, dynamic> resultOfValidateSocialLogin = await validateSocialLogin(user, 'facebook'); return resultOfValidateSocialLogin; } } catch (e) { print(e); return {'success': false, 'message': "Sign up with social account failed"}; } }
内容的提问来源于stack exchange,提问作者Speeder
相关产品推荐
相关产品推荐

