On this page
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
Setup
- Create a Firebase project, register your Android app, and add
google-services.json. - Enable the providers you need (Email/Password, Google) in Authentication โ Sign-in method.
- For Google sign-in, add your app's SHA-1 and SHA-256 fingerprints (debug and release, plus Play App Signing) in project settings.
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
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
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
@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
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
| Exception | Meaning | Message |
|---|---|---|
FirebaseAuthInvalidCredentialsException | Wrong password or malformed email | "Email or password is incorrect" |
FirebaseAuthInvalidUserException | User disabled or deleted | "This account isn't available" |
FirebaseAuthUserCollisionException | Email already registered | "An account already exists. Try signing in." |
FirebaseAuthWeakPasswordException | Password too weak | Show the reason from the exception |
FirebaseNetworkException | No 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.
Walzi4K wallpapers for lock and home screenGet it โธ
NotiVaultNotification history: recover dismissed notificationsGet it โธ
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.