A Complete Guide - Android Firebase Integration Auth, Firestore, Cloud Messaging
Online Code run
Step-by-Step Guide: How to Implement Android Firebase Integration Auth, Firestore, Cloud Messaging
Prerequisites
- Android Studio: Make sure you have the latest version of Android Studio installed.
- Firebase Account: You need a Firebase account and a project set up in the Firebase Console.
Step 1: Create a New Android Project
- Open Android Studio and select "New Project".
- Choose "Empty Activity" and click "Next".
- Configure your project:
- Name:
FirebaseIntegration
- Package name:
com.example.firebaseintegration
- Save location: Choose a directory.
- Language: Java/Kotlin (This guide will use Java).
- Minimum API level: Choose an appropriate level.
- Name:
- Click "Finish" to create the project.
Step 2: Set Up Firebase Project
- Go to the Firebase Console (
- Click on "Add Project" and follow the prompts to create a new Firebase project.
- Once the project is created, click on "Android" to add an Android app to the project.
- Register the app:
- Android package name: Enter
com.example.firebaseintegration
. - Download the
google-services.json
file and place it in theapp
directory of your Android project.
- Android package name: Enter
- Add Firebase SDK dependencies to your project:
- Open
build.gradle
(Project level) and add the Google services classpath:buildscript { dependencies { ... classpath 'com.google.gms:google-services:4.3.15' } }
- Open
build.gradle
(App level) and apply the Google services plugin:apply plugin: 'com.android.application' apply plugin: 'com.google.gms.google-services' dependencies { implementation platform('com.google.firebase:firebase-bom:32.4.1') implementation 'com.google.firebase:firebase-auth:22.3.1' implementation 'com.google.firebase:firebase-firestore:24.9.1' implementation 'com.google.firebase:firebase-messaging:23.3.1' }
- Open
- Sync your project with Gradle files.
Step 3: Set Up Firebase Authentication
Enable Email/Password Authentication:
- In the Firebase Console, go to "Authentication" > "Sign-in method".
- Enable "Email/Password".
Create a Registration Activity:
- Create a new activity
RegisterActivity.java
. - Add the following code to
activity_register.xml
:<LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <EditText android:id="@+id/email" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Email" /> <EditText android:id="@+id/password" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Password" android:inputType="textPassword" /> <Button android:id="@+id/registerButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Register" /> </LinearLayout>
- Add the following code to
RegisterActivity.java
:import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; 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 RegisterActivity extends AppCompatActivity { private EditText emailEditText, passwordEditText; private Button registerButton; private FirebaseAuth mAuth; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_register); emailEditText = findViewById(R.id.email); passwordEditText = findViewById(R.id.password); registerButton = findViewById(R.id.registerButton); mAuth = FirebaseAuth.getInstance(); registerButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String email = emailEditText.getText().toString(); String password = passwordEditText.getText().toString(); mAuth.createUserWithEmailAndPassword(email, password) .addOnCompleteListener(new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (task.isSuccessful()) { Toast.makeText(RegisterActivity.this, "Registration successful!", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(RegisterActivity.this, LoginActivity.class); startActivity(intent); finish(); } else { Toast.makeText(RegisterActivity.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show(); } } }); } }); } }
- Create a new activity
Create a Login Activity:
- Create a new activity
LoginActivity.java
. - Add the following code to
activity_login.xml
:<LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <EditText android:id="@+id/email" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Email" /> <EditText android:id="@+id/password" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Password" android:inputType="textPassword" /> <Button android:id="@+id/loginButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Login" /> </LinearLayout>
- Add the following code to
LoginActivity.java
:import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; 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 LoginActivity extends AppCompatActivity { private EditText emailEditText, passwordEditText; private Button loginButton; private FirebaseAuth mAuth; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); emailEditText = findViewById(R.id.email); passwordEditText = findViewById(R.id.password); loginButton = findViewById(R.id.loginButton); mAuth = FirebaseAuth.getInstance(); loginButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String email = emailEditText.getText().toString(); String password = passwordEditText.getText().toString(); mAuth.signInWithEmailAndPassword(email, password) .addOnCompleteListener(new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (task.isSuccessful()) { Toast.makeText(LoginActivity.this, "Login successful!", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(LoginActivity.this, MainActivity.class); startActivity(intent); finish(); } else { Toast.makeText(LoginActivity.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show(); } } }); } }); } }
- Create a new activity
Step 4: Set Up Firebase Firestore
Enable Firestore in Firebase Console:
- Go to "Firestore Database" and click "Create database".
- Choose "Start in Test Mode" for the initial setup.
Add Firestore to MainActivity:
- Create a new activity
MainActivity.java
. - Add the following code to
activity_main.xml
:<LinearLayout xmlns:android=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <EditText android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Title" /> <EditText android:id="@+id/description" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Description" /> <Button android:id="@+id/addButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Add Note" /> <ListView android:id="@+id/noteListView" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
- Add the following code to
MainActivity.java
:import android.os.Bundle; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.firestore.DocumentChange; import com.google.firebase.firestore.FirebaseFirestore; import com.google.firebase.firestore.QuerySnapshot; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private EditText titleEditText, descriptionEditText; private Button addButton; private ListView noteListView; private ArrayAdapter<String> adapter; private ArrayList<String> noteList; private FirebaseFirestore firestore; private FirebaseAuth mAuth; private String userId; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); titleEditText = findViewById(R.id.title); descriptionEditText = findViewById(R.id.description); addButton = findViewById(R.id.addButton); noteListView = findViewById(R.id.noteListView); firestore = FirebaseFirestore.getInstance(); mAuth = FirebaseAuth.getInstance(); userId = mAuth.getCurrentUser().getUid(); noteList = new ArrayList<>(); adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, noteList); noteListView.setAdapter(adapter); addButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String title = titleEditText.getText().toString(); String description = descriptionEditText.getText().toString(); firestore.collection("users").document(userId).collection("notes") .add(new Note(title, description)) .addOnCompleteListener(task -> { if (task.isSuccessful()) { Toast.makeText(MainActivity.this, "Note added", Toast.LENGTH_SHORT).show(); titleEditText.setText(""); descriptionEditText.setText(""); } else { Toast.makeText(MainActivity.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show(); } }); } }); loadNotes(); } private void loadNotes() { firestore.collection("users").document(userId).collection("notes") .addSnapshotListener((value, error) -> { if (error != null) { Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show(); return; } for (DocumentChange dc : value.getDocumentChanges()) { if (dc.getType() == DocumentChange.Type.ADDED) { Note note = dc.getDocument().toObject(Note.class); noteList.add(note.getTitle() + " - " + note.getDescription()); adapter.notifyDataSetChanged(); } } }); } private static class Note { private String title; private String description; public Note() { // Required empty constructor for Firestore } public Note(String title, String description) { this.title = title; this.description = description; } public String getTitle() { return title; } public String getDescription() { return description; } } }
- Create a new activity
Step 5: Set Up Firebase Cloud Messaging (FCM)
Enable FCM in Firebase Console:
- Go to "Cloud Messaging" and note the Server key.
Add FCM to Your Project:
- In the Firebase Console, go to "Cloud Messaging" > "Edit project settings" and configure the Cloud Messaging server key.
- In the
AndroidManifest.xml
, add the following permissions and services:<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <application ...> <service android:name=".MyFirebaseMessagingService" android:exported="true"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> <service android:name=".MyFirebaseInstanceIDService" android:exported="true"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT" /> </intent-filter> </service> </application>
- Create a new service
MyFirebaseMessagingService.java
:import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.os.Build; import androidx.annotation.NonNull; import androidx.core.app.NotificationCompat; import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; public class MyFirebaseMessagingService extends FirebaseMessagingService { private static final String CHANNEL_ID = "my_channel"; @Override public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); // Check if message contains a notification payload. if (remoteMessage.getNotification() != null) { createNotificationChannel(); sendNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody()); } } private void createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel( CHANNEL_ID, "Channel human readable title", NotificationManager.IMPORTANCE_DEFAULT); channel.setDescription("Channel description"); channel.enableLights(true); channel.setLightColor(Color.GREEN); channel.setVibrationPattern(new long[]{0, 1000, 500, 1000}); channel.enableVibration(true); NotificationManager manager = getSystemService(NotificationManager.class); manager.createNotificationChannel(channel); } } private void sendNotification(String title, String messageBody) { Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.ic_launcher_foreground) .setContentTitle(title) .setContentText(messageBody) .setAutoCancel(true) .setContentIntent(pendingIntent); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(0 /* ID of notification */, notificationBuilder.build()); } }
- Create a new service
MyFirebaseInstanceIDService.java
(Note: This is no longer necessary for newer versions of Firebase. You can ignore this step and remove the corresponding service from theAndroidManifest.xml
):import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.iid.FirebaseInstanceIdService; public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService { @Override public void onTokenRefresh() { super.onTokenRefresh(); String refreshedToken = FirebaseInstanceId.getInstance().getToken(); // You can send the token to your server or save it locally } }
Step 6: Test Your Application
- Run the
RegisterActivity
from Android Studio. - Register a new user by entering an email and password.
- Log in using the registered credentials.
- Add notes in
MainActivity
and observe them in the list. - Send a test push notification from the Firebase Console to your app.
Conclusion
You now have a basic Android application integrated with Firebase Authentication, Firestore, and Cloud Messaging. This setup can be expanded with additional features such as user profiles, more complex data models, and enhanced push notifications.
Top 10 Interview Questions & Answers on Android Firebase Integration Auth, Firestore, Cloud Messaging
Firebase Authentication on Android
1. How do you set up Firebase Authentication in an Android project?
- First, add the Firebase SDK to your app by including it in your
build.gradle
file:implementation 'com.google.firebase:firebase-auth:21.0.1'
- Then, visit the FirebaseAuth auth = FirebaseAuth.getInstance(); auth.createUserWithEmailAndPassword(email, password) .addOnCompleteListener(new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (task.isSuccessful()) { // Sign up success FirebaseUser user = auth.getCurrentUser(); } else { // Handle sign up failure } } });
3. How can I handle Google Sign-In with Firebase on Android?
- Configure the Google Sign-In API with your web client ID from the Firebase console.
- Use the GoogleSignInClient to authenticate users, then exchange the GoogleAuthCredential with Firebase:
FirebaseAuth auth = FirebaseAuth.getInstance(); GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken(getString(R.string.default_web_client_id)) .requestEmail() .build(); GoogleSignInClient googleSignInClient = GoogleSignIn.getClient(this, gso); Intent signInIntent = googleSignInClient.getSignInIntent(); startActivityForResult(signInIntent, RC_SIGN_IN); private void firebaseAuthWithGoogle(String idToken) { AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null); auth.signInWithCredential(credential) .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { if (task.isSuccessful()) { // Sign in success FirebaseUser user = auth.getCurrentUser(); } else { // Handle sign in failure } } }); }
Firestore Database on Android
4. How do you add Firebase Firestore to your Android app?
- Include the Firestore dependency in your
build.gradle
file:implementation 'com.google.firebase:firebase-firestore:24.0.0'
- Initialize Firestore in your app:
FirebaseFirestore db = FirebaseFirestore.getInstance();
5. How do you write and read data to/from Firestore in Java/Kotlin?
- To write data:
Map<String, Object> user = new HashMap<>(); user.put("first", "Ada"); user.put("last", "Lovelace"); user.put("born", 1815); db.collection("users").add(user) .addOnSuccessListener(documentReference -> Log.d(TAG, "DocumentSnapshot added with ID: " + documentReference.getId())) .addOnFailureListener(e -> Log.w(TAG, "Error adding document", e));
- To read data:
db.collection("users").get().addOnCompleteListener(task -> { if (task.isSuccessful()) { for (QueryDocumentSnapshot document : task.getResult()) { Log.d(TAG, document.getId() + " => " + document.getData()); } } else { Log.w(TAG, "Error getting documents.", task.getException()); } });
6. Can you listen for real-time updates on Firestore data?
- Yes, you can set up a listener to receive real-time updates:
final DocumentReference docRef = db.collection("cities").document("SF"); docRef.addSnapshotListener(this, (snapshot, e) -> { if (e != null) { return; } if (snapshot != null && snapshot.exists()) { // Data has changed } else { // No data } });
Cloud Messaging (FCM) on Android
7. How do I integrate Firebase Cloud Messaging into my Android app?
- Add FCM dependency to your
build.gradle
:implementation 'com.google.firebase:firebase-messaging:23.0.0'
- Create a FirebaseMessagingService by extending the class:
public class MyFirebaseMessagingService extends FirebaseMessagingService { @Override public void onMessageReceived(RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); // Handle FCM messages here. } @Override public void onNewToken(String token) { super.onNewToken(token); // Send the instance ID token to your app server. } }
- Register the service in your
AndroidManifest.xml
:<service android:name=".MyFirebaseMessagingService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT"/> </intent-filter> </service>
8. What is FirebaseInstanceId and why is it deprecated?
- FirebaseInstanceId was used to retrieve a unique identifier per device that could be used for messaging. It has been replaced with
FirebaseMessagingService
which automatically handles token generation and updates. - Instead of directly accessing
FirebaseInstanceId
, use callback methods inFirebaseMessagingService
.
9. How do you send push notifications to a specific device using FCM?
- Store the FCM registration token for individual devices.
- From your server side (Node.js example):
const message = { token: 'device_token_here', notification: { title: 'Test Title', body: 'Test Message' }, data: { // any extra data you want to pass in key1: 'value1', key2: 'value2' } }; admin.messaging().send(message) .then((response) => { console.log('Successfully sent message:', response); }) .catch((error) => { console.log('Error sending message:', error); });
10. How do you handle push notifications when your app is in the foreground, background, or closed?
- When the app is in the foreground,
onMessageReceived
will handle the message. - For background/closed states, FCM handles messages automatically and they go to the system tray. To customize the behavior, define a default notification channel and use the
notification
object in your server payload. - Handle the notification click in
onCreate
oronNewIntent
methods by checking incoming intent extras.
Login to post a comment.