Carillon docs

Kotlin SDK

Install and configure the Android SDK, connect Firebase Messaging, and handle taps.

Requirements: Android 7.0+ (minSdk 24), Java 17, and a Firebase project configured for the app.

Samples on this page show placeholders. Sign in to the dashboard in this browser and they fill in with your own organization, app and mobile key.

Install

dependencies {
  implementation("dev.carillon:carillon:0.2.0")
}

Add your Firebase project's google-services.json to the app module and apply the Google services plugin. Use a service account from that same project in Carillon.

plugins {
  id("com.google.gms.google-services")
}

Configure

import dev.carillon.sdk.CarillonCarillon.configure(context, key = "carillon_mk_live_your_mobile_key", debug = true)// Call from a coroutine with the current Activity.Carillon.requestPermission(activity)   // ALLOWED | DENIED

requestPermission takes an Activity because Android's request API does. Below API 33 nothing is asked and nothing is shown, and the answer comes on every version from NotificationManager.areNotificationsEnabled(), which is wider than the runtime permission and the only thing that also sees notifications switched off in Settings.

The permission is declared by the library

POST_NOTIFICATIONS is in the SDK's own manifest and merges into your app, so you do not declare it yourself. An app can only be granted a permission its own manifest declares.

Forward token rotation and messages

Declare the service the SDK ships:

<service android:name="dev.carillon.sdk.CarillonMessagingService"
         android:exported="false">
  <intent-filter>
    <action android:name="com.google.firebase.MESSAGING_EVENT" />
  </intent-filter>
</service>

Or, if you already have a FirebaseMessagingService, forward two calls from it. Firebase dispatches to one service per application, so declaring both leaves one of them never running.

override fun onNewToken(token: String) = Carillon.didRotate(token)
override fun onMessageReceived(message: RemoteMessage) = Carillon.didReceive(message)

Forward the launching intent

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  Carillon.didOpen(intent)
}

override fun onNewIntent(intent: Intent?) {
  super.onNewIntent(intent)
  Carillon.didOpen(intent)
}

Give the launcher activity android:launchMode="singleTop" so onNewIntent fires rather than a second instance being created.

Identity, tags, and open callbacks

import dev.carillon.sdk.tagOf

Carillon.identify("user-42")
Carillon.clearIdentity()

Carillon.setTags(mapOf("plan" to tagOf("pro"), "seats" to tagOf(12)))

Carillon.optOut()
Carillon.optIn()

Carillon.onOpened = { notification ->
  // notification.deliveryId, notification.data, notification.openedAtMs
}

val info = Carillon.debugInfo()

Environment

Always production. FCM has no sandbox; the field exists for iOS.

Foreground notifications

Configure Carillon in your Application, before Firebase callbacks arrive. CarillonMessagingService forwards received messages. If you own the service, call Carillon.didReceive(message) from onMessageReceived.

Carillon.onReceived = { notification ->
  // Read notification.data and return SUPPRESS for your own in-app UI.
  NotificationPresentation.SHOW
}

Carillon.clearNotifications()

The SDK displays foreground notification messages unless the handler returns SUPPRESS. It uses an existing android.notification.channel_id, or creates carillon_default (“Notifications”). Provide a carillon_notification_icon drawable for the small icon; the app icon is the fallback. Android 8+ channel settings control sound. Android 13+ requires notification permission before posting.

Images download through WorkManager with a 10-second budget and a 10 MiB cap. Failures keep the text. thread_id groups foreground notifications. Background notification messages are displayed by FCM itself; Carillon's foreground hook does not suppress those.

Clearing cancels pending display work and removes the app's notifications. It does not opt out the device. Continue forwarding launcher onCreate and onNewIntent to didOpen: the notification's tap intent carries the original data and delivery stamp.

Device ID

Carillon.deviceId is null before registration succeeds. Carillon.onDeviceIdChanged fires on first registration and on actual ID changes. The SDK sends its installation proof to preserve the ID across token rotation. See device identity.

Stored state

SharedPreferences under dev.carillon.sdk: the last registered state hash, the server device id, installation proof and queued events. Android backup may restore this state; the device ID is not an authentication credential.

Track opens · Devices · Troubleshooting

On this page