How to add Google Sign-In in Android (Step-by-Step Guide)

How to add Google Sign-In in Android (Step-by-Step Guide)


Want to let users log in to your Android app with their Google account? This tutorial shows you how to add Google Sign-In in Android the modern way using Jetpack Credential Manager and Google Identity Services. It’s written for students and beginners learning Android with Kotlin/Java, and it follows the latest 2026 best practices (no legacy GoogleSignInClient or One Tap). By the end, you’ll have a working sign-in flow with the new Credential Manager bottom sheet and a dedicated “Sign in with Google” button, plus tips for Firebase Auth and backend verification.

What is Google Sign-In on Android and when should you use it?

Google Sign-In lets users authenticate with their Google account to access your app. It reduces friction, increases conversion, and avoids managing passwords yourself. As of 2026, the recommended Android implementation uses Jetpack Credential Manager together with Google Identity Services (googleid). This unifies credentials (passwords, passkeys, and Sign in with Google) in a single, privacy-respecting bottom sheet, and also supports a dedicated “Sign in with Google” button for explicit login.

  • Modern, secure, and familiar to users
  • Works on API 19+ with automatic sign-in support for returning users
  • Simple integration with your backend and optional Firebase Authentication

Credential Manager vs legacy approaches (quick comparison)

Feature Credential Manager + Google Identity Legacy GoogleSignInClient / One Tap
Status for new apps Recommended path in Android docs Superseded for new apps
UX Unified bottom sheet + “Sign in with Google” button Separate Google UI flows
Credential types Passkeys, passwords, Google sign-in in one API Google sign-in only
Automatic sign-in Auto-select for returning users Limited/extra boilerplate
Backend verification ID token via GoogleIdTokenCredential (audience = Web client ID) Easier to misconfigure audience/flow
Firebase Pass ID token to FirebaseAuth (GoogleAuthProvider) Older, separate integration path

What you’ll build

We’ll implement two UX paths:

  • Automatic sign-in via Credential Manager bottom sheet (for returning/authorized accounts)
  • A branded “Sign in with Google” button for manual sign-in

We’ll request a Google ID token, parse it with GoogleIdTokenCredential, and explain how to verify it on your backend. We’ll use Kotlin and Jetpack Compose for UI, and show a minimal Java/XML example for classic views.

Prerequisites

  • Android Studio latest stable (Giraffe or newer recommended)
  • Min SDK: 19+ (Credential Manager supports API 19 and above)
  • Basic Kotlin knowledge (Java snippet included)
  • A Google Cloud project to create OAuth client IDs
  • Optional: Firebase project if you want to sign in to Firebase using the Google ID token
  • Optional: Your own backend to verify Google ID tokens and create app sessions

Pre‑flight checklist: How to add Google Sign-In in Android

  • Create two OAuth clients in the same Google Cloud project: Web and Android (package + correct SHA‑1).
  • Put the Web client ID in strings.xml as server_client_id; add INTERNET permission.
  • Auto flow: use GetGoogleIdOption with setFilterByAuthorizedAccounts(true) and optional setAutoSelectEnabled(true).
  • Manual flow: use GetSignInWithGoogleOption behind a “Sign in with Google” button.
  • Parse with GoogleIdTokenCredential; send idToken to your backend over HTTPS.
  • On the server, verify iss, aud = Web client ID, exp, and optionally hd.
  • Handle user cancel/no accounts (NoCredentialException) by showing the manual sign-in button.
  • Firebase users: pass idToken to GoogleAuthProvider; don’t use legacy GoogleSignInClient.
  • Add both debug and release SHA‑1. If using Play App Signing for production, include the App Signing SHA‑1.
  • Test on emulator/physical device with a Google account; keep Google Play services and libraries up to date.

Step 1 — Configure OAuth in Google Cloud (Web & Android client IDs)

This is important. You need two OAuth clients in the same Google Cloud project:

  1. Web client ID — Used by your Android app to request a server-verifiable ID token. You’ll pass this ID as serverClientId.
  2. Android client ID — Tied to your app’s package name and SHA‑1. This allows Google Identity Services to recognize your app.

Create the OAuth clients

  1. Open Google Cloud Console > APIs & Services > Credentials.
  2. Click “Create Credentials” > “OAuth client ID”. If prompted, configure the OAuth consent screen.
  3. Create a Web application client. Copy its Client ID (it ends with .apps.googleusercontent.com). This is your serverClientId.
  4. Create an Android client:
    • Enter your app’s Package name (e.g., com.example.myapp).
    • Add your SHA-1 certificate fingerprint (see below).

How to get the SHA‑1 key in Android Studio

  • Via Gradle: In Android Studio, open the Gradle tool window > Your Module > Tasks > android > signingReport. Check the Variant: debug block for SHA1. Use your release SHA‑1 for production.
  • Via command line (debug): ./gradlew signingReport

Add the SHA‑1 to the Android OAuth client in Cloud Console and save.

Important: Always use the Web client ID for serverClientId when requesting an ID token on Android. This ensures you receive a token your backend can verify.

Step 2 — Add dependencies

In your app module’s build.gradle (Kotlin DSL shown; adjust for Groovy if needed):

// build.gradle.kts (Module)
dependencies {
// Jetpack Credential Manager core
implementation("androidx.credentials:credentials:<latest>")
// Play Services bridge for Google Identity
implementation("androidx.credentials:credentials-play-services-auth:<latest>")
// Google Identity Services (Sign in with Google via Credential Manager)
implementation("com.google.android.libraries.identity.googleid:googleid:<latest>")

// Coroutines for suspend functions
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:<latest>")

// Optional: Firebase Auth (only if you plan to sign in to Firebase)
// implementation(platform("com.google.firebase:firebase-bom:<latest>"))
// implementation("com.google.firebase:firebase-auth-ktx")
}

Check the latest versions in the Jetpack Credentials release notes and Google Identity Services docs before you build.

Step 3 — Add your Web client ID to resources

Create a resource to store your Web client ID:

Code
<!-- app/src/main/res/values/strings.xml -->
<resources>
    <string name="app_name">GoogleSignInDemo</string>
    <string name="server_client_id">YOUR_WEB_CLIENT_ID.apps.googleusercontent.com</string>
</resources>

If you plan to call your backend from the app, ensure you have Internet permission:

<uses-permission android:name="android.permission.INTERNET" />

Step 4 — Implement Google Sign-In with Credential Manager (Kotlin + Compose)

We’ll create two flows:

  • Auto sign-in using GetGoogleIdOption with authorized accounts and optional auto-select
  • Manual button using GetSignInWithGoogleOption

Compose: a branded “Sign in with Google” button

Use Google’s branding guidelines (padding, white button, Google “G” logo). You can use a vector asset for the Google “G” logo.

@Composable
fun GoogleSignInButton(onClick: () -> Unit, enabled: Boolean = true) {
androidx.compose.material3.Button(
onClick = onClick,
enabled = enabled,
colors = androidx.compose.material3.ButtonDefaults.buttonColors(
containerColor = androidx.compose.ui.graphics.Color.White,
contentColor = androidx.compose.ui.graphics.Color.Black
),
border = androidx.compose.foundation.BorderStroke(1.dp, androidx.compose.ui.graphics.Color(0xFFE0E0E0))
) {
androidx.compose.foundation.layout.Row(
verticalAlignment = androidx.compose.ui.Alignment.CenterVertically
) {
androidx.compose.foundation.Image(
painter = painterResource(id = R.drawable.ic_google_logo), // add an asset
contentDescription = "Google logo",
modifier = Modifier.size(18.dp)
)
androidx.compose.foundation.layout.Spacer(Modifier.width(12.dp))
androidx.compose.material3.Text(text = "Sign in with Google")
}
}
}

Kotlin: request an ID token with Credential Manager

The following Activity demonstrates both the auto and manual flows, parses the result with GoogleIdTokenCredential, and exposes the ID token you should send to your backend.

Code
class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            SignInScreen()
        }
    }

    class="cd-annotation">@Composable
    class="cd-keyword cd-access">private fun SignInScreen() {
        val context = LocalContext.current
        val scope = rememberCoroutineScope()
        var status by remember { mutableStateOf("Idle") }
        var email by remember { mutableStateOf<String?>(null) }

        LaunchedEffect(Unit) {
            // Try to auto sign-in returning users
            val result = runCatching { getGoogleIdTokenAuto(context) }
            result.onSuccess { cred ->
                cred?.let {
                    email = it.id // Google account ID (not email); decode payload if needed
                    status = "Auto-signed in (ID token received)"
                    // TODO: send it.idToken to your backend for verification
                }
            }.onFailure {
                // No authorized accounts or user dismissed bottom sheet – fall back to button
                status = "Awaiting manual sign-in"
            }
        }

        androidx.compose.material3.Scaffold { paddingValues ->
            androidx.compose.foundation.layout.Column(
                modifier = Modifier
                    .fillMaxSize()
                    .padding(paddingValues)
                    .padding(24.dp),
                verticalArrangement = androidx.compose.foundation.layout.Arrangement.spacedBy(16.dp)
            ) {
                androidx.compose.material3.Text(text = "Status: $status")
                email?.let { androidx.compose.material3.Text(text = "User: $it") }

                GoogleSignInButton(
                    onClick = {
                        scope.launch {
                            val cred = getGoogleIdTokenManual(context)
                            if (cred != null) {
                                status = "Signed in (ID token received)"
                                // TODO: send cred.idToken to your backend or FirebaseAuth
                            } else {
                                status = "Sign-in canceled or failed"
                            }
                        }
                    }
                )
            }
        }
    }

    class="cd-keyword cd-access">private suspend fun getGoogleIdTokenAuto(context: Context): GoogleIdTokenCredential? {
        val credentialManager = androidx.credentials.CredentialManager.create(context)

        // Auto/authorized accounts flow
        val googleIdOption = com.google.android.libraries.identity.googleid.GetGoogleIdOption.Builder()
            .setServerClientId(context.getString(R.string.server_client_id))
            .setFilterByAuthorizedAccounts(true)
            .setAutoSelectEnabled(true) // auto sign-in when possible
            .build()

        val request = androidx.credentials.GetCredentialRequest.Builder()
            .addCredentialOption(googleIdOption)
            .build()

        return parseGoogleIdToken(
            credentialManager.getCredential(request = request, context = context).credential
        )
    }

    class="cd-keyword cd-access">private suspend fun getGoogleIdTokenManual(context: Context): GoogleIdTokenCredential? {
        val credentialManager = androidx.credentials.CredentialManager.create(context)

        // Explicit “Sign in with Google” button flow
        val signInOption = com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption
            .Builder(context.getString(R.string.server_client_id))
            .build()

        val request = androidx.credentials.GetCredentialRequest.Builder()
            .addCredentialOption(signInOption)
            .build()

        return try {
            parseGoogleIdToken(
                credentialManager.getCredential(request = request, context = context).credential
            )
        } catch (e: androidx.credentials.exceptions.NoCredentialException) {
            null // user canceled or no account available
        }
    }

    class="cd-keyword cd-access">private fun parseGoogleIdToken(credential: androidx.credentials.Credential): GoogleIdTokenCredential? {
        return if (credential is androidx.credentials.CustomCredential &&
            credential.type == com.google.android.libraries.identity.googleid.GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL
        ) {
            com.google.android.libraries.identity.googleid.GoogleIdTokenCredential.createFrom(credential.data)
        } else null
    }
}

At this point, you’re successfully retrieving a Google ID token on Android. Your app should send this token to your backend over HTTPS. On the server, verify:

  • Signature (using Google public keys)
  • Issuer is accounts.google.com or https://accounts.google.com
  • Audience equals your Web client ID
  • Expiry is valid
  • Optional: hd claim matches a Workspace domain you require

This server-side verification is required to trust the sign-in.

Sign-in data flow (Credential Manager + Google Identity)

1) User taps “Sign in with Google” OR is prompted for auto sign‑in
2) CredentialManager opens Google Identity bottom sheet (account picker)
3) User selects account → App receives GoogleIdTokenCredential with idToken
4) App sends idToken to your backend via HTTPS
5) Backend verifies token (iss/aud/exp) using Google public keys
6) Backend creates user session/JWT and returns it to the app
7) App stores session and navigates to the signed‑in experience

Sign out

To sign the user out of your app session, clear your local state and optionally call Credential Manager to reset saved state:

suspend fun signOut(context: Context) {
val cm = androidx.credentials.CredentialManager.create(context)
try {
cm.clearCredentialState(androidx.credentials.ClearCredentialStateRequest())
} catch (e: Exception) {
// It's fine to ignore in most cases; also revoke/clear tokens on your backend
}
}

If you use Firebase Authentication, also call FirebaseAuth.getInstance().signOut().

Step 5 — Optional: Use Firebase Authentication with the ID token

If your app uses Firebase as its backend, you can still use Credential Manager to get the Google ID token and then pass it to Firebase Auth. This keeps your sign-in modern while leveraging Firebase sessions:

Code
// After obtaining GoogleIdTokenCredential (cred) via Credential Manager:
val idToken = cred.idToken
val firebaseCredential = com.google.firebase.auth.GoogleAuthProvider.getCredential(idToken, null)
com.google.firebase.auth.FirebaseAuth.getInstance()
    .signInWithCredential(firebaseCredential)
    .addOnCompleteListener { task ->
        if (task.isSuccessful) {
            // User is signed in to Firebase
        } else {
            // Handle error
        }
    }

Note: Do not use the legacy GoogleSignInClient/GoogleSignInOptions flow with Firebase. Credential Manager is the modern path.

Step 6 — Classic Views: minimal Java example

If you’re learning Java/XML, here’s a minimal Activity using a standard button and the explicit Google sign-in flow. This uses the async API with a callback.

Code
class="cd-keyword cd-access">public class LoginActivity extends AppCompatActivity {

    class="cd-keyword cd-access">private androidx.credentials.CredentialManager credentialManager;

    class="cd-annotation">@Override
    class="cd-keyword cd-access">protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        credentialManager = androidx.credentials.CredentialManager.create(this);

        findViewById(R.id.google_sign_in_button).setOnClickListener(v -> startGoogleSignIn());
    }

    class="cd-keyword cd-access">private void startGoogleSignIn() {
        String serverClientId = getString(R.string.server_client_id);
        com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption signInOption =
                new com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption
                        .Builder(serverClientId)
                        .build();

        androidx.credentials.GetCredentialRequest request =
                new androidx.credentials.GetCredentialRequest.Builder()
                        .addCredentialOption(signInOption)
                        .build();

        credentialManager.getCredentialAsync(
                /* context = */ this,
                /* request = */ request,
                /* cancellationSignal = */ null,
                /* executor = */ androidx.core.content.ContextCompat.getMainExecutor(this),
                new androidx.credentials.CredentialManagerCallback<androidx.credentials.CredentialResponse, androidx.credentials.exceptions.GetCredentialException>() {
                    class="cd-annotation">@Override
                    class="cd-keyword cd-access">public void onResult(androidx.credentials.CredentialResponse response) {
                        androidx.credentials.Credential cred = response.getCredential();
                        if (cred instanceof androidx.credentials.CustomCredential) {
                            androidx.credentials.CustomCredential custom = (androidx.credentials.CustomCredential) cred;
                            if (com.google.android.libraries.identity.googleid.GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL
                                    .equals(custom.getType())) {
                                try {
                                    com.google.android.libraries.identity.googleid.GoogleIdTokenCredential googleCred =
                                            com.google.android.libraries.identity.googleid.GoogleIdTokenCredential
                                                    .createFrom(custom.getData());
                                    String idToken = googleCred.getIdToken();
                                    // TODO: send idToken to your backend or FirebaseAuth
                                } catch (Exception e) {
                                    // Parsing error
                                }
                            }
                        }
                    }

                    class="cd-annotation">@Override
                    class="cd-keyword cd-access">public void onError(androidx.credentials.exceptions.GetCredentialException e) {
                        // User canceled, no accounts, or other error
                    }
                }
        );
    }
}

Example XML layout:

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="center"
android:padding="24dp"
android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
android:id="@+id/google_sign_in_button"
android:text="Sign in with Google"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

Result: what you’ll see

  • Returning users may be signed in automatically or shown a bottom sheet with their Google account.
  • New users can tap the “Sign in with Google” button to pick an account.
  • You’ll receive an ID token in your app; send it to your backend (or Firebase) to finish authentication.
  • On success, navigate to your app’s home screen and store the session returned by your backend.

Troubleshooting and common fixes

  • NoCredentialException: The user canceled or no authorized accounts are available. Show the manual “Sign in with Google” button.
  • Token audience mismatch: Verify that the token’s audience matches your Web client ID, not the Android client ID.
  • SHA‑1 mismatch: Ensure the SHA‑1 in your Android OAuth client matches the keystore you’re using (debug vs release). Re-run signingReport and update Cloud Console if needed.
  • Consent screen errors: Complete OAuth consent screen setup in Google Cloud. If your app is unverified and requests sensitive scopes, follow verification steps.
  • Network/403: Check that both Web and Android clients are in the same Google Cloud project. Ensure you’ve enabled the necessary Google APIs.
  • Firebase errors: If using Firebase, keep your Firebase BoM and Auth SDK up to date. Use the ID token from Credential Manager with GoogleAuthProvider, not legacy GoogleSignInClient.

FAQ: People also ask

What is Google Sign-In in Android and why should I use it?

It lets users log in with their Google account, removing the need to manage passwords and improving conversion. The modern approach (Credential Manager + Google Identity Services) also integrates with passkeys/passwords for a smoother, safer experience.

Do I need Firebase to add Google Sign-In to my Android app?

No. You can use Credential Manager to get an ID token and verify it on your own backend. Firebase is optional if you want Firebase-managed sessions; if you use it, pass the ID token to FirebaseAuth.

How do I get the SHA-1 key for Google Sign-In in Android Studio?

Run the signingReport Gradle task (in Android Studio’s Gradle window or via ./gradlew signingReport). Use the SHA‑1 from your debug or release keystore as appropriate and add it to the Android OAuth client in Google Cloud.

How can I add Google Sign-In in Android using Kotlin or Java?

Use Jetpack Credential Manager with Google Identity Services. In Kotlin, call the suspend getCredential API; in Java, use getCredentialAsync with a callback. Parse the result with GoogleIdTokenCredential and send the idToken to your backend or Firebase.

Why is Google Sign-In not working in my Android app and how do I fix it?

Common causes include SHA‑1 mismatch, using the Android client ID instead of the Web client ID as serverClientId, unconfigured consent screen, or outdated libraries. Check logs, verify OAuth setup, and use the troubleshooting guide linked below.

Key takeaways

  • The best way for 2026 is Credential Manager + Google Identity Services (googleid).
  • Always request the ID token using your Web client ID (serverClientId).
  • Verify the ID token on your backend before creating a session.
  • Offer both auto sign-in and a “Sign in with Google” button for best UX.
  • Avoid legacy APIs like GoogleSignInClient and One Tap; they’ve been replaced by Credential Manager flows.

Sources / Further reading

Wrapping up

That’s how to add Google Sign-In in Android using the newest, officially recommended approach. If you’re building a new app or updating an existing one, move to Credential Manager to simplify your auth code, support passkeys alongside Google, and improve sign-in conversion. Pair it with a secure backend that verifies ID tokens, or plug it into Firebase Auth if you prefer. Happy building!

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted