Reading the report-screen counters off a device

Why these are not in an analytics tool

The app ships no analytics SDK. pubspec.yaml carries firebase_core, firebase_crashlytics and firebase_messaging — and nothing else from Firebase. Crashlytics can record breadcrumbs (log) and custom keys (setCustomKey), but both only ever leave the device attached to a crash report, so they would measure crashing sessions and nothing else. That is the opposite of the population we care about here.

Adding firebase_analytics was out of scope for this change, so the counters live in SharedPreferences and are read by hand. They are defined in lib/metrics/report_screen_metrics.dart.

The counters

Key Meaning
metrics.app.sessions App launches. The denominator.
metrics.report.reached Report screens mounted. reached / sessions is rounds-per-session.
metrics.report.exit.repeat Left via the primary “another verb” action.
metrics.report.exit.home Left via the quieter “home” action.
metrics.report.exit.back Left without using either button — system back, the iOS back-swipe, or the route being torn down.
metrics.report.exit.settings Opened Settings. Not terminal and not exclusive with the three above: Settings is a push the user returns from, so this counter can exceed reached and does not participate in the exit split.
metrics.report.interstitial.requested Preloads started. Only ever incremented when canServeAds is true.
metrics.report.interstitial.loaded Preloads that landed.
metrics.report.interstitial.failed Preloads that did not land. requested - loaded - failed = still in flight when the user left.
metrics.report.interstitial.shown Ads actually presented.
metrics.report.interstitial.wasted Preloaded, never shown — the user left by a path that shows no ad. Not a bug; but if this dominates loaded, the preload is mistimed.

exit.repeat + exit.home + exit.back should be close to reached. A persistent shortfall means a route out that nobody has instrumented.

Android

adb shell run-as be.teamwabisabi.verbomatique_secondaire \
  cat /data/data/be.teamwabisabi.verbomatique_secondaire/shared_prefs/FlutterSharedPreferences.xml \
  | grep metrics

run-as needs a debuggable build. For a release build on a device you own, pull the whole backup instead:

adb backup -f /tmp/vb.ab -noapk be.teamwabisabi.verbomatique_secondaire

Keys are stored with a flutter. prefix — flutter.metrics.report.reached.

iOS Simulator

Note the iOS bundle id is not the Android one: it is be.teamwabisabi.verbomatiquesecondaire — no underscore, all lowercase — against Android’s be.teamwabisabi.verbomatique_secondaire.

CONTAINER=$(xcrun simctl get_app_container booted be.teamwabisabi.verbomatiquesecondaire data)
plutil -p "$CONTAINER/Library/Preferences/be.teamwabisabi.verbomatiquesecondaire.plist" \
  | grep metrics

Either platform, no file access

Debug and profile builds print every counter at launch (ReportScreenMetrics.dump()):

adb logcat | grep ReportScreenMetrics                       # Android
xcrun simctl spawn booted log stream | grep ReportScreenMetrics   # iOS

dump() is a no-op in release builds.

What to do with the numbers

The question this was built to answer is how people leave the report screen. If exit.back dominates, the two buttons are not the lever — those users see no ad and reach no label at all, and a back-press handler is the change worth making. Decide that from the counters, not from the shape of the screen.