Firebase Auth (Java)
Every recipe app eventually needs the question "whose recipe is this?" answered. Firebase Authentication gives RecipeBox a ready-made user account system — sign-up, sign-in, session handling — without building and hosting a custom auth backend of our own.
Enabling Email/Password Sign-In
In the Firebase Console, open Authentication → Sign-in method and enable the Email/Password provider. This is a one-time console setting — no extra Gradle dependency beyond firebase-auth, already pinned by the BoM from Setup & Analytics:
dependencies {
implementation platform('com.google.firebase:firebase-bom:33.1.2')
implementation 'com.google.firebase:firebase-auth'
}
Creating a New Account
private void registerAccount(String email, String password) {
FirebaseAuth.getInstance()
.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
Log.d("Auth", "Account created, uid=" + user.getUid());
goToRecipeList();
} else {
Log.w("Auth", "Sign-up failed", task.getException());
showError(task.getException().getMessage());
}
});
}
- createUserWithEmailAndPassword() doesn't block or return a result directly — it returns a Task<AuthResult> immediately and does the network work in the background.
- addOnCompleteListener(task -> { ... }) is the callback that fires once that background work finishes, whether it succeeded or failed.
- task.isSuccessful() tells you which branch you're in; task.getException() gives the failure reason (e.g. "email already in use", "weak password") when it isn't.
- This callback-based Task pattern is Firebase's standard shape for every asynchronous Java call in this section — the same pattern reappears for sign-in, Firestore reads/writes, and more.
Signing In an Existing User
private void login(String email, String password) {
FirebaseAuth.getInstance()
.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
goToRecipeList();
} else {
showError("Invalid email or password");
}
});
}
Checking the Current User & Observing State
To decide whether to show a login screen or go straight to the recipe list, check for a signed-in user at startup:
FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser();
if (currentUser != null) {
goToRecipeList();
} else {
goToLoginScreen();
}
For ongoing changes — sign-in, sign-out, token refresh — attach an AuthStateListener:
private final FirebaseAuth.AuthStateListener authListener = firebaseAuth -> {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
Log.d("Auth", "Signed in as " + user.getUid());
} else {
Log.d("Auth", "Signed out");
}
};
@Override
protected void onStart() {
super.onStart();
FirebaseAuth.getInstance().addAuthStateListener(authListener);
}
@Override
protected void onStop() {
super.onStop();
FirebaseAuth.getInstance().removeAuthStateListener(authListener);
}
Signing Out
FirebaseAuth.getInstance().signOut();
// AuthStateListener fires again here, now with getCurrentUser() == null
Other Sign-In Providers
Email/password is the simplest starting point, but Firebase Auth supports several other providers behind the same FirebaseAuth API — most notably Google Sign-In (one-tap sign-in using the user's existing Google account) and phone number authentication (an SMS verification code in place of a password). Both plug into the same account system; only the initial credential step differs.