Add Push Notifications to Your Android Chat App Using Kotlin
Tags: android, kotlin, firebase, cometchat
Published: 2019-11-24 20:16:08

---
title: Add Push Notifications to Your Android Chat App Using Kotlin
published: true
date: 2019-11-23 22:20:58 UTC
tags: android, kotlin, firebase, cometchat
canonical_url: https://wajahatkarim.com/2019/11/add-push-notifications-to-your-android-chat-app-using-kotlin/
---

> *Originally published at [wajahatkarim.com](https://wajahatkarim.com/2019/11/add-push-notifications-to-your-android-chat-app-using-kotlin/).*

For any kind of chat apps, notifications are the driver behind whole chat concept. These notifications lets users know that a new message has been sent, and asks to respond to it. This seems like a micro-interaction from user experience perspective, but this tiny interactions makes the whole chat a real-time conversation. This allows users to do multitasking while talking with their friends just as people do in real in-person or call meetings.

These notifications are called as Push Notifications in the language of Android / iOS development. In this article, you are going to learn on how to add push notifications in your Android chat apps in Kotlin using the simplicity or rather the beauty of CometChat Pro SDK.

As you are going to integrate push notifications in the Android chat apps, you will need at least a simple chat app with basic functionality such as sending / receiving messages. This article will use the [Chaty sample app](https://github.com/wajahatkarim3/Chaty) from [this article](https://dev.to/wajahatkarim/build-a-one-on-one-android-chat-app-using-kotlin-1cf7-temp-slug-1268680) and integrate push notifications in it when user gets any new message from other users. If you want to develop the chat app first, you can follow that article first and come back to this later. Or you can directly start from the already built chat app to learn about Push Notifications using the [push-notifications-start](https://github.com/wajahatkarim3/Chaty/tree/push-notifications-start) branch of Chaty app here.

Here’s the final demo of the application you’re going to build in this article.

[![Chaty Push Notifications - Demo](https://raw.githubusercontent.com/wajahatkarim3/Chaty/push-notifications-finish/Screenshots/Push%20Notifications%20-%20Demo.gif)](//raw.githubusercontent.com/wajahatkarim3/Chaty/push-notifications-finish/Screenshots/Push%20Notifications%20-%20Demo.gif "Chaty Push Notifications - Demo")Chaty Push Notifications - Demo

You can see in the demo GIF that Captain America (left) & Cyclops (right) are sending messages to each other and those messages are being delivered through push notifications of Android devices. Rather than just simply explaining the basic send/receive push notification, this article is going to explain some practical use-cases implemented in modern chat apps. These cases are listed below:

- User can receive notifications when app is in background or completely removed from the Recent Apps in Android device.

- User can receive notifications while app is active and in foreground and either Contacts or Profile or any other chat conversation screen are open.

- User don’t receive notifications when the chat between sending user and receiving user is already open.

- User can mute or unmute any specific user’s notifications at anytime.

* * *

# Chaty Code Overview

Before getting started, if you have followed the Chaty article, then here’s a basic overview of the code and parts where you will be working in. And if you have your own chat app with your custom code, then you can skip this section.

- `LoginActivity.kt` manages the user login functionality. Once the user is successfully logged in, it opens the Contacts screen.

- `ContactsActivity.kt` represents the Contacts screen. It fetches all other users data from CometChat Pro and shows in the screen.

- `ProfileActivity.kt` displays the profile screen with the current logged in user’s name, email, avatar etc. This also manages the logout functionality of the user.

- `ChatActivity.kt` handles the chat session of the users. This is responsible for sending and receiving messages between the users.

- `ChatyApp.kt` is the main Application class of the whole app and is responsible for initializing the CometChat SDK when the app launches.

- `strings.xml` file contains the CometChat API key and App ID. You should update this with your own keys now before moving further with this article.

Beside these classes, there are some model files for data holding and some Kotlin extensions to make utility methods easier to use.

* * *

# Setting up Firebase Project

There are many different APIs for sending push notifications in Android such [OneSignal](http://onesignal.com/), [Firebase Messaging Service (FCM)](http://onesignal.com/) etc. This tutorial will show you on how to integrate Firebase Messaging Service (FCM) service in your chat apps in a very easy way.

To integrate Firebase Messaging, you will need to create a project in Firebase Console. Go to [Firebase Console](http://console.firebase.google.com/) and create a new account if you don’t have one. Once inside Firebase console, add a new project by clicking on the `+ Add project` button. Set the name of the project to `MyChatApp` or anything you like.

![](https://paper-attachments.dropbox.com/s_A5A6DACFC66FBAC46DB7218924BF83F9DB2BA1B6D57CDCC57D9717A408CB4383_1569792894504_image.png)

On the step 2, uncheck the `Enable Google Analytics for this project` and click `Create Project`.

![](https://paper-attachments.dropbox.com/s_A5A6DACFC66FBAC46DB7218924BF83F9DB2BA1B6D57CDCC57D9717A408CB4383_1569793176884_image.png)

Now, as your project becomes ready, you will be redirected the project overview page. Here. add add a new Android app by clicking on the android robot icon.

![](https://paper-attachments.dropbox.com/s_A5A6DACFC66FBAC46DB7218924BF83F9DB2BA1B6D57CDCC57D9717A408CB4383_1569793345495_image.png)

You will be presented with a registration form now. Add the _Package Name_ of your app. For example, `com.cometchat.mychatapp`. You can skip the App Name, _Debug Signing Certificate SHA-1_ here. Click on _Register App_ button.

This will allow you to download the `google-services.json` file. This file is the configuration to integrate your app and Firebase and use any Firebase services from your app. In your case, that service is going to Firebase Messaging Service. Click on the Download google-services.json button and save it in the `app` directory of your app code.

![](https://www.gstatic.com/mobilesdk/160426_mobilesdk/images/android_studio_project_panel@2x.png)

Now, in your project’s root `build.gradle` file, copy this line (#12) in the `dependencies` section like this:

```
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext.kotlin_version = '1.3.21'
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.0'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "com.google.gms:google-services:4.3.2"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
```

And in your app’s `build.gradle` file, add Google Services plugin (line #24), Firebase Messaging dependency (line #23), CometChat Push Notification extension (line #20 & #21) and change the `applicationId` to the package name you added in the Firebase Console when creating the project (line #8). In this case, it was `com.comet.mychatapp` like the code below.

```
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.comet.mychatapp"
        minSdkVersion 21
        // ... 
    }
    // ...
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    // ...

    // CometChat Push Notification Extension
    implementation "com.cometchat:pro-android-chat-sdk:1.8.+"
    implementation "com.cometchat:pro-ext-pn:1.0.+"

    // Firebase Messaging
    implementation "com.google.firebase:firebase-messaging:20.0.0"

    // ...
}
apply plugin: 'com.google.gms.google-services'
```

Press _Sync Now_ button and this will be a successful build. Firebase is integrated in our app. Back to the Firebase Console, click the Next button and then continue to the console.

Now, click on the small gear icon beside the `Overview` button, and select `Project Settings` button.

![](https://paper-attachments.dropbox.com/s_A5A6DACFC66FBAC46DB7218924BF83F9DB2BA1B6D57CDCC57D9717A408CB4383_1569795726181_image.png)

Select the `Cloud Messaging` tab and copy the `Server key` to some temporary place. This will come handy in a moment.

![](https://paper-attachments.dropbox.com/s_A5A6DACFC66FBAC46DB7218924BF83F9DB2BA1B6D57CDCC57D9717A408CB4383_1569796003084_image.png)

Now, you are all set from the Firebase Console side. Let’s move to the CometChat dashboard now.

* * *

# Enabling CometChat Push Notification Extension

One of the great features of CometChat Pro is to provide you the **Extensions**. These extensions let you add more functionality with the full control over it to enable/disable at anytime. So to integrate Firebase Messaging (FCM) push notifications feature into CometChat, you need to enable the [Push Notification Extension](https://prodocs.cometchat.com/docs/push-notifications) from CometChat dashboard. Head to your [CometChat dashboard](https://prodocs.cometchat.com/docs/push-notifications) and click on the `Extensions` menu. Add `Push Notification` from the extensions list.

![](https://paper-attachments.dropbox.com/s_A5A6DACFC66FBAC46DB7218924BF83F9DB2BA1B6D57CDCC57D9717A408CB4383_1569796321067_image.png)

Once the extension is enabled, paste the copied FCM Server key it into the extension by clicking on **Actions → Settings**.

![](https://paper-attachments.dropbox.com/s_A5A6DACFC66FBAC46DB7218924BF83F9DB2BA1B6D57CDCC57D9717A408CB4383_1569796597626_image.png)

Now, CometChat and Firebase are integrated with each other. This means that CometChat will be able to use FCM as the push notifications service. Let’s head into the coding now.

* * *

# Add Firebase Messaging in Your App

As you have configured Firebase and CometChat project and setup their integration, its time to actually utilize this integration to send/receive push notifications in your chat apps. First step is to create the `FirebaseMessagingService` class. This class will manage the functionality when any push notification is triggered for your apps. This is where you will actually write code to create mobile notification with vibration, sound, etc. to show it to the user.

Create a new class and name it `FcmListenerService`. Now extend this from the `FirebaseMessagingService` class, and override the following methods:

- `onNewToken()` - This is called when the device token gets generated. The device token change when app deletes the Instance ID, or app is restored on a new device, or the user uninstalls / re-installs the app, or the user deletes the app cache. This method will provide you the new device token. This token is used to send the push notifications to that specific device.

- `onMessageReceived()` - This is the actual method which is called when any push notification is received by the device. This is where you will perform your notification functionality like generating the actual device notification with the data like sender name, message, avatar image etc. and show it to the user.

```
class FcmListenerService : FirebaseMessagingService()
{
    override fun onNewToken(token: String) {
      super.onNewToken(token)
    }

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
      Log.w("onMessageReceived", "Message Received from " + remoteMessage.from)

      PNExtension.getMessageFromJson(JSONObject(remoteMessage.data["message"]), object : CometChat.CallbackListener<BaseMessage>(){
          override fun onSuccess(baseMessage: BaseMessage?) {
              when(baseMessage)
              {
                  is TextMessage -> {
                      // Convert BaseMessage to TextMessage
                      var textMessage = baseMessage

                      // Send notification for this text message here
                      
                  }
              }
          }

          override fun onError(exception: CometChatException?) {
              exception?.printStackTrace()
          }
      })
  }
```

Once your class is ready, add it in the `AndroidManifest.xml` file in the `<application>` tag.

```
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.wajahatkarim3.chaty">

    <application>
      
        <!-- Firebase Messaging -->
        <service
            android:name=".FcmListenerService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
        
    </application>
</manifest>
```

In the traditional way, you have to get the device token in `onNewToken()` method, and then send it to the server or any remotely available storage. And each time any user sends the message, you have to hit some remote service which dispatches notifications to the target devices. And then in the `onMessageReceived()` method, you have to decode that message and extract data from it and show it to the user in form of any device notification.

But, CometChat is doing everything on its own and removes the dependency of the remote connection. It allows you to decode Firebase’s `RemoteMessage` through the `PNExtension.getMessageFromJson()` method in a very simple code.

![](https://paper-attachments.dropbox.com/s_A5A6DACFC66FBAC46DB7218924BF83F9DB2BA1B6D57CDCC57D9717A408CB4383_1569829766647_image.png)

Now we have all the boilerplate work in place. Let’s actually send / receive some messages.

* * *

# Sending and receiving messages

Firebase offers two ways to send messages to other devices.

1. Sending messages to the device IDs (tokens)
2. Sending messages to the topics.

Since the device IDs / tokens are managed by CometChat and the app must not store any device ID (either own or some other user’s) due to security reasons, this article will use [the topics approach to send messages](https://firebase.google.com/docs/cloud-messaging/android/topic-messaging). The topics in the FCM allows you to send messages to all devices that subscribed to a particular topic. The basic idea is that each user subscribes to any topic when logged in, and unsubscribes from it when logging out the app. Other users will send messages to that topic, and all the users who are subscribed to it will receive the messages.

To simply identify the topic of any user, you need to create the topic IDs with any pattern. This article will follow `CometChat App ID + USER + USER ID` pattern. For example, a topic for the App ID with 12345 for the user 7689 will be `12345_user_7689`.

So, head to the `LoginActivity.kt` file, and open the `performLogin()` method. In the `onSuccess()` callback of the `CometChat.login()` method, user will subscribe to the the topic. You can subscribe to any topic with the `FirebaseMessaging.getInstance().subsrcibeToTopic()` method.

```
// Register for the user type notifications
val topicId = getString(R.string.comet_app_id) + "_" + CometChatConstants.RECEIVER_TYPE_USER + "_" + user.uid
FirebaseMessaging.getInstance().subscribeToTopic(topicId)
```

To unsubscribe from this topic at the logging out, go to the `ProfileActivity.kt` file. In the the `onSuccess()` callback of the `CometChat.logout()`, add this code below.

```
// Unsubscribe from the user notifications
val topicId = getString(R.string.comet_app_id) + "_" + CometChatConstants.RECEIVER_TYPE_USER + "_" + user.uid
FirebaseMessaging.getInstance().unsubscribeFromTopic(topicId)
```

And voila. You’re all set. Now, when you send message to any other user, the `onMessageReceived()` method will be called in receiving user’s app. Since we have only added the line in logs, you will see a message in Logcat panel in Android Studio.

```
2019-09-30 06:44:55.457 5100-5271/com.comet.mychatapp W/onMessageReceived: Message Received from /topics/1234c23c123455_user_superhero1
```

You can do anything as per your app requirements regarding notifications in this `onMessageReceived` method. For the actual device notification, we will use a third-party library called as [Notify available at Github](https://github.com/Karn/notify) to generate the notifications easily. Follow the instructions on the library’s Read Me page and add this code in the `onMessageReceived()` in the `when` block for `TextMessage` to show the notification on device.

```
when(baseMessage)
{
    is TextMessage -> {
        // Convert BaseMessage to TextMessage
        var textMessage = baseMessage

        // Send notification for this text message here
        val notificationId = 124952
        Notify
            .with(this@FcmListenerService)
            .content { // this: Payload.Content.Default
                title = textMessage.sender.name
                text = textMessage.text
            }
            .alerting("high_priority_notification") {
                channelImportance = Notify.IMPORTANCE_HIGH
            }
            .show(notificationId)

    }
}
```

Now, when you send messages to any user, you will see a device notification like this.

[![Notification when app is in background](https://paper-attachments.dropbox.com/s_A5A6DACFC66FBAC46DB7218924BF83F9DB2BA1B6D57CDCC57D9717A408CB4383_1569834735313_Screenshot_1569834417.png)](//paper-attachments.dropbox.com/s_A5A6DACFC66FBAC46DB7218924BF83F9DB2BA1B6D57CDCC57D9717A408CB4383_1569834735313_Screenshot_1569834417.png "Notification when app is in background")Notification when app is in background

* * *

# Mute / Unmute Any User’s Notifications

One important feature of any modern chat app is the ability to mute / unmute notifications from other specific users. CometChat or Firebase do not directly provide any method to do this, but you can do it very easily with using some basic logic in the app.

In the Chaty app, we have added a popup menu in the Contacts screen where user can mute / unmute others users. When someone mutes any other user, the app stores the user’s ID with prefix `mute-`, for e.g. `mute-123456` in the `SharedPreferences`. This lets the app know that user `123456` is muted by the current logged in user. So, now in the `onMessageReceived()` method, app checks if the sender’s ID is in the muted list, then it doesn’t generate notification at all like the code below.

```
when(baseMessage)
{
    is TextMessage -> {
        // Convert BaseMessage to TextMessage
        var textMessage = baseMessage

        var prefs = PreferenceManager.getDefaultSharedPreferences(this@FcmListenerService)
        if ( prefs.getBoolean("mute-${textMessage.sender.uid}", false) )
        {
          // Don't send the notification as the contact is muted for notifications
        }
        else
        {
          // Send notification for this text message here
          val notificationId = 124952
          Notify
              .with(this@FcmListenerService)
              .content { // this: Payload.Content.Default
                  title = textMessage.sender.name
                  text = textMessage.text
              }
              .alerting("high_priority_notification") {
                  channelImportance = Notify.IMPORTANCE_HIGH
              }
              .show(notificationId)
        }
    }
}
```

Now, when you add `mute-USER_ID` in the app’s `SharedPreferences`, then app won’t show notifications of that specific user. You can see in the [`ContactsActivity`](https://github.com/wajahatkarim3/Chaty/blob/push-notifications-finish/app/src/main/java/com/wajahatkarim3/chaty/ContactsActivity.kt) in the final code at [push-notifications-finish](https://github.com/wajahatkarim3/Chaty/tree/push-notifications-finish) branch of Chaty on Github how this small tactic is being used to mute / unmute users.

* * *

# Showing Notifications in Specific Screens

Now as mute functionality is working, there’s one other case where you can avoid to show notifications. For example, if the user is already chatting with other user, and that specific chat is already open, then it doesn’t make sense to send / receive notifications while in that screen. The Chaty app handles this in a very similar approach as mute / unmute functionality is doing. The app is storing `isChatOn` and that user’s ID in the `SharedPreferences` in the `chatUserId`. And then in the `onMessageReceived()` method in `FcmListenerService` class, we are adding another check to see if the app should generate notification or not.

```
when(baseMessage)
{
    is TextMessage -> {
        // Convert BaseMessage to TextMessage
        var textMessage = baseMessage

        var prefs = PreferenceManager.getDefaultSharedPreferences(this@FcmListenerService)
        if ( prefs.getBoolean("mute-${textMessage.sender.uid}", false) 
          || (prefs.getBoolean("isChatOn", false) && prefs.getString("chatUserId", "").equals(textMessage.sender.uid)) )
        {
          // Don't send the notification as the contact is muted for notifications
        }
        else
        {
          // Send notification for this text message here
          val notificationId = 124952
          Notify
              .with(this@FcmListenerService)
              .content { // this: Payload.Content.Default
                  title = textMessage.sender.name
                  text = textMessage.text
              }
              .alerting("high_priority_notification") {
                  channelImportance = Notify.IMPORTANCE_HIGH
              }
              .show(notificationId)
        }
    }
}
```

This tells the app that chat screen is already open of the sender user, so there’s no need to generate the device notification.

You can do a lot of other stuff like generate popup notifications, showing unread messages count bubble etc. with this simple tactic. You can see how [`ChatActivity.kt`](https://github.com/wajahatkarim3/Chaty/blob/push-notifications-finish/app/src/main/java/com/wajahatkarim3/chaty/ChatActivity.kt.kt) is handling the `isChatOn` and `chatUserId` values in `SharedPreferences` to allow this simple feature on the [push-notifications-finish](https://github.com/wajahatkarim3/Chaty/tree/push-notifications-finish) branch of Chaty app on Github.

* * *

# Conclusion

You have now learned how to add push notifications feature to your Andorid apps in Kotlin using CometChat Pro and Firebase Messaging Service. You also learned about how to send / receive message notifications, mute / unmute specific users, and handling notifications for specific screens. You also learned about CometChat and how easy it is to build a custom chat app using its chat SDK. Congratulations on making it this far!

Don’t forget to checkout [CometChat documentation](https://prodocs.cometchat.com/docs/android-quick-start) for advanced features such as sending image and voice chat etc. And for the whole code of this tutorial, check `push-notification-finish` branch of the [Chaty app on Github here](https://prodocs.cometchat.com/docs/android-quick-start).

* * *

**If you liked this article, you can read my new articles below:**

**[⚡ Is Your Android Studio Always Slow? 🚀Here’s How to Speed Up Immediately.](https://dev.to/wajahatkarim/-is-your-android-studio-always-slow-heres-how-to-speed-up-immediately-4fi1)**  

**[📆 Reflections on 2018 — My Year In Review](https://link.medium.com/fKKVXLB8fZ)**


* * *

**Wajahat Karim** is a graduate from [NUST, Islamabad](http://nust.edu.pk), an experienced mobile developer, an active open source contributor, and co-author of two books [Learning Android Intents](https://www.amazon.com/Learning-Android-Intents-Muhammad-Usama/dp/1783289635) and [Mastering Android Game Development with Unity](https://www.amazon.com/Mastering-Android-Game-Development-Unity/dp/1783550775/). In his spare time, he likes to spend time with his family, do experiments on coding, loves to write about lots of things (mostly on blog and medium) and is passionate contributor to open source. In June 2018, one of his library became #1 on [Github Trending](https://github.com/trending). [His libraries](http://github.com/wajahatkarim3) have about 2000 stars on Github and are being used in various apps by the developers all around the globe. Follow him on [Twitter](https://twitter.com/WajahatKarim) and [Medium](https://medium.com/@wajahatkarim3) to get more updates about his work in Writing, Android and Open Source.

Also, if you have any questions you’d like him to answer, contact him through his website at [wajahatkarim.com](http://wajahatkarim.com) with DEAR WAJAHAT in the subject line.