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:
My Google Cloud Console Configuration:
In my Google Cloud Project, I have the following scopes configured:
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:
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).