Implementing Real-time Notifications in Android Using Firebase

Implementing Real-time Notifications in Android Using Firebase is Not easier than before! But we’ve put together some steps by which you can implement real-time notifications in Android using Firebase.

Check out the process of implementing real-time notifications in Android using Firebase

Firebase Cloud Messaging (FCM) is a powerful real-time solution that allows you to send notifications to Android client apps without incurring any charges. FCM is reliable and capable of transferring notifications with payloads of up to 4KB. In this article, we will walk you through the development of a sample Android app that demonstrates how you can utilize FCM to send and receive real-time notifications. Instead of using an app server, we will integrate the Firebase Admin SDK directly into our Android application.

Download Source Code

Implementing Firebase push notifications in an Android app using Kotlin is quite similar to the Java approach I mentioned earlier. Here’s a Kotlin-specific guide:

1. Set Up Firebase Project:

  • Create a new Firebase project if you don’t have one.
  • Through Android studio >Tools > Firebase > Cloud Messages > Connect > Add FCM to your App or You Can connect manually  Open Firebase create New Project > Go to Project Setting  Add App Package Name > Open Project Setting and Download google-services.json file and Put inside the app folder add dependency Manually.
  • Add your Android app to the project and provide the necessary details.
  • Implementing Real-time Notifications in Android Using Firebase

2. Add Firebase SDK:

  • Add the Firebase SDK dependencies to your app-level gradle file.
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
implementation 'com.google.firebase:firebase-messaging:22.0.0'
implementation 'com.google.firebase:firebase-messaging:22.0.0'
implementation 'com.google.firebase:firebase-messaging:22.0.0'
  • Sync your project to ensure the new dependencies are downloaded.

3. Implement the Firebase Messaging Service:

  • Create a Kotlin class that extends MyFirebaseMessagingService. This service class will handle incoming FCM messages.
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package com.example.firebasepushnotification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.util.Log
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
class MyFirebaseMessagingService : FirebaseMessagingService() {
private val channel_id = "web_app"
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
// println("++++++ " + Gson().toJson(remoteMessage))
if (remoteMessage.data.isNotEmpty()) {
val data = remoteMessage.data
val title = data["title"]
val body = data["body"]
val url = data["url"]
// above is optional key if you want normal notification then remove it from this
if (title != null && body != null ) {
showNotification(title, body, url)
}
}
}
private fun showNotification(title: String, message: String, url: String) {
val intent: Intent = if (url != null && url.startsWith("http")) {
Intent(Intent.ACTION_VIEW, Uri.parse(url))
} else {
// this code for app flow... where you want to land your notification after click
// if (AppPreference.getPreferenceValueByKey(this, AppPreference.INSTITUTE_ID).toString() != "") {
// Intent(this, InstHomeActivity::class.java)
// } else {
Intent(this, MainActivity::class.java)
// }
}
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(
this, 0, intent,
PendingIntent.FLAG_MUTABLE
)
val contentView = RemoteViews(packageName, R.layout.notification)
contentView.setTextViewText(R.id.title, title)
contentView.setTextViewText(R.id.message, message)
val notificationBuilder = NotificationCompat.Builder(this, channel_id)
.setSmallIcon(R.mipmap.ic_launcher)
.setAutoCancel(true)
.setVibrate(longArrayOf(1000, 1000, 1000, 1000, 1000))
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setLights(Color.BLUE, 500, 500)// Set priority to PRIORITY_MAX
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
notificationBuilder.setStyle(NotificationCompat.DecoratedCustomViewStyle())
}
notificationBuilder.setCustomContentView(contentView)
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel(
channel_id,
"web_app",
NotificationManager.IMPORTANCE_HIGH
)
notificationManager.createNotificationChannel(notificationChannel)
}
notificationManager.notify(0, notificationBuilder.build())
}
override fun onNewToken(token: String) {
Log.d(TAG, "Refreshed token: $token")
sendRegistrationToServer(token)
}
private fun sendRegistrationToServer(token: String?) {
Log.d(TAG, "sendRegistrationTokenToServer($token)")
// Send the registration token to your server if needed
}
companion object {
private const val TAG = "MyFirebaseMsgService"
}
}
package com.example.firebasepushnotification import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.content.Intent import android.graphics.Color import android.net.Uri import android.os.Build import android.util.Log import android.widget.RemoteViews import androidx.core.app.NotificationCompat import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage class MyFirebaseMessagingService : FirebaseMessagingService() { private val channel_id = "web_app" override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) // println("++++++ " + Gson().toJson(remoteMessage)) if (remoteMessage.data.isNotEmpty()) { val data = remoteMessage.data val title = data["title"] val body = data["body"] val url = data["url"] // above is optional key if you want normal notification then remove it from this if (title != null && body != null ) { showNotification(title, body, url) } } } private fun showNotification(title: String, message: String, url: String) { val intent: Intent = if (url != null && url.startsWith("http")) { Intent(Intent.ACTION_VIEW, Uri.parse(url)) } else { // this code for app flow... where you want to land your notification after click // if (AppPreference.getPreferenceValueByKey(this, AppPreference.INSTITUTE_ID).toString() != "") { // Intent(this, InstHomeActivity::class.java) // } else { Intent(this, MainActivity::class.java) // } } intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) val pendingIntent = PendingIntent.getActivity( this, 0, intent, PendingIntent.FLAG_MUTABLE ) val contentView = RemoteViews(packageName, R.layout.notification) contentView.setTextViewText(R.id.title, title) contentView.setTextViewText(R.id.message, message) val notificationBuilder = NotificationCompat.Builder(this, channel_id) .setSmallIcon(R.mipmap.ic_launcher) .setAutoCancel(true) .setVibrate(longArrayOf(1000, 1000, 1000, 1000, 1000)) .setOnlyAlertOnce(true) .setContentIntent(pendingIntent) .setPriority(NotificationCompat.PRIORITY_MAX) .setLights(Color.BLUE, 500, 500)// Set priority to PRIORITY_MAX if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { notificationBuilder.setStyle(NotificationCompat.DecoratedCustomViewStyle()) } notificationBuilder.setCustomContentView(contentView) val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val notificationChannel = NotificationChannel( channel_id, "web_app", NotificationManager.IMPORTANCE_HIGH ) notificationManager.createNotificationChannel(notificationChannel) } notificationManager.notify(0, notificationBuilder.build()) } override fun onNewToken(token: String) { Log.d(TAG, "Refreshed token: $token") sendRegistrationToServer(token) } private fun sendRegistrationToServer(token: String?) { Log.d(TAG, "sendRegistrationTokenToServer($token)") // Send the registration token to your server if needed } companion object { private const val TAG = "MyFirebaseMsgService" } }
package com.example.firebasepushnotification

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Build
import android.util.Log
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

class MyFirebaseMessagingService : FirebaseMessagingService() {
    private val channel_id = "web_app"

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)

//        println("++++++ " + Gson().toJson(remoteMessage))

        if (remoteMessage.data.isNotEmpty()) {
            val data = remoteMessage.data
            val title = data["title"]
            val body = data["body"]
            val url = data["url"]
//            above is optional key if you want normal notification then remove it from this 

            if (title != null && body != null ) {
                showNotification(title, body, url)
            }
        }
    }

    private fun showNotification(title: String, message: String, url: String) {
        val intent: Intent = if (url != null && url.startsWith("http")) {
            Intent(Intent.ACTION_VIEW, Uri.parse(url))
        } else {
//            this code for app flow... where you want to land your notification after click

//            if (AppPreference.getPreferenceValueByKey(this, AppPreference.INSTITUTE_ID).toString() != "") {
//                Intent(this, InstHomeActivity::class.java)
//            } else {
            Intent(this, MainActivity::class.java)
//            }
        }

        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        val pendingIntent = PendingIntent.getActivity(
            this, 0, intent,
            PendingIntent.FLAG_MUTABLE
        )


        val contentView = RemoteViews(packageName, R.layout.notification)
        contentView.setTextViewText(R.id.title, title)
        contentView.setTextViewText(R.id.message, message)


        val notificationBuilder = NotificationCompat.Builder(this, channel_id)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setAutoCancel(true)
            .setVibrate(longArrayOf(1000, 1000, 1000, 1000, 1000))
            .setOnlyAlertOnce(true)
            .setContentIntent(pendingIntent)
            .setPriority(NotificationCompat.PRIORITY_MAX)
            .setLights(Color.BLUE, 500, 500)// Set priority to PRIORITY_MAX

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            notificationBuilder.setStyle(NotificationCompat.DecoratedCustomViewStyle())
        }

        notificationBuilder.setCustomContentView(contentView)

        val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationChannel = NotificationChannel(
                channel_id,
                "web_app",
                NotificationManager.IMPORTANCE_HIGH
            )
            notificationManager.createNotificationChannel(notificationChannel)
        }

        notificationManager.notify(0, notificationBuilder.build())
    }


    override fun onNewToken(token: String) {
        Log.d(TAG, "Refreshed token: $token")
        sendRegistrationToServer(token)
    }

    private fun sendRegistrationToServer(token: String?) {
        Log.d(TAG, "sendRegistrationTokenToServer($token)")
        // Send the registration token to your server if needed
    }

    companion object {
        private const val TAG = "MyFirebaseMsgService"
    }
}

4. Register the Service:

  • Declare your MyFirebaseMessagingService class in the manifest file.
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<service
android:name=".MyFirebaseMessagingService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
<service android:name=".MyFirebaseMessagingService" android:exported="true"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </service>
<service
      android:name=".MyFirebaseMessagingService"
      android:exported="true">
      <intent-filter>
          <action android:name="com.google.firebase.MESSAGING_EVENT" />
          <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
  </service>

6. Create new Layout (notification.xml) for custom design

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingHorizontal="5dp">
<RelativeLayout
android:paddingHorizontal="3dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingExtra="0.04dp"
android:text="Title"
android:textColor="@color/black"
android:textSize="15dp"
android:textStyle="bold" />
<TextView
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/title"
android:ellipsize="none"
android:maxLines="10"
android:text="Message"
android:textColor="@color/black"
android:textSize="13dp" />
<!-- this code for push image -->
<ImageView
android:visibility="gone"
android:layout_below="@+id/message"
android:layout_width="match_parent"
android:layout_height="200dp"/>
</RelativeLayout>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/linear_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingHorizontal="5dp"> <RelativeLayout android:paddingHorizontal="3dp" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:lineSpacingExtra="0.04dp" android:text="Title" android:textColor="@color/black" android:textSize="15dp" android:textStyle="bold" /> <TextView android:id="@+id/message" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/title" android:ellipsize="none" android:maxLines="10" android:text="Message" android:textColor="@color/black" android:textSize="13dp" /> <!-- this code for push image --> <ImageView android:visibility="gone" android:layout_below="@+id/message" android:layout_width="match_parent" android:layout_height="200dp"/> </RelativeLayout> </RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linear_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:paddingHorizontal="5dp">

    <RelativeLayout
        android:paddingHorizontal="3dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:lineSpacingExtra="0.04dp"
            android:text="Title"
            android:textColor="@color/black"
            android:textSize="15dp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/message"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@+id/title"
            android:ellipsize="none"
            android:maxLines="10"
            android:text="Message"
            android:textColor="@color/black"
            android:textSize="13dp" />

<!--        this code for push image -->

        <ImageView
            android:visibility="gone"
            android:layout_below="@+id/message"
            android:layout_width="match_parent"
            android:layout_height="200dp"/>

    </RelativeLayout>

</RelativeLayout>

now you can send notification through firebase and you receive notification in your device.

Extra:- If you want to send notification through our own dashboard or particular user then you need to get device token and save to our server through api

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
private fun getToken() {
try {
FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w(ContentValues.TAG, "Fetching FCM registration token failed", task.exception)
return@OnCompleteListener
}
// Get new FCM registration token
var devicetoken = task.result
if (devicetoken != null && devicetoken != "") {
//here you can perform task with device token
println("++++ $devicetoken")
}
})
} catch (e: Exception) {
}
}
private fun getToken() { try { FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task -> if (!task.isSuccessful) { Log.w(ContentValues.TAG, "Fetching FCM registration token failed", task.exception) return@OnCompleteListener } // Get new FCM registration token var devicetoken = task.result if (devicetoken != null && devicetoken != "") { //here you can perform task with device token println("++++ $devicetoken") } }) } catch (e: Exception) { } }
private fun getToken() {
    try {
        FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
            if (!task.isSuccessful) {
                Log.w(ContentValues.TAG, "Fetching FCM registration token failed", task.exception)
                return@OnCompleteListener
            }

            // Get new FCM registration token
            var  devicetoken = task.result
            if (devicetoken != null && devicetoken != "") {

           //here you can perform task with device token
                println("++++ $devicetoken")
            }
        })

    } catch (e: Exception) {

    }
}

For Sending firebase notification through postman

add url :- https://fcm.googleapis.com/fcm/send

Next, add data in header like this in value key =

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Authorization:key = ENTER YOUR OWN AUTH KEY
Content-Type:application/json
Authorization:key = ENTER YOUR OWN AUTH KEY Content-Type:application/json
Authorization:key = ENTER YOUR OWN AUTH KEY
Content-Type:application/json

add data in body :- to–> Device Token (where you want to post notification) 

data:- body: Your Message
title:- Notification Title
url :- if you want to post any other data

 

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
{
"to" : "dBgprIAnSueREXLmTLYcPD:APA91bE6gwYmXfe9tiO2zWY63S-cyO77_TOErUxv8n5HyDEgs_iCybPBm5PHLC40X1jEpgn6_p8ferqbapdov3LsGZ0MO3vmKAC9da1h0hz01K6xZ_uztOkJjib_rY8H-wgUKY0GXGnd",
"data" : {
"body" : "An aerospace engineer, Karidhal has been responsible for guiding Chandrayaan-2 spacecraft through its space journey. She held overall responsibility for insertion of the spacecraft into the lunar orbit, and for its final An aerospace engineer, Karidhal has been responsible for guiding Chandrayaan-2 spacecraft through its space ",
"title": "Notification Title",
"url" : "123"
}
}
{ "to" : "dBgprIAnSueREXLmTLYcPD:APA91bE6gwYmXfe9tiO2zWY63S-cyO77_TOErUxv8n5HyDEgs_iCybPBm5PHLC40X1jEpgn6_p8ferqbapdov3LsGZ0MO3vmKAC9da1h0hz01K6xZ_uztOkJjib_rY8H-wgUKY0GXGnd", "data" : { "body" : "An aerospace engineer, Karidhal has been responsible for guiding Chandrayaan-2 spacecraft through its space journey. She held overall responsibility for insertion of the spacecraft into the lunar orbit, and for its final An aerospace engineer, Karidhal has been responsible for guiding Chandrayaan-2 spacecraft through its space ", "title": "Notification Title", "url" : "123" } }
{
 "to" : "dBgprIAnSueREXLmTLYcPD:APA91bE6gwYmXfe9tiO2zWY63S-cyO77_TOErUxv8n5HyDEgs_iCybPBm5PHLC40X1jEpgn6_p8ferqbapdov3LsGZ0MO3vmKAC9da1h0hz01K6xZ_uztOkJjib_rY8H-wgUKY0GXGnd",
 "data" : {
     "body" : "An aerospace engineer, Karidhal has been responsible for guiding Chandrayaan-2 spacecraft through its space journey. She held overall responsibility for insertion of the spacecraft into the lunar orbit, and for its final   An aerospace engineer, Karidhal has been responsible for guiding Chandrayaan-2 spacecraft through its space ",
     "title": "Notification Title",
     "url" : "123"
 }
}

Real time notifications in android using firebase

Real time notifications in android using firebase

this type you can send and receive notification through firebase.
Real time notifications in android using firebase

Thank You !!!