androidgoogle-signin

Android google sign in with credential manager, unable to get user data on returning user


I have trouble with the Android Google sign in. I have an application with Google Sign-in. It's already in production.

About 2-4 days ago our app got several reports from users that use login with a Google account.

The problem was :

  1. While user logs in the first time on our app, clicks login with Google, then shows the dialog from Google that user should choose their account to login, after user picks one, then user consent prompt will show. User should agree with it -> the code work normal, able to get user email.
  2. However, when the user logs out and then logs in with the same account, the user consent prompt does not, and then our code is unable to get their email, but it will return some string id like "11231231231231231"

googleIdTokenCredential.getId() <-- should return email, documentation here

enter image description here

The code : following from https://developer.android.com/identity/sign-in/credential-manager-siwg

GetSignInWithGoogleOption googleIdOption = new GetSignInWithGoogleOption.Builder(getString(R.string.your_web_client_id)).setNonce("nonce").build();
    GetCredentialRequest request = new GetCredentialRequest.Builder().addCredentialOption(googleIdOption).build();

credentialManager.getCredentialAsync(this, request, new CancellationSignal(), Executors.newSingleThreadExecutor(), new CredentialManagerCallback<GetCredentialResponse, GetCredentialException>() {
                @Override
                public void onResult(GetCredentialResponse result) {
                    handleSignIn(result);
                }

                @Override
                public void onError(GetCredentialException e) {
                    Log.e(TAG, "Login Err" + e.getMessage());
                }
            });
public void handleSignIn(GetCredentialResponse result) {
    Credential credential = result.getCredential();
    if (credential instanceof CustomCredential) {
        if (GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL.equals(credential.getType())) {
            GoogleIdTokenCredential googleIdTokenCredential = null;
            try {
                googleIdTokenCredential = GoogleIdTokenCredential.createFrom(((CustomCredential) credential).getData());
            } catch (Exception e) {
                Log.e(TAG, "Received an invalid google id token response" + e.getMessage());
            }
          
            String personName = googleIdTokenCredential.getDisplayName();
            String email = googleIdTokenCredential.getId();
        }
    }
}

After debugging more, I noticed that response token is also different for first user and returning user.

First user

{
  "iss": "https://accounts.google.com",
  "azp": "....",
  "aud": "....",
  "sub": "105676566517108135791",
  "email": "someemail@gmail.com",
  "email_verified": true,
  "nonce": "6f7492ed4cf77a82ad276b5d54f65e72",
  "name": "some name",
  "picture": "...",
  "given_name": "Some",
  "family_name": "Test",
  "iat": 1726990428,
  "exp": 1726994028
}

Returning user user

{
  "iss": "https://accounts.google.com",
  "azp": "....",
  "aud": ".....",
  "sub": "105676566517108135791",
  "nonce": "some_nonce",
  "iat": 1726990462,
  "exp": 1726994062
}

Solution

  • We apologize for any inconvenience this may have caused; we have identified the cause and this was due to an improper information between client and server. We are adding integration tests to ensure this doesn't regress. The issue has been fixed through a flag update, and should be taking effect on all devices soon, if not already.