How to Add Analytics and Crash Reporting to a Mobile App
Contents
Last updated: August 2026.
Analytics should tell you where users succeed, where they stop, and which product problem deserves attention next. Crash reporting should tell you what failed, who it affected, and whether the issue started in a specific release.
Adding an SDK is only the setup. The useful work is choosing a small event vocabulary, checking that events fire correctly, protecting user privacy, and connecting product behavior with technical failures.
- Track meaningful user outcomes instead of every tap. - Define event names and properties before adding code. - Connect crashes to app versions, devices, and user journeys. - Test analytics and crash reporting in a release-style build. - Collect only the data you can explain and use.
Start with product questions
Write down the decisions you expect analytics to support.
Useful questions include:
- Do new users reach the first meaningful result?
- Which onboarding step loses the most people?
- How many users complete the core action more than once?
- Where do payments fail?
- Which feature brings users back?
- Does a new release improve or damage completion?
- Which crashes block the main journey?
A question should lead to an action. If nobody knows what they would change after seeing a metric, it probably does not belong in the first tracking plan.
For a receipt-scanning app, the main question might be: "Can a new user scan, review, and save one accurate receipt?" That requires a short event sequence, not hundreds of screen views.
Choose one activation event
Activation is the earliest behavior that shows the user received the app's promised value.
| App type | Weak activation signal | Better activation event |
|---|---|---|
| Habit tracker | Account created | First habit completed |
| Receipt scanner | Camera opened | First receipt reviewed and saved |
| Booking app | Service viewed | Booking confirmed |
| Study app | Lesson opened | First study session completed |
| Marketplace | Profile created | First listing published |
| AI planner | Prompt submitted | Generated plan reviewed and saved |
A sign-up may be required, but it rarely proves value by itself.
Name one activation event and build the first funnel around it. Add retention and revenue metrics after the team can explain activation clearly.
If the core outcome is still unclear, use the mobile app idea validation guide before instrumenting every screen.
Create a small event plan
An event records that something happened. Properties add context.
Use lowercase names with one convention across the app. Verb and object names are easy to understand:
onboarding_startedonboarding_completedreceipt_scan_startedreceipt_scan_failedreceipt_savedsubscription_started
Define each event before implementation.
| Event | Fires when | Useful properties | Do not include |
|---|---|---|---|
onboarding_started | First onboarding screen appears | app version, platform | Email or name |
onboarding_step_viewed | A step becomes active | step name, step number | Free-form user text |
onboarding_completed | User reaches the product | selected path | Sensitive answers |
core_action_started | User begins the main task | entry point | Raw document content |
core_action_completed | Result is saved or confirmed | result type, duration bucket | Full AI output |
core_action_failed | Task cannot complete | error code, stage | Tokens or stack trace |
paywall_viewed | Paywall is visible | source, offer ID | Payment details |
purchase_completed | Backend confirms purchase | product ID, currency | Card information |
Google's Firebase Analytics event guide describes events as records of user actions, system events, or errors. Use recommended event names when they fit the product because analytics tools may provide built-in reporting for them.
An event name should describe the completed fact, not the UI control. Track booking_confirmed, not green_button_clicked.
Track a funnel that matches the real journey
A funnel is an ordered sequence of user actions.
For onboarding:
- Onboarding started
- Value screen viewed
- Personalization completed
- Account created
- First core action started
- First core action completed
For a purchase:
- Paywall viewed
- Product selected
- Checkout started
- Purchase completed
- Entitlement granted
Measure the number and percentage reaching each step. Then inspect the largest meaningful drop.
Do not assume the interface before the drop is the cause. A user may leave a sign-up step because the earlier screens did not show enough value. Combine the numbers with session observation, support messages, and short user interviews.
Use properties without collecting personal data by accident
Properties help explain an event. Good properties are controlled values such as platform, app version, plan, source, feature variant, or error code.
Avoid sending:
- Email addresses
- Full names
- Phone numbers
- Passwords or tokens
- Payment details
- Health, financial, or identity information
- Free-form messages
- Images or document contents
- Full API responses
If the analytics provider supports a user ID, use an internal identifier that is not directly meaningful outside your system. Google's Firebase user ID guidance states that user IDs are optional and recommends values that outside organizations cannot trace back to an individual.
Keep analytics identity separate from authentication secrets. The purpose is to connect permitted product activity, not copy the user's account into an analytics system.
Add crash reporting before the first public beta
A crash report should include enough context to reproduce the failure:
- App version and build
- Operating system and device
- Fatal or non-fatal status
- Stack trace
- Screen or route
- Recent safe breadcrumbs
- Release or update identifier
- Relevant feature flag
- An internal user reference when permitted
Expo's Sentry integration guide explains how Expo projects can connect release data with stack traces and debugging context. Firebase Crashlytics is another option for Apple, Android, Flutter, Unity, and related native platforms.
Choose one primary crash tool at first. Two services can duplicate reports, increase SDK work, and create conflicting counts.
Set alerts for new fatal issues, sudden increases, and failures in high-value flows. Do not send a notification for every individual occurrence.
Make stack traces readable
A crash report is far less useful when production code is minified or native addresses are not symbolicated.
For each release:
- Assign a stable version and build number.
- Upload JavaScript source maps when required.
- Upload iOS debug symbols for native crashes.
- Keep Android mapping files when code is obfuscated.
- Associate over-the-air updates with a release identifier.
- Verify the reporting tool recognizes the build.
Firebase's Crashlytics setup guidance includes forcing a test crash to confirm the installation. This is worth doing before inviting testers. A dashboard with no reports may mean the app is stable, or it may mean reporting is not connected.
Expo currently recommends Sentry or BugSnag when native crash reporting is required, according to its error reporting documentation.
Record handled errors too
Not every serious failure crashes the app.
Capture selected non-fatal errors when:
- A payment confirmation fails
- A database write is rejected unexpectedly
- An authentication refresh cannot recover
- An AI response cannot be parsed
- An upload repeatedly fails
- A required native service does not initialize
Use a stable error code and stage. Add safe context, then show the user a clear recovery path.
Do not report ordinary validation as a technical error. An empty required field is expected behavior. A valid form that fails because the request body uses the wrong schema is a product defect.
Connect product events with technical errors
Analytics and crash data become more useful when both use the same release, feature, and journey vocabulary.
| Shared field | Why it helps |
|---|---|
| App version | Finds regressions after a release |
| Build number | Separates store artifacts |
| Platform | Reveals iOS or Android differences |
| Route | Connects failure with the visible screen |
| Journey stage | Shows where the task broke |
| Feature version | Compares old and new behavior |
| Error code | Groups expected failure types |
| User state | Separates new, returning, free, or paid use |
Suppose receipt_scan_started stays stable while receipt_saved drops after version 1.4. Crash reporting shows a rise in image upload failures on Android. The combined evidence points to a specific release, platform, and stage.
Without shared fields, the team sees a conversion drop in one tool and an error increase in another without knowing they are connected.
Validate events before trusting reports
Test the tracking plan on a development device and a release-style build.
Google's Analytics DebugView shows raw development-device events in near real time and is intended for validating instrumentation.
For each event, verify:
- It fires once at the intended moment.
- It does not fire from screen rerenders.
- Required properties exist.
- Property values use the allowed format.
- No private data is present.
- The event works on iOS and Android.
- The event uses the production project only when intended.
- Consent settings affect collection correctly.
- Sign-out clears or updates user identity.
- Offline events behave as the provider documents.
Keep a tracking plan beside the code. When an event changes, update both. Silent naming changes split one metric into two incomplete histories.
Build a useful dashboard
The first dashboard can be small.
Include:
| Section | Metrics |
|---|---|
| Acquisition | Install or first-open source where available |
| Activation | Core funnel completion |
| Engagement | Core actions per active user |
| Retention | Users returning and repeating value |
| Revenue | Trial, purchase, renewal, entitlement |
| Reliability | Crash-free use, fatal issues, non-fatal blockers |
| Release health | Completion and errors by app version |
Avoid a wall of charts. Put the product promise at the top and reliability beside it.
Review the dashboard on a fixed schedule. Daily review makes sense during a launch or risky release. Weekly review is enough for many early products. Record decisions so the same chart does not trigger a different interpretation each meeting.
Prioritize crashes by product impact
Frequency alone can mislead. A rare payment defect may deserve attention before a common error on a secondary settings screen.
Score each issue using:
- Number of affected users
- Severity
- Position in the core journey
- Data or payment risk
- Availability of a workaround
- Whether it is a new regression
- Confidence in the diagnosis
| Issue | Users | Impact | Suggested action |
|---|---|---|---|
| App crashes on launch | Many | Critical | Stop rollout and fix |
| Purchase succeeds without access | Few | Critical | Fix immediately and reconcile accounts |
| Optional animation fails | Many | Low | Schedule after core issues |
| Upload retry message is unclear | Medium | Medium | Improve recovery soon |
| Old device has slow settings screen | Few | Low | Measure before prioritizing |
A crash tool helps locate technical damage. Product events show whether the damage blocks value.
Respect privacy and store disclosures
Document each SDK, data type, purpose, retention period, and sharing relationship.
Apple's App Privacy Details includes product interaction, crash data, and performance data among the categories developers may need to disclose. Apple's user privacy guidance explains how these practices appear on the product page.
Also check Google Play's Data safety requirements for the SDKs and configuration you use. A provider's default settings may collect more than your product needs.
If the app uses data for tracking across companies or advertising, additional consent and platform rules may apply. Apple's App Tracking Transparency documentation covers the system permission required for defined tracking behavior.
If you cannot explain why an event or property is collected, remove it until there is a real use.
Release checklist
Before launch:
- Name the activation event.
- Document the core funnel.
- Implement only the events needed for current decisions.
- Add one crash reporting service.
- Tag app versions, builds, and updates.
- Upload source maps and symbols.
- Force a test crash.
- Validate events in debug tools.
- Test consent, sign-out, and account deletion.
- Review App Store and Google Play disclosures.
- Set useful alerts.
- Assign an owner for weekly review.
Use the TestFlight beta testing guide to prepare an iOS beta and verify the release before inviting users.
Add analytics and crash reporting with Huxly
Huxly can help you add product events, conversion funnels, crash reporting, authentication context, and release-aware error handling to a working mobile app. Build in Expo, Flutter, or SwiftUI, test the instrumentation while you refine the product, then prepare the app for TestFlight or Google Play.
FAQ
Which analytics events should a new app track first?
Start with onboarding started and completed, the first core action started and completed, major failures, paywall viewed, checkout started, and purchase confirmed when relevant. Add events only when they support a decision.
Should I track every button tap?
No. Track outcomes and meaningful journey stages. A button tap matters when it represents a business or user event that cannot be measured more clearly elsewhere.
What is the difference between analytics and crash reporting?
Analytics measures product behavior such as activation, retention, and feature use. Crash reporting captures failures, stack traces, devices, and releases. Using both helps connect technical defects with user impact.
Should crash reports include the user's email?
Usually, use an internal identifier when identification is necessary and permitted. Avoid sending direct personal data unless the support workflow genuinely requires it and your privacy disclosures cover it.
How do I know crash reporting is installed correctly?
Run a documented test crash in a non-production account or build, confirm it appears with the correct release, and verify that the stack trace is readable. Also test a handled error and alert rule.
Conclusion
A small, accurate tracking plan is more useful than a large one nobody trusts. Start with the core journey, one activation event, and the failures that can block it.
Validate every event, make production traces readable, and review privacy before launch. The result should help the team decide what to fix or build next, not merely prove that the app produces data.
