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

Android Credential Manager谷歌登录异常:返回用户无法获取邮箱数据

Google Sign-in 重复登录无法获取邮箱问题排查与修复

问题原因

  1. API调用错误:你在代码里用googleIdTokenCredential.getId()获取邮箱,这个方法实际返回的是Google用户的唯一标识sub(就是你看到的那串数字ID),并非邮箱地址。官方文档中获取邮箱的正确方法是getEmail()。
  2. 授权范围未显式声明:首次登录时用户默认授权了邮箱权限,但注销后再次登录,Credential Manager会自动复用保存的无邮箱权限的凭证,导致返回的ID Token里缺失email字段。

修复步骤

1. 修正邮箱获取代码

直接替换handleSignIn方法里的邮箱获取逻辑:

// 原错误代码
// String email = googleIdTokenCredential.getId();

// 替换为正确API
String email = googleIdTokenCredential.getEmail();

2. 显式添加授权范围

创建GetSignInWithGoogleOption时,必须明确指定email和profile权限范围,确保每次登录都能拿到邮箱、用户名等信息:

GetSignInWithGoogleOption googleIdOption = new GetSignInWithGoogleOption.Builder(getString(R.string.your_web_client_id))
        .setNonce("nonce")
        // 强制声明需要的权限范围
        .setScopes(List.of("email", "profile"))
        .build();

3. 可选:强制重新授权(避免复用旧凭证)

如果希望用户注销后再登录必须重新授权(不使用本地保存的无权限凭证),可以在登录选项中禁用自动选择,或者注销时清除本地凭证:

// 配置登录选项时禁用自动选择
GetSignInWithGoogleOption googleIdOption = new GetSignInWithGoogleOption.Builder(getString(R.string.your_web_client_id))
        .setNonce("nonce")
        .setScopes(List.of("email", "profile"))
        .setAutoSelectEnabled(false)
        .build();

// 注销时清除保存的凭证
credentialManager.deleteCredentialAsync(this, credential.getId(), new CancellationSignal(), Executors.newSingleThreadExecutor(), new CredentialManagerCallback<Void, CredentialManagerException>() {
    @Override
    public void onResult(Void result) {
        // 清除成功,用户下次登录需重新授权
    }

    @Override
    public void onError(CredentialManagerException e) {
        Log.e(TAG, "清除凭证失败: " + e.getMessage());
    }
});

验证效果

修改完成后,再次登录返回的ID Token会重新包含email、name等字段,使用getEmail()即可正确获取用户邮箱,不会再返回数字ID。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 06:07:02