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

Android Kotlin:谷歌Credential Manager获取用户ID返回邮箱问题求助

关于Google Credential Manager获取用户ID的问题

问题场景

使用新版Google Credential Manager时,发现调用googleIdTokenCredential.id返回的是用户邮箱,而旧版Google Sign In的acct.id返回的是类似113755066377078777777的数字用户ID。现有大量用户已关联该数字ID,因此需要明确两个问题:

  1. 新版API返回邮箱是否属于bug?
  2. 如何通过新版Credential Manager获取旧版格式的数字用户ID?

新版Credential Manager代码

if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
    try {
        val googleIdTokenCredential = GoogleIdTokenCredential
            .createFrom(credential.data)

        val personToken = googleIdTokenCredential.idToken
        val personId = googleIdTokenCredential.id // 此处返回邮箱
        val displayName = googleIdTokenCredential.displayName
        val personPhoto = googleIdTokenCredential.profilePictureUri

    } catch (e: GoogleIdTokenParsingException) {
        Log.d("pikaboo", "Received an invalid google id token response", e)
    }
}

旧版Google Sign In代码

val acct = GoogleSignIn.getLastSignedInAccount(this@GoogleLogin)
if (acct != null) {
    val displayName = acct.displayName
    val personGivenName = acct.givenName
    val personFamilyName = acct.familyName
    val personId = acct.id // 此处返回数字用户ID
    val personPhoto = acct.photoUrl

    var photo = ""
    if(personPhoto != null){
        photo = personPhoto.toString()
    }

    sendToServer(personId!!, photo, displayName, personGivenName, personFamilyName)
}

问题解答

1. googleIdTokenCredential.id返回邮箱是否是bug?

这不是bug,是API设计的差异。旧版Google Sign In的acct.id对应ID Token中的sub字段(用户唯一数字标识),而新版Credential Manager的GoogleIdTokenCredential.id默认返回的是ID Token中的email字段。两者只是API封装时选择暴露的字段不同,并非功能异常。

2. 获取旧版格式的数字用户ID的方法

要拿到和旧版acct.id一致的数字用户ID,需要直接解析ID Token中的sub字段。具体步骤如下:

  1. 获取完整的ID Token字符串(即googleIdTokenCredential.idToken)
  2. 解析该JWT Token,提取sub字段的值,这就是所需的数字用户ID。

示例代码如下:

import com.google.android.gms.auth.api.identity.GoogleIdToken
import com.google.android.gms.auth.api.identity.GoogleIdTokenCredential

if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
    try {
        val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data)
        val idToken = googleIdTokenCredential.idToken
        
        // 解析ID Token获取sub字段(对应旧版acct.id)
        val googleIdToken = GoogleIdToken.parse(idToken)
        val payload = googleIdToken.payload
        val personId = payload.subject // 此处返回数字用户ID
        
        // 其他字段获取保持不变
        val displayName = googleIdTokenCredential.displayName
        val personPhoto = googleIdTokenCredential.profilePictureUri
        
        // 后续逻辑:关联现有用户数据等
        // sendToServer(personId, ...)

    } catch (e: GoogleIdTokenParsingException) {
        Log.d("pikaboo", "Received an invalid google id token response", e)
    } catch (e: IllegalArgumentException) {
        Log.d("pikaboo", "Failed to parse ID token", e)
    }
}

payload.subject的值和旧版acct.id完全一致,可以直接用于关联现有用户的历史数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:54:55