Android SDK
Kotlin library that renders data-only FCM messages itself — notifications look identical in foreground, background or killed state, and every open is tracked reliably. Depends only on Firebase Messaging and AndroidX Core. Requires API 21+. Source on GitHub ↗
Install (JitPack)
Your app must already be connected to Firebase (google-services.json + the com.google.gms.google-services plugin). Then:
// settings.gradle.kts
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven("https://jitpack.io")
}
}
// app/build.gradle.kts
dependencies {
implementation("com.github.notibolt:notibolt-android:0.1.0")
}Initialize
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
Notibolt.initialize(
context = this,
appId = "YOUR_APP_ID" // panel → App → Settings
)
}
}On Android 13+ request the runtime permission:
if (Build.VERSION.SDK_INT >= 33) {
requestPermissions(arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1)
}Done — no manifest changes. The SDK ships its own FirebaseMessagingService and a transparent tap-handling activity (Android 12 trampoline-safe). The device appears in your panel under Devices.
Users & tags
Notibolt.setExternalUserId("user-42") // after login
Notibolt.removeExternalUserId() // after logout
Notibolt.setTags(mapOf("plan" to "pro")) // audience tags
Notibolt.setNotificationsEnabled(false) // in-app opt-out
Notibolt.deviceId // Notibolt device idImages, deep links, channels
- Images — pass
imageUrlwhen sending; rendered as a BigPicture notification. - Deep links — pass
url(https://…ormyapp://…); the tap is recorded, then the link opens. Without a URL the launcher activity opens. - Channels — defaults to a high-importance
notiboltchannel; sendandroidChannelfrom the API to route to any channel your app created.
Payload reference
| data key | Meaning |
|---|---|
notibolt_title / notibolt_body | Rendered title & body |
notibolt_image | Image URL, if provided |
notibolt_url | Deep link, if provided |
notibolt_channel | Target channel, if provided |
notibolt_notification_id / notibolt_device_id | Tracking ids |
| your keys | Anything passed in data |
Silent pushes (
contentAvailable: true) deliver only your data keys — nothing is rendered.Custom FirebaseMessagingService
Android allows one messaging service per app. If you need your own, extend Notibolt's — non-Notibolt messages fall through untouched:
class MyMessagingService : NotiboltMessagingService() {
override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message) // Notibolt handles its own
// your handling for other messages
}
}Tips
- Emulator / local dev:
apiUrl = "http://10.0.2.2:3001/api/v1"(the emulator's alias for your host machine). - Registration is an upsert keyed by push token — re-installs and token refreshes never create duplicate devices.
lastActiveAtand permission status refresh when the app comes to the foreground (throttled to every 5 minutes).