Blog Infos
Author
Published
Topics
, ,
Published

Push Notification in Kotlin Multiplatform

Push Notification in Kotlin Multiplatform

In this blog post I will share with you how to implement push notifications using Firebase in Kotlin Multiplatform (targeting iOS and Android platforms).

Push notifications play a crucial role in keeping users engaged and informed about important updates in your Kotlin Multiplatform (KMP) applications. While Firebase provides a robust platform for handling push notifications, integrating it seamlessly across both Android and iOS platforms in a KMP project can be a challenging task since Firebase doesn’t yet support Kotlin Multiplatform. For this purpose we will use the KMPNotifier library. I developed this push notification library to serve as the bridge between your Kotlin Multiplatform codebase and the implementation of push notifications. Whether you’re aiming to send local notifications or push notifications, KMPNotifier provides a clean and efficient API for managing the entire notification lifecycle. With KMPNotifier you can listen for token changes, subscribe or unsubscribe to topics, get current user token, or just send local notifications for any events.

Zeroth Step — Basic setup using Firebase official guideline

Before starting you need to setup basic things using the Firebase official guidelines (like initializing project in Firebase, adding google-services.json to Android, and GoogleService-Info.plist to iOS).
Firebase setup for iOS — https://firebase.google.com/docs/ios/setup
Firebase setup for Android— https://firebase.google.com/docs/android/setup

Gradle Setup

KMPNotifier is available on Maven Central. In your root project build.gradle.kts file (or settings.gradle file) add mavenCentral() to repositories, and google-services plugin to plugins.

plugins {
  id("com.android.application") version "8.1.3" apply false
  id("org.jetbrains.kotlin.multiplatform") version "1.9.20" apply false
  id("com.google.gms.google-services") version "4.4.0" apply false
}

repositories { 
  mavenCentral()
}

Then in your shared module you add dependency with latest version in commonMain. Latest version(https://github.com/mirzemehdi/KMPNotifier/releases):

In iOS framework part you need to export this library as well.

sourceSets {
  commonMain.dependencies {
    api("io.github.mirzemehdi:kmpnotifier:<version>") // in iOS export this library
  }
}
listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach { iosTarget ->
        iosTarget.binaries.framework {
            export(project("io.github.mirzemehdi:kmpnotifier:<version>"))
            baseName = "shared"
            isStatic = true
        }
    }

And in androidApp build.gradle.kts file you apply google-services plugin

plugins {
  id("com.android.application")
  id("com.google.gms.google-services")
}
Platform Setup

In both platforms on Application Start you need to initialize library using initialize method :

NotifierManager.initialize(NotificationPlatformConfiguration) //passing android or ios configuration depending on the platform

Android Setup

class MyApplication : Application() {
   override fun onCreate() {
       super.onCreate()
       NotifierManager.initialize(
           configuration = NotificationPlatformConfiguration.Android(
               notificationIconResId = R.drawable.ic_launcher_foreground,
           )
       )
   }
}

Also starting from Android 13(API Level 33) you need to ask runtime POST_NOTIFICATIONS in activity. I created a utility function that you can use in the activity.

permissionUtil.askNotificationPermission() //this will ask permission in Android 13(API Level 33) or above, otherwise permission will be granted.

iOS Setup
First, you just need to include FirebaseMessaging library to your iOS app from Xcode. Then on application start you need to call both FirebaseApp initialization and NotifierManager initialization methods, and setting apnsToken as below. Don’t forget to add Push Notifications and Background Modes (Remote Notifications) signing capability in Xcode.

import SwiftUI
import shared
import FirebaseCore
import FirebaseMessaging

class AppDelegate: NSObject, UIApplicationDelegate {
  func application(_ application: UIApplication,
                   didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
      FirebaseApp.configure() //important
      NotifierManager.shared.initialize(configuration: NotificationPlatformConfigurationIos.shared)
      
    return true
  }
  func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Messaging.messaging().apnsToken = deviceToken
  }
    
}
@main
struct iOSApp: App {
    
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
Usage

You can send either local or push notification.

Local Notification

val notifier = NotifierManager.getLocalNotifier()
notifier.notify("Title", "Body") //Sends local notification

Push Notification

Listen for push notification token changes -> In this callback method you can send notification token to the server.

NotifierManager.addListener(object : NotifierManager.Listener {
  override fun onNewToken(token: String) {
    println("onNewToken: $token") //Update user token in the server if needed
  }
})

Other useful functions

NotifierManager.getPushNotifier().getToken() //Get current user push notification token
NotifierManager.getPushNotifier().deleteMyToken() //Delete user's token for example when user logs out 
NotifierManager.getPushNotifier().subscribeToTopic("new_users") 
NotifierManager.getPushNotifier().unSubscribeFromTopic("new_users")

This article was previously published on proandroiddev.com

Job Offers

Job Offers

There are currently no vacancies.

OUR VIDEO RECOMMENDATION

, ,

Migrating to Jetpack Compose – an interop love story

Most of you are familiar with Jetpack Compose and its benefits. If you’re able to start anew and create a Compose-only app, you’re on the right track. But this talk might not be for you…
Watch Video

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer for Jetpack Compose
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engin ...
Google

Migrating to Jetpack Compose - an interop love story

Simona Milanovic
Android DevRel Engineer f ...
Google

Jobs

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
I love Swift enums, even though I am a Kotlin developer. And iOS devs…
READ MORE
blog
Using annotations in Kotlin has some nuances that are useful to know
READ MORE
blog
One of the latest trends in UI design is blurring the background content behind the foreground elements. This creates a sense of depth, transparency, and focus,…
READ MORE
blog
Now that Android Studio Iguana is out and stable, I wanted to write about…
READ MORE

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu