Search code examples
androidkotlingoogle-signinandroid-credential-manager

Android Kotlin - Google Credential Manager - get user ID


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)
    }
}

googleIdTokenCredential.id gives me the email address, is this a bug?

The code for the old Sign In was:

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
    val personPhoto = acct.photoUrl

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

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

and acct.id gave me an id like 113755066377078777777

I have many users which are associated with an id like this, what the hell is wrong with google? How can I get the normal id instead of email address with the new Credential Manager?


Solution

  • To answer your first question on whether that is a bug or not, the answer is no, that is not a bug. As the documentation clearly states, that field returns the email address of the user:

    the email address associated with user's Google Account.

    In order to get to the "id" that you want, you'd need to look inside the ID Token that is captured by personToken in your snippet. The ID Token has a number of fields in a JWT format (basically JSON) and is best to be parsed by the caller to extract the information that is desired. You are probably interested in the "sub" field there, see this for more details. Note that your personToken is a signed-JWT and is Base64-encoded; you would need to decode that (see this post for example) in order to get the payload that you're interested in, and also would need to verify that (possibly on your server side) it was signed by Google, for security measures.

    Finally, as a side note, let me mention that the nature of GoogleSignIn.getLastSignedInAccount is very different from the Credential Manager's API that you had mentioned; the former was used to obtain the information about a Google account that was previously used to sign into an app on the same device while the latter is for the purpose of signing into an app.