1

I'm using the Android Credential Manager API to implement "Sign In with Google" in my application. I'm successfully getting a GoogleIdTokenCredential after a successful sign-in, but I'm encountering an issue where I cannot get the user's email address.

Here's the relevant code:

@Composable
fun SignInWithGoogleButton(modifier: Modifier = Modifier) {
    val context = LocalContext.current
    val credentialManager = remember(context) { CredentialManager.create(context) }
    val coroutineScope = rememberCoroutineScope()

    val WEB_CLIENT_ID = "[MyId]" 

    Button(
        onClick = {
            coroutineScope.launch {
                try {
                    val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption.Builder(serverClientId = WEB_CLIENT_ID)
                        // add the nonce later
                        .build()

                    val request: GetCredentialRequest = GetCredentialRequest.Builder()
                        .addCredentialOption(signInWithGoogleOption)
                        .build()

                    val result = credentialManager.getCredential(
                        context = context,
                        request = request
                    )

                    handleSignInWithGoogleResult(result)

                } catch (e: GetCredentialException) {
                    Log.e("GoogleSignIn", "Credential Manager Sign in with Google failed: ${e.message}", e)
                } catch (e: Exception) {
                    Log.e("GoogleSignIn", "An unexpected error occurred: ${e.message}", e)
                }
            }
        }
    )
    {
        Text("Sign In with Google")
    }
}

private fun handleSignInWithGoogleResult(result: GetCredentialResponse) {
    val credential = result.credential
    when (credential) {
        is CustomCredential -> {
            if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
                try {
                    val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.data)
                    val idToken = googleIdTokenCredential.idToken
                    val email = googleIdTokenCredential.id
                    val displayName = googleIdTokenCredential.displayName

                    Log.d("GoogleSignIn", "ID Token: $idToken")
                    Log.d("GoogleSignIn", "Email (from googleIdTokenCredential.id): $email")
                    Log.d("GoogleSignIn", "Display Name: $displayName")

                } catch (e: GoogleIdTokenParsingException) {
                    Log.e("GoogleSignIn", "Failed to parse Google ID token credential: ${e.message}", e)
                }
            } else {
                Log.e("GoogleSignIn", "Unexpected type of CustomCredential: ${credential.type}")
            }
        }
        else -> {
            Log.e("GoogleSignIn", "Unexpected type of credential: ${credential.type}")
        }
    }
}

Dependencies

    implementation("androidx.credentials:credentials:1.5.0")
    implementation("androidx.credentials:credentials-play-services-auth:1.5.0")
    implementation("com.google.android.libraries.identity.googleid:googleid:1.1.1")

Problem:

  1. When I access googleIdTokenCredential.id, I receive a numerical identifier, not the user's email address.
  2. Upon inspecting the idToken string (by decoding it as a JWT), the email claim within the ID token's payload is null.

My Google Cloud Console Configuration:

In my Google Cloud Project, I have the following scopes configured:

  • ./auth/userinfo.email
  • ./auth/userinfo.profile
  • openid

I've tested this with two different Gmail accounts, and the behavior is consistent.

Question:

How can I correctly obtain the user's email address from the GoogleIdTokenCredential when using the Android Credential Manager, ensuring that the idToken contains the necessary claim? Is there a specific way to request these scopes within the GetSignInWithGoogleOption or GetCredentialRequest that I'm missing?

Any guidance or examples would be greatly appreciated!

What I've already try:

  • Ensured the WEB_CLIENT_ID in my app matches the one configured in Google Cloud Console.
  • Confirmed that the OAuth consent screen is configured.
  • Searched for similar issues related to Credential Manager and Google ID tokens, but haven't found a definitive solution for this specific problem where the email claim is missing despite correct backend scope configuration.

2 Answers 2

1

I suggest you call AuthorizationClient#revokeAccess() for that account and try again. Note that the revokeAccess() method is new in the latest version of play-services:-auth:21.4.0, or revoke access to that app for that user from https://myaccount.google.com/connections (and wait a bit for that to sync to your device).

Sign up to request clarification or add additional context in comments.

2 Comments

https://developer.android.com/jetpack/androidx/releases/credentials this document is showing androidx.credentials:credentials-play-services-auth: has latest version of 1.5.0, how can you refer 21.4.0?
I am referring to com.google.android.gms:play-services-auth:21.4.0
0

It sounds like you're on the right track with your configuration, especially by verifying the WEB_CLIENT_ID and the OAuth consent screen. Just to confirm, are you explicitly requesting the email and profile scopes when setting up your GetSignInWithGoogleOption or GetCredentialRequest? If these scopes aren't included, the ID token might not contain the email claim. Also, make sure your backend verifies the token using the same WEB_CLIENT_ID.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.