Authenticating Android users with Firebase email and password
Firebase Authentication gives an Android app a reliable way to register, sign in, sign out and restore user sessions without building a password database from scratch. For a beginner project, it fits naturally beside Firebase Firestore, Realtime Database or a simple profile screen.
This tutorial uses Kotlin, Android Studio and the Firebase BoM. The same flow works for a practice app built in Sydney, a student project in Melbourne or a small local service preparing for Australian customers. The interface can remain simple while Firebase handles password storage, token management and authentication state.
Email and password sign-in is useful when an app needs a familiar account method without immediately adding Google, Apple or phone-number login. Users can create an account with an email address, receive clear validation messages and return to an authenticated screen after reopening the app.
Before coding, create a Firebase project, register the Android package name and download google-services.json. Firebase services communicate over the internet, so test on both an emulator and a physical device. A user connected through a typical NBN home network should see the same authentication behaviour as someone testing on mobile data in regional Queensland.
| Approach | Best for | Main benefit | Limitation |
|---|---|---|---|
| Firebase email/password | Standard account screens | Quick setup and managed credentials | Requires Firebase configuration |
| Google sign-in | Fast social login | Less typing for users | Extra provider setup |
| Phone authentication | Number-based services | Useful when phone identity matters | SMS cost and regional delivery issues |
| Custom backend | Full control over accounts | Flexible business rules | More security and maintenance work |
Prepare Firebase and the Android project
Open the Firebase console and create a project, then add your Android application using the exact package name from app/build.gradle or build.gradle.kts. Download the configuration file and place it inside the app module directory. In Firebase Authentication, open the Sign-in method page and enable Email/Password.
Add the Google services plugin and Firebase Authentication dependency. With a modern Gradle Kotlin setup, the module dependencies can look like this:
plugins {
id("com.android.application")
id("com.google.gms.google-services")
}
dependencies {
implementation(platform("com.google.firebase:firebase-bom:33.5.1"))
implementation("com.google.firebase:firebase-auth")
}
Use the current Firebase BoM version recommended by the official documentation when starting a new project. The BoM keeps Firebase library versions compatible, while the Google services plugin reads google-services.json during the build.
Build a clear registration and login screen
A basic XML layout can contain two EditText controls and three buttons: one for registering, one for signing in and one for signing out. Set the email field to android:inputType="textEmailAddress" and the password field to android:inputType="textPassword". Add labels and error text so users are not left guessing why an action failed.
For Australian users, write messages in plain English rather than exposing raw exception names. “Enter a valid email address” is more useful than a technical Firebase error. You may also include a password rule such as eight characters minimum, while remembering that Firebase still validates the account on its own servers.
Never place a real password, API secret or test credential in source control. The Firebase configuration file contains project identifiers, but account protection depends on correct Firebase rules, secure release practices and careful handling of authentication results.
Register users with Firebase Auth
Create a Firebase Auth instance in your activity or, preferably, in a view model or repository:
private val auth: FirebaseAuth by lazy {
FirebaseAuth.getInstance()
}
The registration button can validate the fields before calling createUserWithEmailAndPassword:
private fun register(email: String, password: String) {
if (email.isBlank() || password.length < 8) {
showMessage("Enter an email and an eight-character password")
return
}
auth.createUserWithEmailAndPassword(email.trim(), password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
showMessage("Account created")
openHomeScreen()
} else {
showMessage(task.exception?.localizedMessage ?: "Registration failed")
}
}
}
Firebase signs the new user in immediately after successful registration. That means the app can move directly to a home screen, profile page or shopping view. If the application stores extra profile details, save them under the authenticated user’s UID rather than using the email address as a document key.
Sign users in and restore sessions
Existing users sign in with signInWithEmailAndPassword. Keep the button disabled while the request is running, then enable it after the task completes. This prevents accidental duplicate requests when a user taps repeatedly on a slower connection.
private fun signIn(email: String, password: String) {
auth.signInWithEmailAndPassword(email.trim(), password)
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
openHomeScreen()
} else {
showMessage("Email or password was not accepted")
}
}
}
Firebase persists the current authentication state between app launches. At startup, check auth.currentUser and route the user to the correct screen:
override fun onStart() {
super.onStart()
if (auth.currentUser != null) {
openHomeScreen()
}
}
A signed-in session should not automatically grant access to every part of an app. Use the UID to load the user’s own data, and require fresh authentication for particularly sensitive actions such as changing an email address or deleting an account.
Handle errors, recovery and connectivity
Common errors include an invalid email, weak password, existing account, incorrect credentials and a temporary network failure. Firebase exposes exception information through the completed task. Map known cases to friendly messages and avoid confirming whether a particular email address is registered when account privacy matters.
Add a password reset option with sendPasswordResetEmail:
private fun resetPassword(email: String) {
if (email.isBlank()) {
showMessage("Enter your account email first")
return
}
auth.sendPasswordResetEmail(email.trim())
.addOnCompleteListener { task ->
showMessage(
if (task.isSuccessful) {
"Check your email for reset instructions"
} else {
"We could not send the reset email"
}
)
}
}
Authentication testing can expose problems that do not appear in an emulator. Check airplane mode, slow mobile data and a home router with several connected devices. If your test handset struggles to reach Firebase over Wi-Fi, these Wi-Fi range tips may help diagnose coverage issues before you blame the app.
Protect data and test the complete flow
Firebase Authentication confirms identity, but it does not automatically secure Firestore or Realtime Database data. Database security rules should compare the requested record with request.auth.uid, ensuring that one user cannot read another user’s private profile. Test rules with both an authenticated user and an unauthenticated request.
Run a practical test sequence: register a new account, close and reopen the app, sign out, sign in again, request a password reset and try invalid values. Test Australian-style addresses such as name@example.com.au, but do not assume the domain proves a user’s location. Also test on devices commonly used in Brisbane, Perth and Adelaide, where screen sizes and network conditions can differ.
Useful implementation checks include:
- Validate email and password before every Firebase request.
- Display a progress indicator while authentication is running.
- Keep Firebase libraries aligned through the Firebase BoM.
- Use the authenticated UID for user-owned records.
- Provide sign-out and password-reset actions.
- Test offline, slow-network and invalid-credential states.
- Avoid revealing sensitive account details in error messages.
A clean authentication flow makes later features easier to add. Once registration and login work, you can connect the user identity to a profile document, favourites list, orders or preferences while keeping access controlled by Firebase security rules.
Add sign-out and maintainable architecture
Signing out requires only one Firebase call, but the app should also clear sensitive screen content and return to the login activity:
private fun signOut() {
auth.signOut()
startActivity(Intent(this, LoginActivity::class.java))
finish()
}
For a small tutorial, activity callbacks are enough. As the project grows, move authentication operations into a repository and expose loading, success and error states through a ViewModel. This keeps rotation changes from restarting requests and makes the code easier to test.
Finally, separate authentication from presentation. The login screen collects input, the view model manages state, and Firebase Auth performs the identity operation. That structure gives an Android Open Tutorials project a solid base for adding Google sign-in, email verification or account deletion later without rewriting every screen.