Push Notifications Example with Kotlin and Firebase

In this tutorial, we will use Kotlin to make a simple Android mobile app that will be able to receive push notifications sent from Firebase. I used to call these kind of messages “push messages” but the correct term for this tutorials will probably be a Firebase Cloud Messaging or the FCM which also stands for Firebase Cloud Messaging. 

I will share with you how to setup the Firebase support for your Android mobile app and how to receive and also display the received push messages. And the best part of course is that, I will be using Kotlin 🙂 for doing this.

For using Kotlin with Android Studio, I encourage you to use latest Canary version for Android Studio 3.0 which can be installed along side your stable Android Studio installation. At the time of writing this tutorial, latest Canary version available for Android Studio is Canary version 9, released on July 31st, 2017.

I will be using Firebase to setup Google Cloud messaging and making a sample app. Let us start by creating a project and setting up Firebase dependencies.

Create A New Project in Android Studio

To make this example very simple, I will create a brand new project in Android Studio, so that it does not have any extra code.

We will be creating a very simple Android app for receiving push notifications sent from Firebase and then showing them in a dialog bar when the app is open, and when the app is closed, show notifications in a notification bar.

I will give my new project a name “PlayWithNotifications”. The base package name will be com.appsdeveloperblog. Remember to check the “Include Kotlin support” while setting up the project.

As of now, the MainActivity.kt looks should like this:

package com.appsdeveloperblog.playwithnotifications

import android.os.Bundle
import android.support.v7.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

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

Adding Firebase support to Android Studio Project

To add Firebase support to Android Studio project follow these steps:

  1. Open your project in Android Studio
  2. Click Tools > Firebase to open the Assistant window.
Add Firebase support to Android Studio Project
Add Firebase support to Android Studio Project

Once that is done, the Firebase assistant will appear presenting many Firebase services, we need to select the “Cloud Messaging” feature:

Set up Firebase Cloud Messaging
Set up Firebase Cloud Messaging

Once you click ‘Setup Firebase Cloud Messaging’, following dialog will appear to confirm setting up the project:

Connect to Firebase
Connect to Firebase

Next, Android Studio will offer to add relevant code snippets to our app like for example Gradle dependency:

implementation 'com.google.firebase:firebase-messaging:11.0.4'
...
//Added as last line
apply plugin: 'com.google.gms.google-services'

With other changes, it is clearly shown in the dialog Android Studio presented us with a title Add FCM to your app:

Add FCM to your app
Add FCM to your app

Now, we will write some code in Kotlin and create our own Firebase service to use the notification data received as a payload. We also need a service with which we can receive a new token whenever it is refreshed. We will do this next.

FirebaseMessagingService. Know when FCM Message is received.

Make a new class in your Android project and extend FirebaseMessagingService. Once it is done. Your source code should like the one I have below:

import android.util.Log
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

class MyFirebaseMessagingService : FirebaseMessagingService() {

   val TAG = "Service"

   override fun onMessageReceived(remoteMessage: RemoteMessage?) {
       // Handle FCM messages here.
       // If the application is in the foreground handle both data and notification messages here.
       // Also if you intend on generating your own notifications as a result of a received FCM
       // message, here is where that should be initiated.
       Log.d(TAG, "From: " + remoteMessage!!.from)
       Log.d(TAG, "Notification Message Body: " + remoteMessage.notification.body!!)
   }
}

With the help of the above service, we will know whenever a new message arrives to our app. The onMessageReceived will be triggered every time there is a new FCM message. We can properly handle it and if needed generate our own notifications. 

Now let’s test our app by visiting Firebase panel and sending a new FCM message.

Send new FCM message
Send new FCM message

Once the message is sent, you should see the following entries in your Android Studio logcat:

Android Studio logcat entries
Android Studio logcat entries

Display Push Notification(FCM Message) in a Dialog Window

Now, let us show a simple dialog box by making simple changes. We will modify our FirebaseMessagingService like so:

package com.appsdeveloperblog.playwithnotifications

import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.media.RingtoneManager
import android.support.v4.app.NotificationCompat
import android.util.Log
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage

class MyFirebaseMessagingService : FirebaseMessagingService() {

   val TAG = "Service"

   override fun onMessageReceived(remoteMessage: RemoteMessage?) {
       // TODO: Handle FCM messages here.
       // If the application is in the foreground handle both data and notification messages here.
       // Also if you intend on generating your own notifications as a result of a received FCM
       // message, here is where that should be initiated.
       Log.d(TAG, "From: " + remoteMessage!!.from)
       Log.d(TAG, "Notification Message Body: " + remoteMessage.notification.body!!)

       sendNotification(remoteMessage)

       val intent = Intent([email protected], MainActivity::class.java)
       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
       intent.putExtra("message", remoteMessage.notification.body!!)
       startActivity(intent)
   }

   private fun sendNotification(remoteMessage: RemoteMessage) {

       val intent = Intent(this, MainActivity::class.java)
       intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
       val pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
               PendingIntent.FLAG_ONE_SHOT)

       val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)

       val notificationBuilder = NotificationCompat.Builder(this)
               .setContentText(remoteMessage.notification.body)
               .setAutoCancel(true)
               .setSmallIcon(R.mipmap.ic_launcher)
               .setSound(defaultSoundUri)
               .setContentIntent(pendingIntent)

       val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

       notificationManager.notify(0 /* ID of notification */, notificationBuilder.build())
   }
}

See how we added Notification Builder to create a notification and send the message we received to our activity.

Once we send an intent from our Service to the Activity, let us show a dialog. We will modify the onCreate(…) method like so:

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

   val intent = intent
   val message = intent.getStringExtra("message")

   if(!message.isNullOrEmpty()) {
       AlertDialog.Builder(this)
               .setTitle("Notification")
               .setMessage(message)
               .setPositiveButton("Ok", { dialog, which -> }).show()
   }
}

Once this change is made, we can send a new push message(Firebase Cloud Messaging) notification and it should appear in a dialog window on our device like on the picture below:

Display Notification Message
Display Notification Message

Common problems faced with Firebase

During integration of Firebase libraries in Android projects, we usually face common problems like:

  • Invalid library versions. Remember to add appropriate version of libraries, plugins and dependencies. Like the app level Gradle file looks like the one below for me:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
   compileSdkVersion 26
   buildToolsVersion "26.0.0"
   defaultConfig {
       applicationId "com.appsdeveloperblog.playwithnotifications"
       ...
   }
   buildTypes {
       ...
   }
}

dependencies {
   ...
   implementation 'com.google.firebase:firebase-messaging:11.2.2'
...
   implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
}

apply plugin: 'com.google.gms.google-services'

And root level Gradle file looks like this:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
   ext.kotlin_version = '1.1.3-2'
   repositories {
       google()
       jcenter()
   }
   dependencies {
       classpath 'com.android.tools.build:gradle:3.0.0-beta6'
       classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

       // NOTE: Do not place your application dependencies here; they belong
       // in the individual module build.gradle files
       classpath 'com.google.gms:google-services:3.1.0'
   }
}

allprojects {
   ...
}

task clean(type: Delete) {
   delete rootProject.buildDir
}
  • A message like “com.google.firebase.crash.FirebaseCrash is not linked. Skipping initialization.” can also be shown in the Android Monitor log. This one is not a problem because we are not using the Firebase Crash Analytics service.

I hope this tutorial was of some value to you and helped you set up Push Notifications or Google Firebase Cloud Messaging support for you Android mobile application built Kotlin.

To learn more about Android and Kotlin check these books and video courses:

 

Building Mobile Apps with Kotlin for Android

 

Building Mobile Apps with Kotlin and Firebase

Kotlin. Video Courses.

The Complete Android Kotlin Developer Course

Learn how to make online games, and apps for Android O, like Pokémon , twitter,Tic Tac Toe, and notepad using Kotlin. The Complete Android Kotlin Developer Course icon

Kotlin for Java Developers

Use your Java skills to learn Kotlin fast. Enhance career prospects and master Kotlin, including Java interoperability. Kotlin for Java Developers icon

Kotlin for Beginners: Learn Programming With Kotlin

Learn Kotlin from scratch! Grasp object-orientation and idiomatic Kotlin to realize coding projects and Android apps! Kotlin for Java Developers icon