Skip to content
This repository was archived by the owner on Jun 3, 2026. It is now read-only.

Analytics and Audit

Aarsh edited this page May 26, 2026 · 2 revisions

Analytics & Audit

The app logs Firebase Analytics events for every distinct user-visible flow so we can audit which features get traffic and which to retire. Snake-cased event names, scalar params only — no PII, no IDs, no free-form text.


Where to view

Firebase Console for project helloworld-92567418:

⚠ 24h latency in the Events table. New events show up roughly a day after they're logged. For real-time verification, use DebugView — see "Smoke-testing" below.


Event taxonomy

All event-firing methods live in app/src/main/java/com/hora/varisankya/util/Analytics.kt. Init happens once in VarisankyaApplication.onCreate via Analytics.init(this).

Subscription flows

Event Params Where it fires
subscription_add_open — MainActivity.showAddSubscriptionSheet(null)
subscription_edit_open — MainActivity.showAddSubscriptionSheet(existing)
subscription_save is_new: Boolean, recurrence: String AddSubscriptionBottomSheet save button
subscription_delete — AddSubscriptionBottomSheet delete button
subscription_status_change active: Boolean SubscriptionActionHelper.confirmMarkInactive (currently dead path)

Payment flows

Event Params Where it fires
payment_manage_open — PaymentBottomSheet.onCreateView
payment_pay_current — PaymentBottomSheet's Mark as Paid button
payment_add_only — PaymentBottomSheet's Add Payment, Keep Due Date button
payment_edit_date — Inside PaymentBottomSheet after editing a record's date
payment_delete — After deleting a record from PaymentBottomSheet
payment_mark_paid_swipe — SubscriptionActionHelper.confirmMarkAsPaid (swipe-right on home)
payment_history_cleanup count: Int UnifiedHistoryActivity.deleteInvalidRecords

Notification lifecycle

The full chain so you can compute meaningful tap-through rates from the dashboard: notification_posted is the denominator against which every other notification event becomes a ratio.

Event Params Where it fires
notification_worker_scheduled — MainActivity.setupNotifications — every time the scheduling code runs
notification_worker_run success: Boolean, signed_in: Boolean, subscriptions_checked: Int, notifications_posted: Int SubscriptionNotificationWorker.doWork — at the end of every periodic worker run. Answers "did the worker actually fire and did it have anything to post?"
notification_posted days_left: Int (0–10) SubscriptionNotificationWorker.sendNotification — once per notification actually pushed to the system
notification_tap — MainActivity.handleIntent — body of a notification was tapped (open the app). Routed via the EXTRA_FROM_NOTIFICATION intent extra; consumed on first read
notification_dismiss — NotificationActionReceiver.ACTION_NOTIFICATION_DISMISSED — user swiped the notification away without acting
notification_mark_paid_action — NotificationActionReceiver.ACTION_MARK_PAID — the "Mark Paid" action button was tapped
notification_test_sent — SettingsActivity.setupTestNotificationButton — user tapped Send Test Notification in Settings

Screen opens

Event Where it fires
screen_settings_open SettingsActivity.onCreate
screen_search_open SearchActivity.onCreate
screen_all_payments_open UnifiedHistoryActivity.onCreate
screen_about_open SettingsActivity aboutLayout click

Settings

Event Params
setting_theme_change theme: String — light / dark / system
setting_currency_change currency: String — ISO 4217
setting_font_change font: String — google_sans / system
setting_haptics_toggle enabled: Boolean
setting_app_lock_toggle enabled: Boolean
setting_notification_days_change days: Int
setting_notification_time_change —

Auth

Event Params
auth_sign_in provider: String — google
auth_sign_out —

General usage

Event Where it fires
home_refresh_pull MainActivity SwipeRefreshLayout.OnRefreshListener — pull-to-refresh on home

Plus all the Firebase auto-collected events (first_open, session_start, screen_view, app_update, app_remove, os_update, notification_open, etc.).


What we never log

  • Subscription / merchant names — would be PII-adjacent and pollute the dimension space.
  • Amounts / costs / currencies actually paid — financial PII.
  • Document IDs — high cardinality, no analytical value.
  • Notification content text — covered by privacy concerns.
  • User identifiers other than the Firebase Analytics SDK's auto-assigned anonymous app instance ID — set via Firebase Auth integration but never custom-keyed.

Analytics.log() accepts only scalar typed params (String, Int, Long, Double, Float, Boolean). Reviews should reject any new event that tries to smuggle high-cardinality strings through.


The audit recipe (what this was built for)

  1. Wait ~7 days after a beta release that includes user-facing changes.
  2. Open the Events page → date filter to "Last 28 days" → sort by Event count ascending.
  3. Anything at or near zero for active users is a candidate for removal in the next release.
  4. Tag the removal in a PR: the event-firing call sites + the wrapper method in Analytics.kt + the UI surface(s) that triggered them.

Example use of this: after several betas you might find subscription_status_change is never fired (because the swipe-to-pause flow was never wired up in SubscriptionActionHelper), confirming the "Pause subscription" code path is dead and can be deleted along with the confirmMarkInactive method.

Computing notification flow ratios

The notification lifecycle events are designed to be ratioed against notification_posted:

  • Mark-paid tap-through rate = notification_mark_paid_action / notification_posted
  • Body-tap rate = notification_tap / notification_posted
  • Dismiss rate = notification_dismiss / notification_posted
  • Visibility integrity = notifications_posted (param sum across notification_worker_run) ≈ count of notification_posted events (mismatch means something is silently failing inside sendNotification)
  • Worker health = notification_worker_run count over time. Should be ≈ one per active user per day. If lower, WorkManager is being throttled (battery optimisation, doze) or the schedule was lost.

Smoke-testing with DebugView

Events take ~24h to surface in normal reports. For immediate verification, use DebugView on a USB-connected device:

adb shell setprop debug.firebase.analytics.app com.hora.varisankya

Then open the app and tap around — events appear in DebugView within seconds. The console URL is:

https://console.firebase.google.com/project/helloworld-92567418/analytics/app/android:com.hora.varisankya/debugview

Disable when done:

adb shell setprop debug.firebase.analytics.app .none.

You should see things like screen_settings_open, subscription_add_open, auth_sign_in, etc. appearing as you trigger them.


Costs

None. Firebase Analytics is free at any volume:

  • Event collection — unlimited.
  • Default reports — free, 14-month retention.
  • DebugView, Audiences, Funnels, Conversions — free.
  • GA4 account itself — free.

The only optional thing that has any cost is BigQuery export (free streaming, $0.02/GB/month storage — well within GCP free tier for this app's volume). Leave it off until you genuinely need raw-event SQL.


See also

Clone this wiki locally