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.
2. Add Firebase SDK:
- Add the Firebase SDK dependencies to your app-level gradle file.
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.
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.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"]
// 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))
// 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)
Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(
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)
.setVibrate(longArrayOf(1000, 1000, 1000, 1000, 1000))
.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(
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
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.
android:name=".MyFirebaseMessagingService"
<action android:name="com.google.firebase.MESSAGING_EVENT" />
<category android:name="android.intent.category.DEFAULT" />
<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
<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">
android:paddingHorizontal="3dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingExtra="0.04dp"
android:textColor="@color/black"
android:textStyle="bold" />
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/title"
android:textColor="@color/black"
android:textSize="13dp" />
<!-- this code for push image -->
android:visibility="gone"
android:layout_below="@+id/message"
android:layout_width="match_parent"
android:layout_height="200dp"/>
<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
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")
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 =
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
"to" : "dBgprIAnSueREXLmTLYcPD:APA91bE6gwYmXfe9tiO2zWY63S-cyO77_TOErUxv8n5HyDEgs_iCybPBm5PHLC40X1jEpgn6_p8ferqbapdov3LsGZ0MO3vmKAC9da1h0hz01K6xZ_uztOkJjib_rY8H-wgUKY0GXGnd",
"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",
{
"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"
}
}
this type you can send and receive notification through firebase.
Thank You !!!