DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Firebase Auth + Jetpack Compose — Email & Google Sign-In

Firebase Authentication provides secure user management with minimal setup.

AuthRepository with CallbackFlow

class AuthRepository(private val auth: FirebaseAuth) {
    fun signInWithEmail(email: String, password: String): Flow<AuthResult> = callbackFlow {
        auth.signInWithEmailAndPassword(email, password)
            .addOnSuccessListener { trySend(AuthResult.Success(it.user)) }
            .addOnFailureListener { trySend(AuthResult.Error(it.message ?: "Unknown error")) }
    }

    fun signUpWithEmail(email: String, password: String): Flow<AuthResult> = callbackFlow {
        auth.createUserWithEmailAndPassword(email, password)
            .addOnSuccessListener { trySend(AuthResult.Success(it.user)) }
            .addOnFailureListener { trySend(AuthResult.Error(it.message ?: "Unknown error")) }
    }
}
Enter fullscreen mode Exit fullscreen mode

AuthStateListener as Flow

val currentUserFlow: Flow<FirebaseUser?> = callbackFlow {
    val listener = AuthStateListener { auth ->
        trySend(auth.currentUser)
    }
    auth.addAuthStateListener(listener)
    awaitClose { auth.removeAuthStateListener(listener) }
}
Enter fullscreen mode Exit fullscreen mode

Sealed AuthUiState

sealed class AuthUiState {
    object Idle : AuthUiState()
    object Loading : AuthUiState()
    data class Success(val user: FirebaseUser) : AuthUiState()
    data class Error(val message: String) : AuthUiState()
}
Enter fullscreen mode Exit fullscreen mode

LoginScreen with Error & Loading States

@Composable
fun LoginScreen(viewModel: AuthViewModel) {
    val uiState by viewModel.authState.collectAsState()
    var email by remember { mutableStateOf("") }
    var password by remember { mutableStateOf("") }

    Column(Modifier.padding(16.dp)) {
        OutlinedTextField(
            value = email,
            onValueChange = { email = it },
            label = { Text("Email") }
        )
        OutlinedTextField(
            value = password,
            onValueChange = { password = it },
            label = { Text("Password") },
            visualTransformation = PasswordVisualTransformation()
        )

        when(uiState) {
            is AuthUiState.Loading -> CircularProgressIndicator()
            is AuthUiState.Error -> Text((uiState as AuthUiState.Error).message, color = Color.Red)
            is AuthUiState.Success -> Text("Logged in!", color = Color.Green)
            else -> {}
        }

        Button(onClick = { viewModel.signIn(email, password) }) {
            Text("Sign In")
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Integrate Google Sign-In via GoogleSignInClient and FirebaseAuth.signInWithCredential() for seamless authentication.


8 production-ready Android app templates on Gumroad.
Browse templatesGumroad

Top comments (0)