Carillon docs

Kotlin SDK

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

For text, number, boolean and date attributes, SDK methods and audience operators, see Tags.

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.

Emulator setup

Use an Android Virtual Device image with Google APIs or Google Play and working Google Play services. A plain AOSP image cannot obtain an FCM token. Match the Firebase Android app's package name and use its google-services.json. A signed-in Google account is not listed as a prerequisite for modern FCM token registration; do not treat signing in as the fix for every missing token. Check Carillon.debugInfo() for the token and registration result before testing delivery. See Firebase's Android prerequisites.

Install

Use an explicit release version from Maven Central.

dependencies {
  implementation("com.exostack:carillon:0.5.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


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

Carillon.setTag("plan", "pro")
Carillon.setTagNumber("seats", 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

Merge tags

setTags merges keys; pass null to remove a key. Use setTag("plan", "pro") for one key and removeTag("plan") to delete it. Omitted keys remain unchanged. See tags and backend updates.

Receipt tracking

SDK 0.5.0 reports observed receipts from its receive callback and recovers notifications still present when the app starts or resumes. It does not report an open for these notifications. See receipt tracking for platform limits, offline reporting, and reading the timestamps in a trace.

On this page