ADR-0049: Crash and ANR Reporting via Firebase Crashlytics
DateFebruary 28, 2026
CategoryInfrastructure
Tagsci-cdprivacy-security
Context
The app currently has zero crash or ANR reporting. Errors are logged to Log.e() in three
ViewModels and are otherwise silent. Once the app is publicly released, there is no mechanism to
learn about crashes, their frequency, affected devices, or stack traces.
ADR-0005 established a no-network-stack policy to keep the MVP focused and privacy-first.
However, crash reporting is a fundamentally different concern from user-data networking: it
transmits only diagnostic metadata (stack traces, device info, app state) and is an industry
baseline for any shipped application. Operating blind in production is a greater risk to users
(undetected data-corrupting crashes) than the minimal privacy cost of diagnostic telemetry.
The project already declares firebase-bom as a dependency, has a configured
google-services.json, and uses Firebase for Test Lab and App Distribution in CI (ADR-0022).
Adding Crashlytics is an incremental step within an existing Firebase integration, not a new
vendor dependency.
Decision
We will add Firebase Crashlytics as the crash and ANR reporting tool, amending ADR-0005 to
carve out crash reporting as a controlled exception to the no-network policy.
Specifically:
- Add dependencies:
firebase-crashlytics (via existing BOM) and the Crashlytics Gradle
plugin for mapping file uploads.
- Initialize in
LocusFlowApplication: Enable automatic crash collection. No explicit
FirebaseCrashlytics.init() is needed — the content provider auto-initializes.
- Non-fatal recording: Wrap caught exceptions in ViewModels and the data layer with
FirebaseCrashlytics.getInstance().recordException(e) to surface handled errors that
degrade UX without crashing.
- PII protection: Never attach user-generated content (reflection text, inbox items,
display name) to crash reports. Custom keys are limited to: feature flag states, current
screen, database version, model load state.
- Mapping file upload: Configure the Crashlytics Gradle plugin to upload ProGuard/R8
mapping files on release builds (depends on ADR-0036 enabling R8).
- ANR detection: Crashlytics automatically captures ANR traces on Android 11+; no
additional configuration is required.
- Amend ADR-0005: Add a "Controlled Exceptions" section noting that crash/ANR reporting
via Crashlytics is permitted under the no-network policy, with a reference to this ADR.
Rationale
- Observability is non-negotiable: Without crash data, production issues are invisible.
Users rarely report crashes; they just uninstall.
- Firebase is already integrated: BOM, google-services.json, Test Lab, and App Distribution
are already in the project. Crashlytics is a natural extension, not a new vendor.
- Minimal privacy impact: Crashlytics transmits stack traces and device metadata, not user
content. No PII is included when custom key discipline is maintained.
- Industry standard: Every production Android app uses crash reporting. Shipping without it
is an outlier choice with no upside.
Consequences
Positive:
- Visibility into crash rates, ANR rates, and affected devices from day one.
- Non-fatal exception recording surfaces degraded-but-not-crashed states.
- Stack traces with symbolication (via R8 mapping files) enable fast root-cause analysis.
- Crashlytics dashboard provides crash-free session rates, trends, and device breakdowns.
Known downsides:
- Introduces a network call from the app (diagnostic telemetry only).
- Requires amending ADR-0005, which was a clean "no network" stance.
- Crashlytics SDK adds ~200KB to the APK.
- Requires
INTERNET permission (added automatically by the Crashlytics SDK manifest merge).
- Data Safety form must disclose crash/diagnostic data collection (see ADR-0038).
Follow-up work:
- Configure a Crashlytics-forwarding Timber tree after ADR-0040 (structured logging) is
implemented.
- Set up Crashlytics alerts for crash-free rate drops below a threshold (e.g., <99.5%).
- Consider adding a user-facing opt-out toggle for crash reporting in a future release (not
required for launch).
Alternatives Considered
Sentry:
- Pros: Open-source, self-hostable, richer error context.
- Cons: Requires a separate account/project, no existing integration, higher setup cost.
- Rejected: Firebase is already integrated; adding a second vendor adds unnecessary complexity.
On-device crash log export (via existing export feature):
- Pros: No network call, fully offline, aligns with ADR-0005.
- Cons: Users must manually trigger export after a crash — which they almost never do. Crashes
that prevent app launch make export impossible. Provides no aggregate statistics.
- Rejected: Fundamentally inadequate for production observability.
No crash reporting (status quo):
- Rejected: Operating blind in production is unacceptable for a publicly released app.
Notes
- Related: ADR-0005 (no network stack — to be amended), ADR-0022 (CI pipeline), ADR-0036 (R8),
ADR-0038 (Data Safety form).
- The
INTERNET permission added by Crashlytics is limited to diagnostic telemetry. The app
makes no other network calls.
- Crashlytics respects Android's "Usage & diagnostics" system setting; users who opt out at the
OS level will not send crash reports.