Simple and easy to use Kotlin Multiplatform Push Notification library (using Firebase Cloud Messaging) targeting ios and android.
This library is used in FindTravelNow production KMP project.
You can check out Documentation for full library api information.
- 🔔 Local and Push Notification (Firebase Cloud Messaging)
- 📱 Multiplatform (android and iOS)
Before starting you need to setup basic setup using Firebase official guideline (like initializing project in Firebase, adding google-services.json
to android, GoogleService-Info.plist
to iOS).
- Android:
minSdkVersion 21
- iOS:
iOS 14.1
KMPNotifier is available on Maven Central. In your root project build.gradle.kts
file (or settings.gradle
file) add mavenCentral()
to repositories, and add 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 in commonMain
. Latest version: . In iOS framework part export this library as well.
sourceSets {
commonMain.dependencies {
api("io.github.mirzemehdi:kmpnotifier:<version>") // in iOS export this library
}
}
And in androidApp build.gradle.kts
file you apply google-services
plugin
plugins {
id("com.android.application")
id("com.google.gms.google-services")
}
In both platforms on Application Start you need to initialize library using
NotifierManager.initialize(NotificationPlatformConfiguration) //passing android or ios configuration depending on the platform
Android
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
/**
* By default showPushNotification value is true.
* When set showPushNotification to false foreground push notification will not be shown to user.
* You can still get notification content using #onPushNotification listener method.
*/
NotifierManager.initialize(
configuration = NotificationPlatformConfiguration.Android(
notificationIconResId = R.drawable.ic_launcher_foreground,
showPushNotification = true,
)
)
}
}
Also starting from Android 13(API Level 33) you need to ask runtime POST_NOTIFICATIONS
in activity. I created utility function that you can use in activity.
val permissionUtil by permissionUtil()
permissionUtil.askNotificationPermission() //this will ask permission in Android 13(API Level 33) or above, otherwise permission will be granted.
iOS
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 apnsToken setting 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
//By default showPushNotification value is true.
//When set showPushNotification to false foreground push notification will not be shown.
//You can still get notification content using #onPushNotification listener method.
NotifierManager.shared.initialize(configuration: NotificationPlatformConfigurationIos(showPushNotification: true))
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()
}
}
}
You can send either local or push notification.
val notifier = NotifierManager.getLocalNotifier()
val notificationId = notifier.notify("Title", "Body")
// or you can use below to specify ID yourself
notifier.notify(1, "Title", "Body")
notifer.remove(notificationId) //Removes notification by Id
notifier.removeAll() //Removes all notification
In this 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
}
})
NotifierManager.addListener(object : NotifierManager.Listener {
override fun onPushNotification(title:String?,body:String?) {
println("Push Notification notification title: $title")
}
})
NotifierManager.addListener(object : NotifierManager.Listener {
override fun onPayloadData(data: PayloadData) {
println("Push Notification payloadData: $data") //PayloadData is just typeAlias for Map<String,*>.
}
})
And you need to call below platform-specific functions in order to receive payload data properly.
Call NotifierManager.onCreateOrOnNewIntent(intent)
on launcher Activity's onCreate
and onNewIntent
methods.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
NotifierManager.onCreateOrOnNewIntent(intent)
...
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
NotifierManager.onCreateOrOnNewIntent(intent)
}
Call NotifierManager.onApplicationDidReceiveRemoteNotification(userInfo: userInfo)
on application's didReceiveRemoteNotification
method.
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) async -> UIBackgroundFetchResult {
NotifierManager.shared.onApplicationDidReceiveRemoteNotification(userInfo: userInfo)
return UIBackgroundFetchResult.newData
}
Make sure you follow previous step for getting payload data properly.
NotifierManager.addListener(object : NotifierManager.Listener {
override fun onNotificationClicked(data: PayloadData) {
super.onNotificationClicked(data)
println("Notification clicked, Notification payloadData: $data")
}
})
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")