You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter集成Sign In with Apple登录Firebase无法获取用户名

Flutter 对接 Firebase + sign_in_with_apple 无法获取Apple用户姓名的解决方案

核心问题说明

Apple登录的特性决定了:仅在用户首次授权登录你的应用时,才会返回姓名信息,后续重复登录即使请求了fullName权限,也不会再返回该字段。你的代码目前没有处理首次登录时的姓名提取与存储逻辑,也没有从返回的appleCredential中直接获取姓名。

代码修正与解决方案

1. 提取Apple登录返回的姓名(仅首次有效)

在获取appleCredential后,立即提取姓名字段,同时结合Firebase Auth的additionalUserInfo.isNewUser判断是否为首次登录,将姓名保存到Firebase用户信息或你的数据库中:

Future<UserCredential> appleSignIn() async {
  if (kIsWeb) {
    final provider = OAuthProvider("apple.com")
      ..addScope('email')
      ..addScope('name');

    final userCredential = await FirebaseAuth.instance.signInWithPopup(provider);
    
    // Web端处理首次登录的姓名
    if (userCredential.additionalUserInfo?.isNewUser == true) {
      final profile = userCredential.additionalUserInfo?.profile;
      final firstName = profile?['given_name'];
      final lastName = profile?['family_name'];
      if (firstName != null || lastName != null) {
        await userCredential.user?.updateDisplayName('$firstName $lastName'.trim());
        // 可选:将姓名存入Firestore等数据库
        // await FirebaseFirestore.instance.collection('users').doc(userCredential.user?.uid).set({
        //   'displayName': '$firstName $lastName'.trim(),
        //   'email': userCredential.user?.email,
        // });
      }
    }
    
    return userCredential;
  }

  final rawNonce = generateNonce();
  final nonce = sha256ofString(rawNonce);

  // 请求Apple授权凭证
  final appleCredential = await SignInWithApple.getAppleIDCredential(
    scopes: [
      AppleIDAuthorizationScopes.email,
      AppleIDAuthorizationScopes.fullName,
    ],
    nonce: nonce,
  );

  // 创建Firebase OAuth凭证
  final oauthCredential = OAuthProvider("apple.com").credential(
    idToken: appleCredential.identityToken,
    rawNonce: rawNonce,
  );

  // 登录Firebase
  final userCredential = await FirebaseAuth.instance.signInWithCredential(oauthCredential);

  // 仅首次登录时保存姓名
  if (userCredential.additionalUserInfo?.isNewUser == true) {
    final firstName = appleCredential.givenName;
    final lastName = appleCredential.familyName;
    if (firstName != null || lastName != null) {
      // 更新Firebase用户的displayName
      await userCredential.user?.updateDisplayName('$firstName $lastName'.trim());
      // 可选:将姓名存入数据库持久化
      // await FirebaseFirestore.instance.collection('users').doc(userCredential.user?.uid).set({
      //   'displayName': '$firstName $lastName'.trim(),
      //   'email': userCredential.user?.email,
      // });
    }
  }

  return userCredential;
}

Future<User?> signInWithApple(BuildContext context) =>
    signInOrCreateAccount(context, appleSignIn, 'APPLE');

2. 测试注意事项

  • 如果之前已经用Apple登录过你的应用,需要在设备的设置 -> Apple ID -> 密码与安全性 -> 使用Apple ID的应用中找到你的应用,点击「停止使用Apple ID」,然后重新登录才能触发首次授权流程,获取姓名信息。
  • 确保sign_in_with_apple插件使用最新稳定版本,避免版本兼容问题。

关键提示

  • 不要依赖后续登录获取姓名,必须在首次登录时完成姓名的提取与存储。
  • 若用户首次授权时未提供姓名(Apple允许用户隐藏姓名),则givenName和familyName会为null,需做好空值处理。

内容的提问来源于stack exchange,提问作者xG00gle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 09:55:10