Wire the call into the same callback that receives the system permission result. On success, emit `push_optin`. If you also want to measure declines (most teams do), emit `push_decline` on the negative result. Don't pass the device token or any registration ID as metadata — your push backend already has those.
▸ Install the Kotlin (Android) SDK
// build.gradle.kts (app module)
dependencies {
implementation("com.respectlytics:respectlytics-kotlin:3.0.0")
}
Pure Kotlin coroutines implementation. No Java dependencies, no Google Play Services dependencies. ~300KB DEX overhead — compare to roughly 3.8MB for Firebase Analytics (a measurable cold-start improvement on lower-end devices).
▸ Initialize Respectlytics in Kotlin (Android)
import com.respectlytics.android.Respectlytics
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
Respectlytics.configure(this, appKey = "<YOUR_APP_KEY>")
}
}
Initialize once in `Application.onCreate`. No additional permissions in the manifest — `INTERNET` is sufficient. The SDK does not request `AD_ID`, does not query `AdvertisingIdClient`, and does not declare `ACCESS_NETWORK_STATE`.
▸ Track the event in Kotlin (Android)
import androidx.activity.result.contract.ActivityResultContracts
import com.respectlytics.android.Respectlytics
class MainActivity : ComponentActivity() {
private val pushPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { granted ->
Respectlytics.track(if (granted) "push_optin" else "push_decline")
}
private fun requestPushPermission() {
if (Build.VERSION.SDK_INT >= 33) {
pushPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
} else {
// Pre-Android 13: notifications are enabled by default; emit a synthetic optin.
Respectlytics.track("push_optin_implicit_pre_android_13")
}
}
}
On Android 13+ you must request `POST_NOTIFICATIONS`. On older versions, permission is granted by default — emit a separate event name (or skip) so you can distinguish the two cases in analytics.
✦ Privacy & implementation notes
Your push-delivery backend (APNs, FCM, OneSignal, Pusher Beams, etc.) already has the device push token — that's where it lives operationally. Sending it to Respectlytics would just be re-creating a per-user dataset you've already built elsewhere. The API rejects it.
Most push-related product decisions are about *rate*, not *state*: "does moving the prompt to post-onboarding move our DE iOS opt-in rate?". You don't need per-user opt-in state in your analytics pipeline to answer that — you need session-grouped event counts.
Many teams discover the `com.google.android.gms.permission.AD_ID` permission in their merged manifest only after Google Play flags them — usually because a transitive dependency dragged it in. Respectlytics's Kotlin SDK has no Google Play Services dependency at all, so it cannot contribute to that merge.
The SDK is implemented as pure Kotlin coroutines with no Java sources, no RxJava, and no platform channels. Events are queued in a `Channel<Event>` buffered to a small ring (RAM-only), drained by a coroutine that flushes every 30 seconds or on backgrounding. There is no SharedPreferences usage.
⇋ How this compares to other analytics SDKs
| Push opt-in event | Firebase Analytics | Mixpanel | Respectlytics |
|---|---|---|---|
| Device push token stored | Yes (FCM token in user property) | Yes (in profile) | Never |
| Per-user opt-in state | Yes | Yes | Out of scope (your push backend tracks this) |
| Prompt timing as event property | Recommended | Recommended | Use distinct event_name |
| iOS provisional opt-in distinguishable | Manual (via param) | Manual (via property) | Use distinct event_name (push_provisional_optin) |
| Opt-in rate by country / platform | Yes | Yes | Yes (default aggregation) |
❓ Frequently asked questions
How do we know which users opted in if we don't store user state?
You don't, in your analytics. Your push-delivery backend (APNs, FCM, OneSignal, etc.) already has the authoritative opt-in state per device token — that's its job. Respectlytics tells you the opt-in *rate* over sessions, which is the metric you optimize for product decisions.
Can we A/B-test opt-in prompt timing?
Yes — emit distinct event names per prompt-timing variant: `push_optin_at_onboarding`, `push_optin_post_first_session`, etc. The aggregation gives you per-variant conversion rate without any per-user assignment stored.
Should we track when the prompt was *shown* in addition to the result?
Yes, with two event names: `push_prompt_shown` and `push_optin` (or `push_decline`). The session-grouped count gives you prompt → grant rate directly.
What about iOS 15+ provisional authorization?
If you use `provisional` authorization (which doesn't show a prompt and delivers quietly until the user upgrades to full), emit `push_provisional_optin` as a distinct event. It's a different state with different downstream implications, so don't conflate it with the explicit opt-in event.