Integrate Credential Manager with Sign in with Google

Sign in with Google helps you quickly integrate user authentication with your Android app. Users can use their Google Account to sign in to your app, provide consent, and securely share their profile information with your app. Android's Credential Manager Jetpack library makes this integration smooth, offering a consistent experience across Android devices using a single API.

This document guides you through implementing Sign in with Google in Android apps, how you can set up the Sign in with Google button UI, and configuring app-optimized one tap sign-up and sign-in experiences. For smooth device migration, Sign in with Google supports auto sign-in, and its cross-platform nature across Android, iOS, and web surfaces helps you provide sign-in access for your app on any device.

To set up Sign in with Google, follow these two main steps:

Configure Sign in with Google as an option for Credential Manager's bottom sheet UI. This can be configured to automatically prompt the user to sign in. If you have implemented either passkeys or passwords, you can request all relevant credential types simultaneously, so that the user does not have to remember the option they've used previously to sign in.

Credential Manager bottom sheet
Figure 1. The Credential Manager bottomsheet credential selection UI

Add the Sign in with Google button to your app's UI. The Sign in with Google button offers a streamlined way for users to use their existing Google Accounts to sign up or sign in to Android apps. Users will click the Sign in with Google button if they dismiss the bottom sheet UI, or if they explicitly want to use their Google Account for sign up and sign in. For developers, this means easier user onboarding and reduced friction during sign-up.

Animation showing the Sign in with Google flow
Figure 2. The Credential Manager Sign in with Google button UI

This document explains how to integrate the Sign in with Google button and bottom sheet dialog with the Credential Manager API using the Google ID helper library.

Set up your Google APIs console project

  1. Open your project in the API Console, or create a project if you don't already have one.
  2. On the OAuth consent screen page, make sure all of the information is complete and accurate.
    1. Make sure your app has a correct App Name, App Logo, and App Homepage assigned. These values will be presented to users on the Sign in with Google consent screen on sign up and the Third-party apps & services screen.
    2. Make sure you have specified the URLs of your app's privacy policy and terms of service.
  3. In the Credentials page, create an Android client ID for your app if you don't already have one. You will need to specify your app's package name and SHA-1 signature.
    1. Go to the Credentials page.
    2. Click Create credentials > OAuth client ID.
    3. Select the Android application type.
  4. In the Credentials page, create a new "Web application" client ID if you haven't already. You can ignore the "Authorized JavaScript Origins" and "Authorized redirect URIs" fields for now. This client ID will be used to identify your backend server when it communicates with Google's authentication services.
    1. Go to the Credentials page.
    2. Click Create credentials > OAuth client ID.
    3. Select the Web application type.

Declare dependencies

In your module's build.gradle file, declare dependencies using the latest version of Credential Manager:

dependencies {
  // ... other dependencies

  implementation "androidx.credentials:credentials:<latest version>"
  implementation "androidx.credentials:credentials-play-services-auth:<latest version>"
  implementation "com.google.android.libraries.identity.googleid:googleid:<latest version>"
}

Instantiate a Google sign-in request

To begin your implementation, instantiate a Google sign-in request. Use GetGoogleIdOption to retrieve a user's Google ID Token.

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(WEB_CLIENT_ID)
  .setAutoSelectEnabled(true)
  .setNonce(<nonce string to use when generating a Google ID token>)
  .build()

First, check if the user has any accounts that have previously been used to sign in to your app by calling the API with the setFilterByAuthorizedAccounts parameter set to true. Users can choose between available accounts to sign in.

If no authorized Google Accounts are available, the user should be prompted to sign up with any of their available accounts. To do this, prompt the user by calling the API again and setting setFilterByAuthorizedAccounts to false. Learn more about sign up.

Enable automatic sign-in for returning users (recommended)

Developers should enable automatic sign-in for users who register with their single account. This provides a seamless experience across devices, especially during device migration, where users can quickly regain access to their account without re-entering credentials. For your users, this removes unnecessary friction when they were already previously signed in.

To enable automatic sign-in, use setAutoSelectEnabled(true). Automatic sign in is only possible when the following criteria are met:

  • There is a single credential matching the request, which can be a Google Account or a password, and this credential matches the default account on the Android-powered device.
  • The user has not explicitly signed out.
  • The user hasn't disabled automatic sign-in in their Google Account settings.
val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(WEB_CLIENT_ID)
  .setAutoSelectEnabled(true)
  .setNonce(<nonce string to use when generating a Google ID token>)
  .build()

Remember to correctly handle sign-out when implementing automatic sign-in, so that users can always choose the proper account after they explicitly sign out of your app.

Set a nonce to improve security

To improve sign-in security and avoid replay attacks, add setNonce to include a nonce in each request. Learn more about generating a nonce.

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(true)
  .setServerClientId(WEB_CLIENT_ID)
  .setAutoSelectEnabled(true)
  .setNonce(<nonce string to use when generating a Google ID token>)
  .build()

Create the Sign in with Google flow

The steps to set up a Sign in with Google flow are as follows:

  1. Instantiate the GetCredentialRequest and add the googleIdOption created earlier to retrieve the credentials.
  2. Pass this request to getCredential() (Kotlin) or getCredentialAsync() (Java) call to retrieve the user's available credentials.
  3. Once the API is successful, extract the CustomCredential which holds the result for GoogleIdTokenCredential data.
  4. The type for CustomCredential should be equal to the value of GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL. Convert the object into a GoogleIdTokenCredential using the GoogleIdTokenCredential.createFrom method.
  5. If the conversion succeeds, extract the GoogleIdTokenCredential ID, validate it, and authenticate the credential on your server.

  6. If the conversion fails with a GoogleIdTokenParsingException, then you may need to update your Sign in with Google library version.

  7. Catch any unrecognized custom credential types.

val request: GetCredentialRequest = Builder()
  .addGetCredentialOption(googleIdOption)
  .build()

coroutineScope.launch {
  try {
    val result = credentialManager.getCredential(
      request = request,
      context = activityContext,
    )
    handleSignIn(result)
  } catch (e: GetCredentialException) {
    handleFailure(e)
  }
}

fun handleSignIn(result: GetCredentialResponse) {
  // Handle the successfully returned credential.
  val credential = result.credential

  when (credential) {

    // Passkey credential
    is PublicKeyCredential -> {
      // Share responseJson such as a GetCredentialResponse on your server to
      // validate and authenticate
      responseJson = credential.authenticationResponseJson
    }

    // Password credential
    is PasswordCredential -> {
      // Send ID and password to your server to validate and authenticate.
      val username = credential.id
      val password = credential.password
    }

    // GoogleIdToken credential
    is CustomCredential -> {
      if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
        try {
          // Use googleIdTokenCredential and extract id to validate and
          // authenticate on your server.
          val googleIdTokenCredential = GoogleIdTokenCredential
            .createFrom(credential.data)
        } catch (e: GoogleIdTokenParsingException) {
          Log.e(TAG, "Received an invalid google id token response", e)
        }
      } else {
        // Catch any unrecognized custom credential type here.
        Log.e(TAG, "Unexpected type of credential")
      }
    }

    else -> {
      // Catch any unrecognized credential type here.
      Log.e(TAG, "Unexpected type of credential")
    }
  }
}

Trigger a Sign in with Google button flow

To trigger the Sign in with Google button flow, use GetSignInWithGoogleOption instead of GetGoogleIdOption:

val signInWithGoogleOption: GetSignInWithGoogleOption = GetSignInWithGoogleOption.Builder()
  .setServerClientId(WEB_CLIENT_ID)
  .setNonce(<nonce string to use when generating a Google ID token>)
  .build()

Handle the returned GoogleIdTokenCredential as described in the following code example.

fun handleSignIn(result: GetCredentialResponse) {
  // Handle the successfully returned credential.
  val credential = result.credential

  when (credential) {
    is CustomCredential -> {
      if (credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
        try {
          // Use googleIdTokenCredential and extract id to validate and
          // authenticate on your server.
          val googleIdTokenCredential = GoogleIdTokenCredential
            .createFrom(credential.data)
        } catch (e: GoogleIdTokenParsingException) {
          Log.e(TAG, "Received an invalid google id token response", e)
        }
      }
      else -> {
        // Catch any unrecognized credential type here.
        Log.e(TAG, "Unexpected type of credential")
      }
    }

    else -> {
      // Catch any unrecognized credential type here.
      Log.e(TAG, "Unexpected type of credential")
    }
  }
}

Once you instantiate the Google sign in request, launch the authentication flow in a similar manner as mentioned in the Sign in with Google section.

Enable sign-up for new users (recommended)

Sign in with Google is the easiest way for users to create a new account with your app or service in just a few taps.

If no saved credentials are found (no Google Accounts returned by getGoogleIdOption), prompt your user to sign up. First, check if setFilterByAuthorizedAccounts(true) to see if any previously used accounts exist. If none are found, prompt the user to sign up with their Google Account using setFilterByAuthorizedAccounts(false)

Example:

val googleIdOption: GetGoogleIdOption = GetGoogleIdOption.Builder()
  .setFilterByAuthorizedAccounts(false)
  .setServerClientId(SERVER_CLIENT_ID)
  .build()

Once you instantiate the Google sign up request, launch the authentication flow. If users don't want to sign up with Google, consider autofill services or passkeys for account creation.

Handle sign-out

When a user signs out of your app, call the API clearCredentialState() method to clear the current user credential state from all credential providers. This will notify all credential providers that any stored credential session for the given app should be cleared.

A credential provider may have stored an active credential session and use it to limit sign-in options for future get-credential calls. For example, it may prioritize the active credential over any other available credential. When your user explicitly signs out of your app and in order to get the holistic sign-in options the next time, you should call this API to let the provider clear any stored credential session.