Repository navigation
Analytics and 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.
Firebase Console for project helloworld-92567418:
- All events (sortable by count): https://console.firebase.google.com/project/helloworld-92567418/analytics/app/android:com.hora.varisankya/events
- Live event stream (DebugView): https://console.firebase.google.com/project/helloworld-92567418/analytics/app/android:com.hora.varisankya/debugview
- Dashboard overview: https://console.firebase.google.com/project/helloworld-92567418/analytics
⚠ 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.
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).
| 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) |
| 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 |
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 |
| 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 |
| 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 |
— |
| Event | Params |
|---|---|
auth_sign_in |
provider: String — google
|
auth_sign_out |
— |
| 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.).
- 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.
- Wait ~7 days after a beta release that includes user-facing changes.
- Open the Events page → date filter to "Last 28 days" → sort by Event count ascending.
- Anything at or near zero for active users is a candidate for removal in the next release.
- 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.
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 acrossnotification_worker_run) ≈ count ofnotification_postedevents (mismatch means something is silently failing insidesendNotification) -
Worker health =
notification_worker_runcount over time. Should be ≈ one per active user per day. If lower, WorkManager is being throttled (battery optimisation, doze) or the schedule was lost.
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.varisankyaThen open the app and tap around — events appear in DebugView within seconds. The console URL is:
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.
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.
- Firebase Setup — how the GA4 link was established.
- Architecture — where the events fire in the app flow.
Source: aarshps/varisankya-android · This wiki is human-facing; the repo itself targets AI coding agents (AGENTS.md).