Respectlytics Respect lytics
Menu
Kotlin (Android) Onboarding completion Privacy-first

How to track onboarding completion in Kotlin (Android) without personal data

Onboarding completion is the cheapest activation signal you have, and the most common place teams accidentally start collecting PII ("let's tag the event with the user's email so we can re-engage them"). Respectlytics helps developers avoid collecting personal data in the first place: in Kotlin (Android), you emit a single `onboarding_complete` event with **no metadata** when the user finishes the last step of your flow. Funnel analysis is computed from the per-event-name session counts you already have. Below: a complete Kotlin (Android) pattern for the step-by-step funnel, what fails fast against the API, and the resulting comparison to Firebase / Mixpanel.

Treat each onboarding step as its own event name (`onboarding_step_1_complete`, `onboarding_step_2_complete`, …, `onboarding_complete`). Funnel rates are then session-grouped event-name counts — no per-user attribution required. The pattern below is what we recommend for most Kotlin (Android) apps.

Install the Kotlin (Android) SDK

kotlin Respectlytics
// 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)

kotlin Respectlytics
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)

kotlin Respectlytics
import com.respectlytics.android.Respectlytics

// Each step is its own event name:
Respectlytics.track("onboarding_step_1_complete")
Respectlytics.track("onboarding_step_2_complete")
// ...
Respectlytics.track("onboarding_complete")

// In a Compose UI:
@Composable
fun OnboardingFinalStep(onFinish: () -> Unit) {
    Button(onClick = {
        Respectlytics.track("onboarding_complete")
        onFinish()
    }) { Text("Get started") }
}

Distinct event names compose with the funnel auto-discovery — no manual configuration required.

Privacy & implementation notes

Common mistake: emitting one `onboarding_step_completed` event with `{step: 1}` as a parameter. Respectlytics's API rejects that with a 400. Instead, emit `onboarding_step_1_complete`, `onboarding_step_2_complete`, etc. as distinct event names — Respectlytics's funnel auto-discovery picks them up without any manual configuration.

The most frequent unintentional PII leak is sending the user's email or phone number as event metadata ("so we can re-engage them later"). The API returns a 400 with the offending field name — so this fails on the first integration test, not after months of unnoticed silent collection.

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

Onboarding completion event Firebase Analytics Mixpanel Respectlytics
Per-user identity app_instance_id distinct_id (if signed in) Never
Step metadata as parameters Up to 25 params per event Up to 250 properties Use distinct event_name per step
Email / signup_method as event property Recommended Recommended Rejected by API
Session-level funnel computation Yes (session-scoped tables) Yes (insights builder) Yes (default)
What you store about who finished a lot a lot event_name + session_id (rotated) + timestamp + platform + country

Frequently asked questions

Why use distinct event_names per step instead of one event with a step parameter?

Two reasons. First, Respectlytics's API rejects custom parameters — you have five fields, period. Second, distinct event names compose better with the automatic funnel-discovery feature: any monotonic sequence of event names in a session is a candidate funnel, no manual configuration required.

How do we segment onboarding completion by acquisition source?

If your acquisition source is one of N values (organic, paid_search, referral, …), emit it as part of the event name: `onboarding_complete_organic`, `onboarding_complete_paid_search`, etc. The aggregation engine groups them. Avoid composing freeform combinations — keep your taxonomy short.

What about completion time / duration?

Two timestamped events in the same session implicitly carry duration — compute it server-side in your dashboard, not as an event property. The raw timestamps stay on Respectlytics; the duration metric is your derivation.

Should we track each step view or just step completions?

Just completions, in nearly every case. "Saw step 3" with no completion is rarely actionable — a session that has `onboarding_step_2_complete` but no `onboarding_step_3_complete` already tells you they got stuck.

Related guides

Track what matters. Collect nothing you don't.

Five-field event schema, RAM-only event queue, no IDFA, no AAID, no persistent user IDs. Helps developers avoid collecting personal data in the first place.