๐Ÿ”Œ APIs, Databases, and Backend Integration

Firebase Authentication in Android

Firebase Authentication gives Android apps secure sign-in without building an auth backend: email and password, Google, phone and more. This guide implements email and Google sign-in with modern APIs, exposes auth state as a Flow, and connects it securely to your own server.

โœ๏ธ Yunok Tech ๐Ÿ“… Updated โฑ 3 min read ๐ŸŽฏ Beginner
On this page
  1. How it fits together
  2. Setup
  3. An AuthRepository
  4. Google sign-in with Credential Manager
  5. Routing by auth state
  6. Calling your own backend securely
  7. Errors and UX
  8. Common setups
  9. Common mistakes
  10. Frequently asked questions
  11. Conclusion

Rolling your own authentication means hashing passwords, securing reset flows, rate-limiting attacks and managing sessions, all of which are easy to get dangerously wrong. Firebase Authentication handles these as a managed service, while your app focuses on the sign-in experience.

How it fits together

Firebase Authentication sign-in and backend verification The app gets credentials from the user, via email and password or Google through Credential Manager, and signs in with Firebase Auth. Firebase returns a user and an ID token. The app sends the ID token to your backend, which verifies it with the Firebase Admin SDK before serving data. Credentialsemail ยท Google Firebase Authuser + ID token Your appBearer ID token Your backendverifies token Never trust a user ID sent by the client. Verify the signed ID token on the server.
Firebase proves who the user is. Your backend checks that proof on every request.

Setup

  1. Create a Firebase project, register your Android app, and add google-services.json.
  2. Enable the providers you need (Email/Password, Google) in Authentication โ†’ Sign-in method.
  3. For Google sign-in, add your app's SHA-1 and SHA-256 fingerprints (debug and release, plus Play App Signing) in project settings.
app/build.gradle.ktsGradle KTS
dependencies {
    implementation(platform("com.google.firebase:firebase-bom:<latest>"))
    implementation("com.google.firebase:firebase-auth")
    // Google sign-in through Credential Manager
    implementation("androidx.credentials:credentials:<version>")
    implementation("androidx.credentials:credentials-play-services-auth:<version>")
    implementation("com.google.android.libraries.identity.googleid:googleid:<version>")
}

An AuthRepository

AuthRepository.ktKotlin
class AuthRepository(private val auth: FirebaseAuth = Firebase.auth) {

    /** Emits the current user (or null) and every change. */
    val currentUser: Flow<FirebaseUser?> = callbackFlow {
        val listener = FirebaseAuth.AuthStateListener { trySend(it.currentUser) }
        auth.addAuthStateListener(listener)
        awaitClose { auth.removeAuthStateListener(listener) }
    }

    suspend fun signIn(email: String, password: String): FirebaseUser =
        auth.signInWithEmailAndPassword(email.trim(), password).await().user!!

    suspend fun register(email: String, password: String): FirebaseUser {
        val user = auth.createUserWithEmailAndPassword(email.trim(), password).await().user!!
        user.sendEmailVerification().await()
        return user
    }

    suspend fun sendPasswordReset(email: String) { auth.sendPasswordResetEmail(email.trim()).await() }

    suspend fun signInWithGoogleIdToken(idToken: String): FirebaseUser =
        auth.signInWithCredential(GoogleAuthProvider.getCredential(idToken, null)).await().user!!

    /** Fresh ID token for calls to your own backend. */
    suspend fun idToken(forceRefresh: Boolean = false): String? =
        auth.currentUser?.getIdToken(forceRefresh)?.await()?.token

    fun signOut() = auth.signOut()
}

await() comes from kotlinx-coroutines-play-services. On success, Firebase returns a non-null user, which is why !! is acceptable here.

Google sign-in with Credential Manager

GoogleSignIn.ktKotlin
suspend fun requestGoogleIdToken(activity: Activity, webClientId: String): String? {
    val credentialManager = CredentialManager.create(activity)
    val option = GetGoogleIdOption.Builder()
        .setServerClientId(webClientId)              // "Web client" ID from your Firebase/Google Cloud project
        .setFilterByAuthorizedAccounts(false)        // show all Google accounts on the device
        .build()
    val request = GetCredentialRequest.Builder().addCredentialOption(option).build()

    return try {
        val credential = credentialManager.getCredential(activity, request).credential
        if (credential is CustomCredential && credential.type == GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL) {
            GoogleIdTokenCredential.createFrom(credential.data).idToken
        } else null
    } catch (e: GetCredentialCancellationException) {
        null                                          // user dismissed the sheet
    } catch (e: GetCredentialException) {
        null                                          // no accounts, misconfiguration, etc.
    }
}
// val token = requestGoogleIdToken(activity, getString(R.string.default_web_client_id))
// token?.let { authRepository.signInWithGoogleIdToken(it) }

Routing by auth state

AppRoot.ktKotlin
@Composable
fun AppRoot(authRepository: AuthRepository) {
    val user by authRepository.currentUser.collectAsStateWithLifecycle(initialValue = null)
    if (user == null) SignInFlow() else MainApp()
}

In production, distinguish "unknown, still loading" from "signed out" to avoid a flash of the sign-in screen at startup.

Calling your own backend securely

Attach the Firebase ID tokenKotlin
class FirebaseTokenInterceptor(private val auth: FirebaseAuth) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        // getIdToken may refresh over the network; Tasks.await blocks this OkHttp thread (not main).
        val token = auth.currentUser?.let { Tasks.await(it.getIdToken(false)).token }
        val request = chain.request().newBuilder().apply {
            if (token != null) header("Authorization", "Bearer $token")
        }.build()
        return chain.proceed(request)
    }
}

Your server must verify the ID token with the Firebase Admin SDK and use the verified UID, never a user ID sent in the request body. If you use Firestore or Realtime Database, protect data with Security Rules based on request.auth.

Errors and UX

ExceptionMeaningMessage
FirebaseAuthInvalidCredentialsExceptionWrong password or malformed email"Email or password is incorrect"
FirebaseAuthInvalidUserExceptionUser disabled or deleted"This account isn't available"
FirebaseAuthUserCollisionExceptionEmail already registered"An account already exists. Try signing in."
FirebaseAuthWeakPasswordExceptionPassword too weakShow the reason from the exception
FirebaseNetworkExceptionNo connectivity"You're offline"

Depending on your project's settings, Firebase may return a generic invalid-credential error instead of revealing whether an email exists. Design messages that work either way.

Common setups

Consumer app

Google sign-in as the primary option, email as a fallback, and optional anonymous auth to let users try first and link later.

App with its own API

Firebase for identity, your backend verifying ID tokens and storing app data.

Sensitive actions

Re-authenticate before changing email or deleting an account, and consider biometrics for local unlock.

Common mistakes

  • Missing release or Play App Signing SHA fingerprints, so Google sign-in works in debug but fails in production.
  • Trusting client-provided user IDs on the server.
  • Storing passwords locally.
  • Not offering account deletion. Google Play requires apps that allow account creation to provide account deletion.

Frequently asked questions

Does Firebase Auth keep users signed in?

Yes. Sessions persist across app restarts until the user signs out or the session is revoked. ID tokens refresh automatically.

Should I use the old Google Sign-In SDK?

Google recommends Credential Manager for new implementations of Sign in with Google on Android.

Is Firebase Auth free?

Many providers have a generous free tier, but some features (such as phone authentication and enterprise features) have usage-based pricing. Check current Firebase pricing.

Conclusion

Firebase Authentication provides managed, secure identity. Expose auth state as a Flow, use Credential Manager for Google sign-in, send ID tokens to your backend and verify them server-side, and map auth errors to clear messages.

Next step: reach users with Firebase Cloud Messaging and Push Notifications.

Official references

๐Ÿ“ฑ Apps built by Yunok Tech

Real Android apps on Google Play, free to download.

See all our apps โ†’

Ready to build real Android applications?

Networking, persistence and offline sync are where real apps get complicated. Practise building a data layer that handles slow networks, failures and caching, not just the happy path.

Move beyond theory and strengthen your Android development skills with Yunoktech's Android course. Learn core concepts, practical implementation, modern Android development techniques, and the reasoning behind building maintainable applications.

Explore the Android course and take your next step as an Android developer.

Share: LinkedIn X / Twitter WhatsApp