chat app in firebase

Building Real-time Chat App in Android using Firebase

In this article, we will learn about Cloud Firestore and Authentication- integrating Google SignIn and Cloud firebase in Android Application using firebase . If you want to build a chat app in android using firebase, you’ve come to the right place.

We will use Firebase to create an application for a real-time chat in this tutorial. In building a messaging or Chat application. A service that acts as a backend provider can be defined as Firebase. We can also say that this is a Web service that gives us the possibility of saving and recovering our data from Google’s web service in a cloud-based infrastructure. We don’t have to keep our servers and write code for the server. It offers many features such as data storage, authentication, analysis, notification, hosting, crashalytics, etc. Up to the most part, it is available.

If you don’t know what is firebase then please refer to What is Firebase | All about Firebase

Output:

Two core features, i.e., Cloud Firestore, and Authentication, are used in this tutorial. We will save our chat messages in cloud firestore, which are retrieved from all apps.  we provide the user with log-in,sign-up, and logout features using Firebase Authentication.

Prerequisites

To be able to follow this step-by-step Android chat app tutorial, you’ll need the following:

  1. The latest version of Android Studio
  2. A Firebase account

Example:

Step 1: Create a new Android Studio Project (Empty Activity).

Step 2: Go to Firebase Console– Create a Project.

Enter a name for your project and then click.

Disable Google Analytics. We’re not going to need it.

firebase

Click on Create Project and wait till it’s done. Then click on Continue.

firebase

Connect your Android Studio Project to Firebase project: Select Android as shown below.

Project

Add the required details and SHA key.

To generate SHA key : Go to the Android Studio Project and press ctrl 2 times and Run Anything pop up in this pop-up type – signingReport and Enter.

SHA key generating

Step 3: Enable google authentication: If you don’t know how to enable Google SignIn Authentication then please refer to Google SignIn Using Firebase in Android | Authentication.

Step 4: Create a Cloud Firestore.

On the sidebar by the left, click on Firestore Database.

project overview

On the page that shows up, click the create database button.

create firebase database

Select your preferred location( Select the nearby location ) and click next.

firebase

Next, choose to use the database in test mode and click on the Enable button and wait for the process to complete.

firebase

This will create an empty database , as shown below:

cloud firestore

Step 5: Add the required dependency:


dependencies {
implementation “androidx.appcompat:appcompat:$rootProject.appCompatVersion”

//coroutines
implementation “org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version”
api “org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines”
api “org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines”

// UI
implementation “androidx.constraintlayout:constraintlayout:$rootProject.constraintLayoutVersion”
implementation “com.google.android.material:material:$rootProject.materialVersion”

/* coroutines support for firebase operations */
implementation ‘org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.1.1
implementation ‘com.android.support:multidex:1.0.3’


// Import the BoM for the Firebase platform
implementation platform(‘com.google.firebase:firebase-bom:26.1.0’)
implementation ‘com.google.firebase:firebase-firestore’
implementation ‘com.google.firebase:firebase-auth-ktx’
implementation ‘com.firebaseui:firebase-ui-firestore:7.1.1’
implementation ‘com.google.android.gms:play-services-auth:19.2.0’

// Glide for Image Loading
implementation ‘com.github.bumptech.glide:glide:4.12.0’
kapt (‘com.github.bumptech.glide:compiler:4.12.0’)

// Testing
testImplementation “junit:junit:$rootProject.junitVersion”
androidTestImplementation “androidx.arch.core:core-testing:$rootProject.coreTestingVersion”
androidTestImplementation (“androidx.test.espresso:espresso-core:$rootProject.espressoVersion”, {
exclude group: ‘com.android.support’, module: ‘support-annotations’
})
androidTestImplementation “androidx.test.ext:junit:$rootProject.androidxJunitVersion”

}

and Plugin also:

plugins {

id ‘kotlin-kapt’
id ‘com.google.gms.google-services’
}

your build.gradle(Module:app) file look like:

plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt'
    id 'com.google.gms.google-services'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.example.messagingapp"
        minSdkVersion 16
        targetSdkVersion 30
        multiDexEnabled true

        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {
    implementation "androidx.appcompat:appcompat:$rootProject.appCompatVersion"

    //coroutines
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    api "org.jetbrains.kotlinx:kotlinx-coroutines-core:$rootProject.coroutines"
    api "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"

    // UI
    implementation "androidx.constraintlayout:constraintlayout:$rootProject.constraintLayoutVersion"
    implementation "com.google.android.material:material:$rootProject.materialVersion"

    /* coroutines support for firebase operations */
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.1.1'

    implementation 'com.android.support:multidex:1.0.3'


    // Import the BoM for the Firebase platform
    implementation platform('com.google.firebase:firebase-bom:26.1.0')
    implementation 'com.google.firebase:firebase-firestore'
    implementation 'com.google.firebase:firebase-auth-ktx'
    implementation 'com.firebaseui:firebase-ui-firestore:7.1.1'

    implementation 'com.google.android.gms:play-services-auth:19.2.0'
// Glide for Image Loading
    implementation 'com.github.bumptech.glide:glide:4.12.0'
     kapt ('com.github.bumptech.glide:compiler:4.12.0')

    // Testing
    testImplementation "junit:junit:$rootProject.junitVersion"
    androidTestImplementation "androidx.arch.core:core-testing:$rootProject.coreTestingVersion"
    androidTestImplementation ("androidx.test.espresso:espresso-core:$rootProject.espressoVersion", {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    androidTestImplementation "androidx.test.ext:junit:$rootProject.androidxJunitVersion"

}

Add this dependency in your file build.gradle(Project:app) file

dependencies {

classpath ‘com.google.gms:google-services:4.3.8’

}

Use the updated version number and paste the code in build.gradle(Project:app) file:

ext {
appCompatVersion = ‘1.2.0’
constraintLayoutVersion = ‘2.0.2’
coreTestingVersion = ‘2.1.0’
coroutines = ‘1.3.9’
lifecycleVersion = ‘2.2.0’
materialVersion = ‘1.2.1’
// testing
junitVersion = ‘4.13.1’
espressoVersion = ‘3.1.0’
androidxJunitVersion = ‘1.1.2’
}

and your build.gradle(Project:app) look like:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = "1.5.10"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.2.1"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.google.gms:google-services:4.3.8'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        mavenCentral()
     }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

ext {
    appCompatVersion = '1.2.0'
    constraintLayoutVersion = '2.0.2'
    coreTestingVersion = '2.1.0'
    coroutines = '1.3.9'
    lifecycleVersion = '2.2.0'
    materialVersion = '1.2.1'
    // testing
    junitVersion = '4.13.1'
    espressoVersion = '3.1.0'
    androidxJunitVersion = '1.1.2'
}

Step : 6 Create a data class and name it User and add the code given below:

data class User(
    val uid: String = "",
    val displayName: String? = "",
    val imageUrl: String = ""
)

Step 7: Create a Dao for User class name it UserDao and add the code given below:

import com.example.messagingapp.models.User
import com.google.android.gms.tasks.Task
import com.google.firebase.firestore.DocumentSnapshot
import com.google.firebase.firestore.FirebaseFirestore
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

class UserDao {
    private val db = FirebaseFirestore.getInstance()
    private val usersCollection = db.collection("users")

    fun addUser(user: User?) {
        user?.let {
            GlobalScope.launch(Dispatchers.IO) {
                usersCollection.document(user.uid).set(it)

            }
        }
    }

    fun getUserById(uId: String): Task<DocumentSnapshot> {
        return usersCollection.document(uId).get()
    }

}

Step 8: Create a data class, name it post and add the code given below:

data class Post(
    val text: String = "",
    val createdBy: User=  User(),
    val createdAt: Long = 0L,
    val likedBy: ArrayList<String> = ArrayList()
)

Step 9: Create a Dao for post class, name it postDao and add the code given below:

import android.util.Log
import com.example.messagingapp.models.Post
import com.example.messagingapp.models.User
import com.google.android.gms.tasks.Task
import com.google.firebase.auth.ktx.auth
import com.google.firebase.firestore.DocumentSnapshot
import com.google.firebase.firestore.FirebaseFirestore
import com.google.firebase.ktx.Firebase
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await

class PostDao {
    val db = FirebaseFirestore.getInstance()
    val postCollection = db.collection("posts")
    val auth = Firebase.auth



    fun addPost(text: String) {
        GlobalScope.launch {
            try {
                val currentUserId = auth.currentUser!!.uid

                val userDao = UserDao()
                val user = userDao.getUserById(currentUserId).await().toObject(User::class.java)!!
                val currentTime = System.currentTimeMillis()
                val post = Post(text, user, currentTime)
                postCollection.document().set(post)
            } catch (e: Exception) {
                Log.i("uman","${e.message}")
            }


        }
    }
        fun getPostById(postId: String): Task<DocumentSnapshot> {
            return postCollection.document(postId).get()
        }
        fun updateLikes(postId: String) {
            GlobalScope.launch {
                val currentUserId = auth.currentUser!!.uid
                val post = getPostById(postId).await().toObject(Post::class.java)!!
                val isLiked = post.likedBy.contains(currentUserId)
                if (isLiked) {
                    post.likedBy.remove(currentUserId)
                } else {
                    post.likedBy.add(currentUserId)

                }
                postCollection.document(postId).set(post)


            }


        }

}

Step 10: Create a Adapter, name it postAdapter and add the code given below:

import Utils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.messagingapp.R
import com.example.messagingapp.models.Post
import com.firebase.ui.firestore.FirestoreRecyclerAdapter
import com.firebase.ui.firestore.FirestoreRecyclerOptions
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase

class PostAdapter(options: FirestoreRecyclerOptions<Post>, val listener: IPostAdapter) :
    FirestoreRecyclerAdapter<Post, PostAdapter.PostViewHolder>(
        options
    ) {

    class PostViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val postText: TextView = itemView.findViewById(R.id.postTitle)
        val userText: TextView = itemView.findViewById(R.id.userName)
        val createdAt: TextView = itemView.findViewById(R.id.createdAt)
        val likeCount: TextView = itemView.findViewById(R.id.likeCount)
        val userImage: ImageView = itemView.findViewById(R.id.userImage)
        val likeButton: ImageView = itemView.findViewById(R.id.likeButton)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostViewHolder {
        val viewHolder = PostViewHolder(
            LayoutInflater.from(parent.context).inflate(R.layout.item_list, parent, false)
        )
        viewHolder.likeButton.setOnClickListener {
            listener.onLikesClicked(snapshots.getSnapshot(viewHolder.adapterPosition).id)
        }
        return viewHolder

    }

    override fun onBindViewHolder(holder: PostViewHolder, position: Int, model: Post) {
        holder.postText.text = model.text
        holder.userText.text = model.createdBy.displayName
        Glide.with(holder.userImage.context).load(model.createdBy.imageUrl).circleCrop()
            .into(holder.userImage)
        holder.likeCount.text = model.likedBy.size.toString()
        holder.createdAt.text = Utils.getTimeAgo(model.createdAt)


        val auth = Firebase.auth
        val currentUserId = auth.currentUser!!.uid
        val isLiked = model.likedBy.contains(currentUserId)
        if (isLiked) {
             holder.likeButton.setImageDrawable(ContextCompat.getDrawable(holder.likeButton.context,R.drawable.ic_likes))
        } else {
            holder.likeButton.setImageDrawable(ContextCompat.getDrawable(holder.likeButton.context,R.drawable.ic_unliked))

        }
    }


}

interface IPostAdapter {
    fun onLikesClicked(postId: String)

}

Step 11: Create a new class ,name it Utils and add the code given below:

class Utils {
    companion object {
        private const val SECOND_MILLIS = 1000
        private const val MINUTE_MILLIS = 60 * SECOND_MILLIS
        private const val HOUR_MILLIS = 60 * MINUTE_MILLIS
        private const val DAY_MILLIS = 24 * HOUR_MILLIS

        fun getTimeAgo(time: Long): String? {
            val now: Long = System.currentTimeMillis()
            if (time > now || time <= 0) {
                return null
            }

            val diff = now - time
            return if (diff < MINUTE_MILLIS) {
                "just now"
            } else if (diff < 2 * MINUTE_MILLIS) {
                "a minute ago"
            } else if (diff < 50 * MINUTE_MILLIS) {
                (diff / MINUTE_MILLIS).toString() + " minutes ago"
            } else if (diff < 90 * MINUTE_MILLIS) {
                "an hour ago"
            } else if (diff < 24 * HOUR_MILLIS) {
                (diff / HOUR_MILLIS).toString() + " hours ago"
            } else if (diff < 48 * HOUR_MILLIS) {
                "yesterday"
            } else {
                (diff / DAY_MILLIS).toString() + " days ago"
            }
        }


    }
}

Step 12: Create a New Activity(Empty Activity), name it SignIn and add the code given below:

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.ProgressBar
import com.example.messagingapp.Dao.UserDao
import com.example.messagingapp.models.User
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.android.gms.common.SignInButton
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.tasks.Task
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.GoogleAuthProvider
import com.google.firebase.auth.ktx.auth
import com.google.firebase.ktx.Firebase
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import kotlinx.coroutines.withContext

class SignIn : AppCompatActivity() {
    private val RC_SIGN_IN: Int = 123
    private val TAG = "MainActivity"
    lateinit var auth: FirebaseAuth
    private lateinit var googleSignInClient: GoogleSignInClient


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sign_in)

        val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.default_web_client_id))
            .requestEmail()
            .build()
        googleSignInClient = GoogleSignIn.getClient(this, gso)
        auth = Firebase.auth

        findViewById<SignInButton>(R.id.SignInbtn).setOnClickListener {
            signIn()
        }

    }

    override fun onStart() {
        super.onStart()
        val currentuser = auth.currentUser
        updateUI(currentuser)

    }

    private fun signIn() {
        val signInIntent = googleSignInClient.signInIntent
        startActivityForResult(signInIntent, RC_SIGN_IN)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            val task = GoogleSignIn.getSignedInAccountFromIntent(data)
            handleSignInResult(task)
        }
    }

    private fun handleSignInResult(completedTask: Task<GoogleSignInAccount>) {
        val account =
            completedTask.getResult(ApiException::class.java)!!
        Log.d(TAG, "firebaseAuthWithGoogle:" + account.id)
        firebaseAuthWithGoogle(account.idToken!!)
    }

    private fun firebaseAuthWithGoogle(idToken: String) {
        val credential = GoogleAuthProvider.getCredential(idToken, null)
        findViewById<SignInButton>(R.id.SignInbtn).visibility = View.GONE
        findViewById<ProgressBar>(R.id.progressBar).visibility = View.VISIBLE
        GlobalScope.launch(Dispatchers.IO) {
            val auth = auth.signInWithCredential(credential).await()
            val firebaseUser = auth.user
            withContext(Dispatchers.Main) {
                updateUI(firebaseUser!!)
            }
        }

    }

    private fun updateUI(firebaseUser: FirebaseUser?) {
        if (firebaseUser != null) {
            val user = User(
                firebaseUser.uid,
                firebaseUser.displayName,
                firebaseUser.photoUrl.toString()
            )
            val userDao = UserDao()
            userDao.addUser(user)


            val mainActivityIntent = Intent(this, MainActivity::class.java)
            startActivity(mainActivityIntent)
            finish()
        } else {
            findViewById<SignInButton>(R.id.SignInbtn).visibility = View.VISIBLE
            findViewById<ProgressBar>(R.id.progressBar).visibility = View.GONE
        }
    }
}

Step 13: In activity_sign_in.xml add the code given below:

chat application in android source code,chat application in android source code,chat application in android source code,chat application in android source code,chat application in android source code,

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SignIn">

    <com.google.android.gms.common.SignInButton
        android:id="@+id/SignInbtn"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginBottom="15dp"
        android:visibility="visible"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="330dp"
        android:visibility="gone"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="4dp"
        android:layout_marginLeft="4dp"
        android:layout_marginTop="62dp"
        android:layout_marginEnd="4dp"
        android:layout_marginRight="4dp"
        android:layout_marginBottom="234dp"
        app:layout_constraintBottom_toTopOf="@+id/SignInbtn"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/common_google_signin_btn_icon_dark" />

</androidx.constraintlayout.widget.ConstraintLayout>

Step 14: Create a new Activity(Empty Activity), name it CreatePostActivity, and add the code given below:

messaging app using firebase, messaging app using firebase, , v messaging app using firebase, , messaging app using firebase, , messaging app using firebase, , messaging app using firebase, , messaging app using firebase, , messaging app using firebase, , messaging app using firebase, , messaging app using firebase, , messaging app using firebase, m messaging app using firebase, , messaging app using firebase, , messaging app using firebase, , messaging app using firebase, , messaging app using firebase, , messaging app using firebase, , messaging app using firebase, messaging app using firebase,

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.EditText
import com.example.messagingapp.Dao.PostDao

class CreatePostActivity : AppCompatActivity() {
    private lateinit var postDao: PostDao
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_create_post)
        postDao = PostDao()
        findViewById<Button>(R.id.postButton).setOnClickListener {

            val input = findViewById<EditText>(R.id.inputText).text.toString().trim()
            if (input.isNotEmpty()) {
                postDao.addPost(input)
                val intent = Intent(this, MainActivity::class.java)
                startActivity(intent)
            }
        }
    }
}

Step 15: In activity_create_post.xml, add the code given below:

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.EditText
import com.example.messagingapp.Dao.PostDao

class CreatePostActivity : AppCompatActivity() {
    private lateinit var postDao: PostDao
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_create_post)
        postDao = PostDao()
        findViewById<Button>(R.id.postButton).setOnClickListener {

            val input = findViewById<EditText>(R.id.inputText).text.toString().trim()
            if (input.isNotEmpty()) {
                postDao.addPost(input)
                val intent = Intent(this, MainActivity::class.java)
                startActivity(intent)
            }
        }
    }
}

Step: 16 In MainActivity.kt file, add the code given below:

chat app in android,chat app in android,chat app in android,chat app in android,chat app in android,chat app in android,chat app in android,chat app in android,chat app in android,chat app in androidchat app in android,chat app in android,chat app in androidchat app in androidchat app in android,chat app in androidvchat app in android,chat app in android,chat app in android,chat app in android,v,chat app in androidvchat app in android,chat app in android,chat app in firebase.

chat application using firebase, chat application using firebase , chat application using firebase ., chat application using firebase , chat application using firebase , chat application using firebase , chat application using firebase ,chat application using firebase, chat application using firebase , chat application using firebase ., chat application using firebase , chat application using firebase , chat application using firebase , chat application using firebase ,

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatDelegate
import androidx.drawerlayout.widget.DrawerLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.messagingapp.Adapter.IPostAdapter
import com.example.messagingapp.Adapter.PostAdapter
import com.example.messagingapp.Dao.PostDao
import com.example.messagingapp.models.Post
import com.firebase.ui.firestore.FirestoreRecyclerOptions
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.firestore.Query
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity(), IPostAdapter {
    private lateinit var postDao: PostDao
    private lateinit var adapter: PostAdapter
    lateinit var firebaseAuth: FirebaseAuth
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        firebaseAuth = FirebaseAuth.getInstance()
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);

        findViewById<FloatingActionButton>(R.id.fab).setOnClickListener {
            val intent = Intent(this, CreatePostActivity::class.java)
            startActivity(intent)
        }
        setUpRecyclerView()
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        super.onCreateOptionsMenu(menu)
        menuInflater.inflate(R.menu.option_menu, menu)
        return true

    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        super.onOptionsItemSelected(item)

        when (item.itemId) {
            R.id.logoutoption -> {
                GlobalScope.launch {

                    FirebaseAuth.getInstance().signOut()
                }
                    val intent = Intent(this, SignIn::class.java)
                    startActivity(intent)
                    finish()
            }

        }
        return  true
    }


    private fun setUpRecyclerView() {
        postDao = PostDao()
        val postsCollections = postDao.postCollection
        val query = postsCollections.orderBy("createdAt", Query.Direction.DESCENDING)
        val recyclerViewOptions =
            FirestoreRecyclerOptions.Builder<Post>().setQuery(query, Post::class.java).build()


        adapter = PostAdapter(recyclerViewOptions, this)
        findViewById<RecyclerView>(R.id.recyclerView).adapter = adapter
        findViewById<RecyclerView>(R.id.recyclerView).layoutManager = LinearLayoutManager(this)


    }

    override fun onStart() {
        super.onStart()
        adapter.startListening()
    }

    override fun onStop() {
        super.onStop()
        adapter.stopListening()
    }

    override fun onLikesClicked(postId: String) {
        postDao.updateLikes(postId)
    }
}


Step 17: Create a menu resource file- res/new/android resource directory/ resource type: menu – > and name it option_menu and click OK.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">


    <item android:title="Logout"
        android:id="@+id/logoutoption"
         />
    <item android:title="About Us"
        android:id="@+id/aboutusoption"/>
</menu>

Step 18: In activity_main.xml, add the code given below:

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="24dp"
        android:src="@drawable/ic_baseline_add_24"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

Step 19: Create a new layout file, name it item_list.xml and add the code given below:

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    app:cardCornerRadius="5dp"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_marginTop="16dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:background="@color/teal_200"
        android:layout_height="wrap_content"
        android:padding="16dp">

        <ImageView
            android:layout_width="42dp"
            android:layout_height="42dp"
            android:id="@+id/userImage"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/userName"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintLeft_toRightOf="@id/userImage"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="@id/userImage"
            android:layout_marginLeft="12dp"
            android:textSize="16sp"
            android:textColor="#212121"
            android:textStyle="bold"/>

        <TextView
            android:id="@+id/createdAt"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintLeft_toRightOf="@id/userImage"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/userName"
            android:layout_marginTop="4dp"
            android:layout_marginLeft="12dp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/userImage"
            android:id="@+id/postTitle"
            android:textSize="16sp"
            android:layout_marginTop="12dp"
            android:textColor="#212121" />

        <ImageView
            android:id="@+id/likeButton"
            android:layout_width="24dp"
            android:layout_height="24dp"
            app:layout_constraintLeft_toLeftOf="@id/postTitle"
            app:layout_constraintTop_toBottomOf="@id/postTitle"
            android:layout_marginTop="16dp" />

        <TextView
            android:id="@+id/likeCount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintLeft_toRightOf="@id/likeButton"
            app:layout_constraintTop_toTopOf="@id/likeButton"
            android:layout_marginLeft="6dp"
            app:layout_constraintBottom_toBottomOf="@id/likeButton" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>

Run the application now. You will get the output shown in the output section.

chat application in android, chat application in android,chat application in android,chat application in android,chat application in android,chat application in android,chat application in android,chat application in android,chat application in android

Source Code:

We’ve completed the development of a chat application in android using Firebase. You can get the Source code from the given below button.

  • We hope that this guide will assist you in understanding all about the concepts of chat application in android using firebase. We have concentrated on making a basic, meaningful and easy-to -learn guide to the concepts of chat application in android using firebase with suitable examples. Still if you have any problems regarding this, please post them in the comments section, we will be glad to assist you.

Leave a Reply