Chatting Application in Android with Kotlin
Last Updated :
01 Aug, 2024
Building a Real-Time Chat Application can be a great way to dive into Android Development and Firebase. In this article, we will learn to make a basic chat application using Android Studio IDE with Kotlin and real-time chatting using Google's FirebaseFirestore as a database.
Pre-requisites
- Android Studio Installed
- Basic Knowledge of Kotlin
- Basic Knowledge of Firebase console.
In this article, we will focus solely on the coding part. Therefore, it is assumed that you already know how to use the Firebase console through the website.
Step-By-Step Implementation of Chatting Application in Android Kotlin
- Setting Up the Project
1.1 Create a new Android Studio Project
Open your Android Studio IDE and create a new project. You can give it any name you prefer.
1.2 Add Firebase to your Project
Connecting Firebase to Android Studio is an easy process . Inside the tools menu, select Firebase
Search for Cloud Firestore -> Get Started with Cloud Firestore
Follow the first Two Steps inside the documentation to connect your application to Cloud Firestore
The first step will redirect you to the Firebase console website, where you will connect your Android studio application with Firebase Console. The second step will add the required dependencies to your application automatically.
After doing this, your application will be connected to Cloud Firestore!
Make sure you activate the FirebaseFirestore inside the console before using it!
- Making UI
This application will have 2 activities. We won't be authenticating any users, but we will be getting their usernames. User authentication can also be done using Firebase, but in this article, we will only be focusing on the database part.
2.1 Main Activity Layout
This layout will be taking usernames as input for further use. So we will need an Edit Text and a Button. We can use additional components like TextView and ImageView to make it look good.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="@color/white">
<ImageView
android:id="@+id/Image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/logo"
android:layout_marginBottom="50dp"
app:layout_constraintBottom_toTopOf="@id/AppName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/AppName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="GFG Chat Application"
android:textColor="@color/black"
android:textSize="35sp"
app:layout_constraintBottom_toTopOf="@+id/NameLabel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/Image"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/NameLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name: "
android:textColor="@color/black"
android:textSize="40sp"
app:layout_constraintBottom_toTopOf="@id/enter"
app:layout_constraintEnd_toStartOf="@+id/NameEnter"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/AppName" />
<EditText
android:id="@+id/NameEnter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Name"
android:textSize="40sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/NameLabel"
app:layout_constraintTop_toBottomOf="@id/AppName" />
<Button
android:id="@+id/enter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enter Chat!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/NameLabel"
android:layout_marginTop="30dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Here is what the Main Activity will look like
2.2 Chat Activity
In this layout, the actual chat will take place. This activity will make use of RecyclerView to show chats in a list form and an EditText and a Submit button to add a new text.
activity_chat.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"
android:background="@color/white">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="GFG Chat"
android:gravity="center"
android:textColor="@color/black"
android:textSize="20sp"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:itemCount="10"
android:layout_weight="1"
tools:listitem="@layout/chat_layout"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/editTextMessage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Type a message" />
<Button
android:id="@+id/buttonSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send" />
</LinearLayout>
</LinearLayout>
The RecyclerView will also have its layout file, so create one extra XML file named chat_layout.xml
chat_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp"
android:background="#dcdcdc"
android:layout_margin="10dp">
<TextView
android:id="@+id/textViewSender"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Sender"
android:textColor="#a52a2a"
android:textStyle="bold"
android:textSize="14sp" />
<TextView
android:id="@+id/textViewMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Message"
android:textColor="@color/black"
android:textSize="16sp"
android:paddingTop="4dp" />
</LinearLayout>
Here's how the chat layout looks like
Don't worry, this is just a preview, the data will be dynamically fetched from the database and will display on the application correctly in the RunTime.
- Backend
The backend will be made using Kotlin and it will handle all the functionalities of this application:
- Fetching Previous Messages from Firebase Firestore
- Sending new Messages
- Storing new Messages in Firebase Firestore.
3.1 Inputting UserName
The first thing our app will be doing is getting the username from the user before displaying the chat interface. That's why we have made 2 different activities for this. Once the user inputs the username and clicks on the Submit button, the chat Interface will open with the help of Intent, and the username will be passed on to the chat activity.
Here how it is implemented:
MainActivity.kt
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
class MainActivity : AppCompatActivity() {
// Declaring the EditText and Button variables.
private lateinit var nameEditText: EditText
private lateinit var enterButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
// Integrating the EditText and button variables with UI
nameEditText = findViewById(R.id.NameEnter)
enterButton = findViewById(R.id.enter)
// If username is not empty, proceed to ChatActivity and pass the username along it.
enterButton.setOnClickListener {
val name = nameEditText.text.toString()
if (name.isNotEmpty()) {
val intent = Intent(this, ChatActivity::class.java)
intent.putExtra("USER_NAME", name)
startActivity(intent)
finish()
}
}
}
}
3.2 Implementing ChatActivity.
ChatActivity has a RecyclerView element. The Recycler view element must have an Adapter Class and a Data Model Class. Let's implement the Data Model and Adapter Classes first.
Data Model Class:
The data Model class will contain variables that will represent each chat message inside the RecyclerView. It is a simple class declaration with getters and setters.
ChatMessage.kt
data class ChatMessage(
val id: String = "",
val message: String = "",
val timestamp: Long = System.currentTimeMillis(),
val senderId: String = ""
)
RecyclerView Adapter Class:
The RecyclerView Adapter class. It is responsible for setting the layout of recyclerView and filling it with the content provided.
chatAdapter.kt
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class ChatAdapter(private val messages: List<ChatMessage>) : RecyclerView.Adapter<ChatAdapter.ChatViewHolder>() {
class ChatViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val senderTextView: TextView = view.findViewById(R.id.textViewSender)
val messageTextView: TextView = view.findViewById(R.id.textViewMessage)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ChatViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.chat_layout, parent, false)
return ChatViewHolder(view)
}
override fun onBindViewHolder(holder: ChatViewHolder, position: Int) {
val chatMessage = messages[position]
holder.senderTextView.text = chatMessage.senderId
holder.messageTextView.text = chatMessage.message
}
override fun getItemCount() = messages.size
}
Let's proceed to the main Kotlin file for the ChatActivity. Functionalities of ChatActivity:
- Here we will use the Firebase Firestore and fetch chat data if any.
- We will set the RecyclerView's adapter here and pass any previous messages fetched from the Database.
- This class will also be responsible for handling the Send Message button and updating the messages in realtime.
Let's see how to do it.
ChatActivity.kt
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.Toast
import android.widget.Toast.LENGTH_SHORT
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.firestore.Query
class ChatActivity : AppCompatActivity() {
// Declaring Necessary variables
private lateinit var recyclerView: RecyclerView
private lateinit var editTextMessage: EditText
private lateinit var buttonSend: Button
private lateinit var chatAdapter: ChatAdapter
private val firestore = FirebaseFirestore.getInstance() // Getting Firestore instance.
private val messagesCollection = firestore.collection("messages") // Our messages will be stored and fetched from "messages" collection
private val messages = mutableListOf<ChatMessage>()
private lateinit var userName: String
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)
recyclerView = findViewById(R.id.recyclerView)
editTextMessage = findViewById(R.id.editTextMessage)
buttonSend = findViewById(R.id.buttonSend)
userName = intent.getStringExtra("USER_NAME") ?: "Anonymous"
chatAdapter = ChatAdapter(messages)
recyclerView.adapter = chatAdapter
recyclerView.layoutManager = LinearLayoutManager(this)
fetchExistingMessages()
buttonSend.setOnClickListener {
val messageText = editTextMessage.text.toString()
// Update the database with new messages.
if (messageText.isNotEmpty()) {
val message = ChatMessage(
id = messagesCollection.document().id,
message = messageText,
senderId = userName
)
messagesCollection.document(message.id).set(message)
editTextMessage.text.clear()
}
}
// Mock data for preview purposes
messagesCollection.orderBy("timestamp", Query.Direction.ASCENDING)
// SnapShot Listener listenes to any changes inside the collection, If there is any change, Update the recycler View. This helps chat update Realtime.
.addSnapshotListener { snapshot, e ->
if (e != null) {
Toast.makeText(this, "Unable to get new Messages", LENGTH_SHORT)
return@addSnapshotListener
}
if (snapshot != null && !snapshot.isEmpty) {
messages.clear()
for (document in snapshot.documents) {
// Convert the data directly into class variable
val message = document.toObject(ChatMessage::class.java)
if (message != null) {
// Add the new message into the list of messages
messages.add(message)
}
}
// Update the RecyclerView.
chatAdapter.notifyDataSetChanged()
recyclerView.scrollToPosition(messages.size - 1)
}
}
}
private fun fetchExistingMessages() {
// Getting any previous messages and ordering them with respect to time they got sent.
messagesCollection.orderBy("timestamp", Query.Direction.ASCENDING)
.get()
.addOnSuccessListener { snapshot ->
if (snapshot != null && !snapshot.isEmpty) {
messages.clear()
for (document in snapshot.documents) {
// Add all the messages into the list 'messages'
val message = document.toObject(ChatMessage::class.java)
if (message != null) {
messages.add(message)
}
}
// Update the RecyclerView with the messages.
chatAdapter.notifyDataSetChanged()
recyclerView.scrollToPosition(messages.size - 1)
}
}
.addOnFailureListener { e ->
Toast.makeText(this, "Unable to fetch Messages", LENGTH_SHORT)
}
}
}
With this the chat application is complete! You can chat with anyone in realtime.
Here's what it will look like.
Note : To access the full android application of Chatting Android check this repository: Chatting Android Application
Similar Reads
Speech to Text Application in Android with Kotlin
Speech to Text is seen in many applications such as Google search. With the help of this feature, the user can simply speak the query he wants to search. The text format of that speech will be automatically generated in the search bar. In this article, we will be taking a look at How to implement Sp
4 min read
Creating Multiple Screen Applications in Android
This article shows how to create an android application to move from one activity to another using the concept of Explicit Intents. Below are the steps for Creating a Simple Android Application to move from one activity to another activity. Step By Step ImplementationStep 1: Create a New Project in
6 min read
Calendar View App in Android with Kotlin
Calendar View is seen in most travel booking applications in which the user has to select the date of the journey. For the selection of the date, this view is used. In this article, we will take a look at How to implement Calendar View within our Android application using Kotlin. A sample video is g
3 min read
Android - Create BarChart with Kotlin
Bar Chart is a UI component that is seen in most FinTech applications. These bar charts are used to display vast amounts of data in an easily readable form. In this article, we will be building a simple Bar Chart within our Android application using Kotlin. A sample GIF is given below to get an idea
4 min read
Build a Chat App in Android using Kotlin
Almost all brands these days need an app with chat functionality so that users can interact with each other or connect to their customer support easily. In this article, we will show you how to build a chat app for Android devices. Throughout this tutorial, we use the most lightweight, clean, and Go
7 min read
Android - Create Group BarChart with Kotlin
Bar Charts in Android are used to represent vast amounts of data in an easily readable format. We can display a single bar chart within our bar chart. But for making a comparison between two categories we can implement a group bar chart to display data for both categories side by side. In this artic
3 min read
Retrofit with Kotlin Coroutine in Android
Retrofit is a type-safe http client which is used to retrieve, update and delete the data from web services. Nowadays retrofit library is popular among the developers to use the API key. The Kotlin team defines coroutines as âlightweight threadsâ. They are sort of tasks that the actual threads can e
3 min read
Room Database with Kotlin Coroutines in Android
This project will be used for the implementation phase. If you have not yet completed the project, you should do so and then return. To keep things simple, the project employs a basic MVVM architecture. The complete code for the implementation mentioned in this blog can be found in the project itsel
3 min read
How to Handle Network Operations in an Android Application?
Handling network operations in an Android application is an essential task for developers. Network operations typically involve making HTTP requests to web services or APIs and receiving responses from them. These operations can include fetching data from a server, uploading files or data, authentic
5 min read
How to Build a Step Counting Application in Android Studio?
Many of us have used the step counter on our phones while we go for walk or run. It counts the total steps that the user has walked and displays it on the screen. The other name for the step counter is a pedometer. But have you ever thought about how can an app count our steps? What is the coding be
7 min read