On this page
Many apps track either everything (thousands of meaningless events) or nothing. Good instrumentation starts from questions: where do new users drop off, which features drive retention, which crashes affect most users, and adds just enough events to answer them.
The observability stack
Designing analytics events
- Write the questions first: "What % of new users create their first note within a day?"
- Define a small event set: verbs in snake_case, with consistent parameters.
- Document it in a tracking plan, and review new events in PRs.
sealed class AnalyticsEvent(val name: String, val params: Map<String, Any> = emptyMap()) {
data object SignUpCompleted : AnalyticsEvent("sign_up_completed")
data class NoteCreated(val source: String) : AnalyticsEvent("note_created", mapOf("source" to source))
data class PaywallViewed(val placement: String) : AnalyticsEvent("paywall_viewed", mapOf("placement" to placement))
data class PurchaseCompleted(val productId: String) : AnalyticsEvent("purchase_completed", mapOf("product_id" to productId))
}
interface Analytics { fun log(event: AnalyticsEvent) }
class FirebaseAnalyticsLogger(private val fa: FirebaseAnalytics) : Analytics {
override fun log(event: AnalyticsEvent) {
fa.logEvent(event.name, Bundle().apply {
event.params.forEach { (k, v) ->
when (v) {
is String -> putString(k, v)
is Long -> putLong(k, v)
is Int -> putLong(k, v.toLong())
is Double -> putDouble(k, v)
}
}
})
}
}A typed wrapper prevents typos, makes events searchable in code, and lets you swap providers, or use a no-op in tests and debug builds.
Crash reporting that helps you fix things
// Custom keys and breadcrumbs make crashes reproducible (never include personal data)
Firebase.crashlytics.setCustomKeys {
key("feature_flag_new_checkout", flags.isEnabled(Flag.NEW_CHECKOUT))
key("current_screen", "Checkout")
}
Firebase.crashlytics.log("Tapped Pay with UPI") // breadcrumb
// Non-fatal: important failures that didn't crash
try {
paymentRepository.confirm(orderId)
} catch (e: PaymentException) {
Firebase.crashlytics.recordException(e)
showPaymentError()
}- Upload R8 mapping files so stack traces are readable. The Crashlytics Gradle plugin can do this.
- Triage by users affected and trend after release, not just event counts.
- Use Android Studio's App Quality Insights to jump from crash clusters to source.
Privacy and consent
- Never log personal data (names, emails, phone numbers, message content) in events or crash logs.
- Respect consent requirements in your markets, and provide an opt-out (for example
setAnalyticsCollectionEnabled(false)). - Disclose analytics and crash SDKs in the Play Data safety form and privacy policy.
- Disable collection in debug builds to keep data clean.
From data to decisions
Onboarding drop-off
The funnel shows 40% drop at a permission screen. Move the permission request into context, then measure again.
Crash after release
A new cluster on one Android version. Halt the staged rollout, fix it, and resume.
Feature value
Users who use search in week 1 retain better. Make search more discoverable.
Frequently asked questions
How many events should I track?
Usually a few dozen well-defined events are enough. Each event should answer a question someone will actually ask.
Crashlytics or Android vitals?
Both. Vitals shows system-level data for all Play users, including ANRs. Crashlytics adds custom context, non-fatals and faster iteration.
Can analytics slow my app?
SDK initialisation and heavy logging can affect startup. Initialise lazily where possible, and measure.
Conclusion
Instrument with intent: a small, documented event set for product questions, crash reporting with context and non-fatals for engineering, Android vitals for system health, and privacy by design throughout.
Next step: launch your own product with Building and Launching an Android App as a Solo Developer.
Official references
๐ฑ Apps built by Yunok Tech
Real Android apps on Google Play, free to download.
Walzi4K wallpapers for lock and home screenGet it โธ
NotiVaultNotification history: recover dismissed notificationsGet it โธ
Ready to build real Android applications?
Shipping is a skill of its own. Learn to take an app from a working build to a polished, signed release that real users can install from Google Play.
Move beyond theory and strengthen your Android development skills with Yunoktech's Android course. Learn core concepts, practical implementation, modern Android development techniques, and the reasoning behind building maintainable applications.
Explore the Android course and take your next step as an Android developer.