Notification Support¶
Kindly notification support in handover¶
First provide the SDK with the FCM token using:
When a push notification is received¶
Forward the notification to SDK using
The SDK will double-check if notification type is a Kindly notification before handling it.
Check if a notification is from Kindly¶
To determine if a notification should be handled by the Kindly SDK or another notification provider, use the following helper method:
This can be particularly useful when integrating with multiple push notification providers. Example usage:
override fun onMessageReceived(remoteMessage: RemoteMessage) {
if (KindlySDK.isKindlyNotification(remoteMessage)) {
// Handle with Kindly SDK
KindlySDK.handleNotification(remoteMessage)
} else {
// Handle with another notification provider (e.g., Braze, mParticle)
otherNotificationProvider.handleNotification(remoteMessage)
}
}
When the SDK Displays the Notification¶
Kindly silent pushes are encrypted; the SDK decrypts each one and posts a system notification with the decrypted title/body — except when the user is already actively reading the chat conversation. The display rule is:
| App state | Active screen | SDK presents the banner? |
|---|---|---|
| Background | any | ✅ Yes |
| Foreground | Chat conversation | ❌ No (the user can already see the message) |
| Foreground | Settings, language, image preview, host-app screens, etc. | ✅ Yes |
Heads-up display in the foreground requires the
kindly_channelnotification channel to remain atIMPORTANCE_HIGH(the SDK creates it that way) and the user to have granted thePOST_NOTIFICATIONSruntime permission on Android 13+.
Intercepting Notifications (shouldHandleNotification)¶
Every Kindly silent push that the SDK successfully decrypts is forwarded to the host app via the shouldHandleNotification(notification) method on KindlySDKInteraction — regardless of foreground/background state or which screen is on top. Use it to run side effects (analytics, logging, in-app indicators) or to take over the presentation entirely with your own UI.
| Scenario | Result |
|---|---|
| Interface not set | SDK presents the notification (subject to the display rule above) |
shouldHandleNotification returns true (default) |
SDK presents the notification (subject to the display rule above) |
shouldHandleNotification returns false |
SDK does not present anything — your app handles it |
The interface receives a ExternalNotification containing the decrypted fields plus the original RemoteMessage.data map for any extra fields your backend attached:
data class ExternalNotification(
val id: String, // decrypted chat_id
val title: String, // decrypted title
val body: String, // decrypted body
val data: Map<String, String>, // original RemoteMessage.data
)
Implementation¶
KindlySDK.`interface` = object : KindlySDKInteraction {
override fun didPressButton(chatButton: ButtonChat, chatLog: List<MessageChat>) {
// Handle button press if needed
}
override fun shouldHandleNotification(notification: ExternalNotification): Boolean {
// Always log every Kindly notification, regardless of who presents it
Analytics.track("kindly_notification_received", notification.id)
// Example: take over presentation when the app is in a custom in-app inbox
if (isShowingCustomInbox) {
customInbox.add(notification)
return false // SDK does not present its banner
}
return true // let the SDK present the banner
}
}
Notes¶
- The method has a default implementation that returns
true, so you only need to override it if you want to observe or intercept notifications. - The callback fires for every successfully decrypted Kindly push — it is not gated by the SDK's foreground/chat-screen display rule. Use it for analytics that need to run even when the SDK is on screen.
- The polarity matches
shouldHandleLink: returningtruemeans "the SDK should handle this", returningfalsemeans "I'll handle it myself". - Returning
falseonly suppresses the system notification — the underlying message has already been delivered to the chat session via the websocket //latestendpoint, so it will appear in the chat history when the user opens it.