visit
Firebase is a mobile(Android or iOS) and web application development platform that provides a suite of cloud-based tools and services offered by
In this tutorial, we'll build a simple Java Android app with Firebase for authentication that allows users to create accounts. sign in and sign out of the accounts. We'll also cover how to use your Android phone as an emulator.
To use an emulator, follow these steps:
To connect to a physical Android device, follow the following steps:
On your Android device( phone or tablet), open the settings and navigate to `About phone`. Click on 'Software Information'.
In this step, we'll create the user interface and design. Navigate to the app/res
folder; this is where most of the user interface changes will take place.
app/res/values/colors.xml
file and add the colour codes for our app.<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="slateblue"> #6F58C9</color>
<color name="black">#FF000000</color>
<color name="white"> #FFFFFFFF</color>
</resources>
app/res/values
folder, create a new XML file and name styles.xml
this is where we’ll add styles for the app to improve modularity and reusability across components or layouts.res
folder, navigate to the drawable
folder, right-click on it, click New
," and select Drawable Resource File
. Save the name as custom_edittext
and change the root element from selector to shape, then click 'OK'.<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="//schemas.android.com/apk/res/android" android:shape="rectangle">
<stroke
android:width="2dp"
android:color="@color/slateblue"/>
<corners
android:radius="30dp"/>
</shape>
Add vector images:
res
folder, navigate to the ‘drawable' folder, right-click on it, click 'New," and select 'Vector Asset'. Here we'll download vector images for the forms.android:tint="@color/slateblue"
.
app/java/com.example.firebaseauthapp
folder, right-click on it, and select New
. Scroll down and click 'Activity," then select 'Empty Activity'.SignUpActivity
, check the box that says Launcher Activity
, and then click 'Finish'.
Repeat the steps excluding making it a launcher activity, this time for LoginActivity
.
Open the app/manifests/AndroidManifest.xml
file and remove the intent filter from the Main Activity block, also change the android:exported="true"
to android:exported="false"
. It should look like this:
<activity
android:name=".LoginActivity"
android:exported="false" />
<activity
android:name=".SignUpActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:exported="false">
</activity>
app/res/layout/activity_main.xml
file.<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="//schemas.android.com/apk/res/android"
xmlns:app="//schemas.android.com/apk/res-auto"
xmlns:tools="//schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textColor="@color/slateblue"
android:textSize="26sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
app/res/layout/activity_sign_up.xml
file.<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="//schemas.android.com/apk/res/android"
xmlns:app="//schemas.android.com/apk/res-auto"
xmlns:tools="//schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SignUpActivity">
<androidx.cardview.widget.CardView
android:id="@+id/cardView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="30dp"
app:cardCornerRadius="30dp"
app:cardElevation="20dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_horizontal"
android:padding="24dp"
android:background="@drawable/custom_edittext">
<TextView
style="@style/TitleText"
android:text="Sign Up"/>
<EditText
style="@style/EditTextView"
android:id="@+id/signup_email"
android:hint="Email"
android:drawableLeft="@drawable/baseline_person_24"
android:textColor="@color/black" />
<EditText
style="@style/EditTextView"
android:id="@+id/signup_password"
android:hint="Password"
android:drawableLeft="@drawable/baseline_lock_person_24"
android:textColor="@color/black" />
<Button
style="@style/ButtonStyle"
android:id="@+id/signup_button"
android:text="Sign Up"
app:cornerRadius = "20dp"
/>
<TextView
style="@style/LoginRedirectText"
android:id="@+id/loginRedirectText"
android:text="Already a user. Login" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
app/res/layout/activity_login.xml
.<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="//schemas.android.com/apk/res/android"
xmlns:app="//schemas.android.com/apk/res-auto"
xmlns:tools="//schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".LoginActivity">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="30dp"
app:cardCornerRadius="30dp"
app:cardElevation="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_horizontal"
android:padding="24dp"
android:background="@drawable/custom_edittext">
<TextView
style="@style/TitleText"
android:text="Login"/>
<EditText
style="@style/EditTextView"
android:id="@+id/login_email"
android:hint="Email"
android:drawableLeft="@drawable/baseline_person_24"
android:textColor="@color/black" />
<EditText
style="@style/EditTextView"
android:id="@+id/login_password"
android:hint="Password"
android:drawableLeft="@drawable/baseline_lock_person_24"
android:textColor="@color/black" />
<Button
style="@style/ButtonStyle"
android:text="Login"
android:id="@+id/login_button"
app:cornerRadius="20dp" />
<TextView
style="@style/LoginRedirectText"
android:id="@+id/signUpRedirectText"
android:text="Not yet registered? Sign Up" />
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
app/res/values/styles.xml
.<resources>
<style name="TitleText">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textSize">36sp</item>
<item name="android:textAlignment">center</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/slateblue</item>
</style>
<style name="EditTextView">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">50dp</item>
<item name="android:background">@drawable/custom_edittext</item>
<item name="android:layout_marginTop">20dp</item>
<item name="android:padding">8dp</item>
<item name="android:drawablePadding">8dp</item>
</style>
<style name="ButtonStyle">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">60dp</item>
<item name="android:textSize">18sp</item>
<item name="android:layout_marginTop">30dp</item>
<item name="android:backgroundTint">@color/slateblue</item>
</style>
<style name="LoginRedirectText">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_gravity">center</item>
<item name="android:padding">8dp</item>
<item name="android:layout_marginTop">10dp</item>
<item name="android:textColor">@color/slateblue</item>
<item name="android:textSize">18sp</item>
</style>
</resources>
Hey guys, you might notice that I left the app:cornerRadius
button in the layout files instead of adding it to the styles.xml
file. This is because app:cornerRadius
attribute is specific to the CardView
widget and is not a standard attribute for the Button
widget.
Once you do that, you'll see a side pop-up bar. Scroll through and click on Authentication, and then select 'Authentication using a custom authentication system'.
Remember, this is a Java Android tutorial, so make sure the option you're selecting does not use KOTLIN.
signingReport
on the search bar and press enter.Note: If you have more than one app on the project, go to the project overview, then click on 'app' and select which app you want to authenticate.
package com.example.firebaseauthapp;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
public class SignUpActivity extends AppCompatActivity {
// Declare necessary variables
private FirebaseAuth auth;
private EditText signupEmail, signupPassword;
private Button signupButton;
private TextView loginRedirectText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_up);
// Initialize the FirebaseAuth instance in onCreate()
auth = FirebaseAuth.getInstance();
signupEmail = findViewById(R.id.signup_email);
signupPassword = findViewById(R.id.signup_password);
signupButton = findViewById(R.id.signup_button);
loginRedirectText = findViewById(R.id.loginRedirectText);
signupButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String user = signupEmail.getText().toString().trim();
String pass = signupPassword.getText().toString().trim();
// Set up Validation Logic
if (user.isEmpty()) {
signupEmail.setError("Email cannot be empty");
} else if (pass.isEmpty()) {
signupPassword.setError("Password cannot be empty");
} else {
auth.createUserWithEmailAndPassword(user, pass)
.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Toast.makeText(SignUpActivity.this, "Signup Successful", Toast.LENGTH_SHORT).show();
startActivity(new Intent(SignUpActivity.this, LoginActivity.class));
} else {
Toast.makeText(SignUpActivity.this, "Signup Failed: " + task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
}
});
// Set up Success and Failure Listeners
loginRedirectText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(SignUpActivity.this, LoginActivity.class));
}
});
}
}
package com.example.firebaseauthapp;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
public class LoginActivity extends AppCompatActivity {
// Declare necessary variables
private FirebaseAuth auth;
private EditText loginEmail, loginPassword;
private TextView signupRedirectText;
private Button loginButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// Initialize Firebase Auth instance
auth = FirebaseAuth.getInstance();
loginEmail = findViewById(R.id.login_email);
loginPassword = findViewById(R.id.login_password);
loginButton = findViewById(R.id.login_button);
signupRedirectText = findViewById(R.id.signupRedirectText);
loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String email = loginEmail.getText().toString().trim();
String pass = loginPassword.getText().toString().trim();
if (email.isEmpty()) {
loginEmail.setError("Email cannot be empty");
} else if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) {
loginEmail.setError("Please enter a valid email");
} else if (pass.isEmpty()) {
loginPassword.setError("Password cannot be empty");
} else {
auth.signInWithEmailAndPassword(email, pass)
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
Toast.makeText(LoginActivity.this, "Login Successful", Toast.LENGTH_SHORT).show();
startActivity(new Intent(LoginActivity.this, MainActivity.class));
finish();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(LoginActivity.this, "Login Failed: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
});
signupRedirectText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(LoginActivity.this, SignUpActivity.class));
}
});
}
}