DEV Community

Dallington Asingwire
Dallington Asingwire

Posted on • Edited on

How to send a push notification from node.js & display it in a kotlin app

In this article, we look at how you can send a push notification using Firebase and node.js to a mobile device.
First of all, I assume you have a mobile application in which you have Firebase configured. I also assume you have a node.js application.

First of all, you need to install 2 node libraries i.e firebase-admin and fcm-notification in your node application.

npm i firebase-admin --save
npm i fcm-notification --save
Enter fullscreen mode Exit fullscreen mode

You need to access your firebase account and private key which is a json file and include it in your node.js application. To get this private key, Go to Firebase > YouProjectName > Settings > Service Accounts > click Generate new private key button.
Import the following packages in your class or function in your node app.

var admin = require("firebase-admin");
var fcm = require('fcm-notification');
var serviceAccount = require("../config/privateKey.json");
const certPath = admin.credential.cert(serviceAccount);
var FCM = new fcm(certPath);
Enter fullscreen mode Exit fullscreen mode

I use firebase-admin to create a certificate from the private key json file. as seen on code line

const certPath = admin.credential.cert(serviceAccount);

This certificate created from the private key, is meant to authenticate your requests to your firebase account.

Function to send push notification

  sendPushNotification= (fcm_token, title, body) => {

    try{
        let message = {
            android: {
                notification: {
                    title: title,
                    body: body,
                },
            },
            token: fcm_token
        };

        FCM.send(message, function(err, resp) {
            if(err){
                throw err;
            }else{
                console.log('Successfully sent notification');
            }
        });

    }catch(err){
        throw err;
        }

    }

Enter fullscreen mode Exit fullscreen mode

sendPushNotification() is the function name i have created to send push notification. it takes 3 parameters i.e fcm_token, title and then body of the push notification. message is an object with android and token keys. Android is a key that indicates that the notification is being sent to a mobile device. Within android key, is notification object which holds title and body of the push notification. token is the key that holds the fcm token to which the notification is being sent.

FCM is the instance of fcm class from fcm-notification package which takes in the certificate created from the private key.
Within fcm class, is a method send which is accessed through the instance and it takes in 2 parameters i.e the message object and a callback function as seen in the code snippet below;

 FCM.send(message, function(err, resp) {
   if(err){
        throw err;
     }else{
        console.log('Successfully sent notification');
     }
   });
Enter fullscreen mode Exit fullscreen mode

This is how you can send a push notification to a mobile device from node.js using firebase.
Before I conclude, note that fcm tokens come from a mobile app in which firebase is configured and used. This means that you can actually access this token from database that is if you are storing it in your database.

In Kotlin (Mobile App)
In your kotlin code, you can setup your firebase service as follows;

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.media.RingtoneManager
import android.net.Uri
import android.os.Build
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import com.google.firebase.messaging.FirebaseMessaging
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

class CustomFirebaseMessagingService : FirebaseMessagingService() {

    override fun onMessageReceived(remoteMessage: RemoteMessage) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val mNotificationManager =
                getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            val importance = NotificationManager.IMPORTANCE_HIGH
            val mChannel = NotificationChannel(
                AppConstants.FCMConstants.CHANNEL_ID,
                AppConstants.FCMConstants.CHANNEL_NAME,
                importance
            )
            mChannel.description = AppConstants.FCMConstants.CHANNEL_DESC
            mNotificationManager.createNotificationChannel(mChannel)
        }

        if(remoteMessage.data.isNotEmpty()) {
            remoteMessage.data.let {

                var title = it["title"]
                var body = it["message"]
                println("From data object, notification title: $title and body: $body")
                sendNotification(title.toString(), body.toString())
            }
        }

        if (remoteMessage.notification != null){
            var title = remoteMessage.notification?.title
            var body = remoteMessage.notification?.body
            println("From notification object, notification title: $title and body: $body")
            if(!title.isNullOrEmpty() && !body.isNullOrEmpty()){
                sendNotification(title.toString(), body.toString())
            }
        }


    }


    private fun sendNotification(title: String, messageBody: String) {
        var intent: Intent? = null
        intent = Intent(this, HomeActivity::class.java)
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        val pendingIntent = PendingIntent.getActivity(
            this, 0 /* Request code */, intent,
            PendingIntent.FLAG_ONE_SHOT
        )
        var defaultSoundUri: Uri? = null
        defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val importance = NotificationManager.IMPORTANCE_HIGH
            val channel =
                NotificationChannel(
                    AppConstants.FCMConstants.CHANNEL_ID,
                    AppConstants.FCMConstants.CHANNEL_NAME,
                    importance
                )
            channel.description = AppConstants.FCMConstants.CHANNEL_DESC
            // Register the channel with the system; you can't change the importance
            // or other notification behaviors after this
            val notificationManager = this.getSystemService(
                NotificationManager::class.java
            )
            notificationManager.createNotificationChannel(channel)
        }
        val notificationBuilder: NotificationCompat.Builder =
            NotificationCompat.Builder(this, AppConstants.FCMConstants.CHANNEL_ID)
                .setStyle(NotificationCompat.BigTextStyle().bigText(messageBody))
                .setContentTitle(title)
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setPriority(NotificationManager.IMPORTANCE_MAX)
                .setChannelId(AppConstants.FCMConstants.CHANNEL_ID)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            notificationBuilder.setSmallIcon(R.drawable.push_icon)
            notificationBuilder.color = ContextCompat.getColor(this, R.color.pink_500)
        } else {
            notificationBuilder.setSmallIcon(R.mipmap.ic_launcher)
        }
        val notificationManager =
            this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build())
    }


    override fun onNewToken(p0: String) {
        Log.d("NotificationFCM", "Token: " + p0)
    }

}
Enter fullscreen mode Exit fullscreen mode

Thank you for reading through this article, I hope you find it helpful.

Top comments (0)