| name | mobile-analytics |
|---|---|
| description | Add crash reporting and event tracking to a React Native/Expo or Flutter app. Covers Sentry, Firebase Crashlytics, PostHog, source map upload, user identification, session recording, and GDPR compliance. Use when the user wants visibility into crashes, user behavior, or app performance in production. |
| standards-version | 1.7.0 |
Use this skill when the user:
- Wants crash reporting or error tracking in production
- Needs event analytics or user behavior tracking
- Asks about Sentry, Firebase Crashlytics, PostHog, or Mixpanel
- Wants to understand how users interact with their app
- Mentions "analytics", "crash reporting", "crashlytics", "sentry", "tracking", "events", or "session recording"
- Analytics type: crash reporting only, event tracking only, or both
- Provider: Sentry (recommended for crash + performance), Firebase Crashlytics, PostHog, or Mixpanel
- Framework: Expo (React Native) or Flutter
-
Choose a provider. Each has different strengths:
Provider Best for Free tier Source maps Session recording Sentry Crashes + performance monitoring 5K errors/month Yes Yes (beta) Firebase Crashlytics Crash-only, Google ecosystem Unlimited Yes (via CLI) No PostHog Product analytics + feature flags 1M events/month No Yes Mixpanel Event funnels and retention 20M events/month No No You can combine providers. A common pattern is Sentry for crashes + PostHog for product analytics.
-
Set up Sentry (recommended). For Expo:
npx expo install @sentry/react-native
Add the config plugin in
app.json:{ "expo": { "plugins": [ [ "@sentry/react-native/expo", { "organization": "your-org", "project": "your-project" } ] ] } } -
Initialize Sentry. In
app/_layout.tsxor your entry point:import * as Sentry from "@sentry/react-native"; Sentry.init({ dsn: process.env.EXPO_PUBLIC_SENTRY_DSN!, environment: __DEV__ ? "development" : "production", tracesSampleRate: __DEV__ ? 1.0 : 0.2, enabled: !__DEV__, });
Wrap your root component:
export default Sentry.wrap(function RootLayout() { return <Stack />; });
-
Upload source maps for readable stack traces. With EAS Build, add a post-publish hook in
app.json:{ "expo": { "hooks": { "postPublish": [ { "file": "@sentry/react-native/expo", "config": { "organization": "your-org", "project": "your-project" } } ] } } }Set the auth token in your EAS secrets:
eas secret:create --name SENTRY_AUTH_TOKEN --value "your-token" --scope project -
Track custom events. Beyond automatic crash reporting:
import * as Sentry from "@sentry/react-native"; Sentry.addBreadcrumb({ category: "navigation", message: "User opened profile screen", level: "info", }); Sentry.captureMessage("User completed onboarding"); Sentry.captureException(new Error("Payment failed"), { tags: { payment_provider: "stripe" }, extra: { amount: 999, currency: "usd" }, });
-
Set up PostHog for product analytics (optional). Install:
npx expo install posthog-react-native
Initialize in your app:
import { PostHogProvider } from "posthog-react-native"; export default function RootLayout() { return ( <PostHogProvider apiKey={process.env.EXPO_PUBLIC_POSTHOG_KEY!} options={{ host: "https://us.i.posthog.com", enableSessionReplay: true, }} > <Stack /> </PostHogProvider> ); }
Track events:
import { usePostHog } from "posthog-react-native"; function CheckoutScreen() { const posthog = usePostHog(); const handlePurchase = () => { posthog.capture("purchase_completed", { product_id: "premium_yearly", price: 39.99, }); }; }
-
Identify users. Link analytics to authenticated users:
// Sentry Sentry.setUser({ id: user.id, email: user.email }); // PostHog posthog.identify(user.id, { email: user.email, plan: "premium" }); // On sign-out, clear the user Sentry.setUser(null); posthog.reset();
-
GDPR and privacy compliance. Respect user privacy:
import * as Sentry from "@sentry/react-native"; function disableTracking() { Sentry.init({ enabled: false }); posthog.optOut(); } function enableTracking() { Sentry.init({ enabled: true, dsn: process.env.EXPO_PUBLIC_SENTRY_DSN! }); posthog.optIn(); }
Add a privacy settings screen where users can opt out of analytics. Required for EU users under GDPR and recommended for App Store review.
- Sentry: React Native
- Sentry: Expo integration
- Firebase Crashlytics: React Native
- PostHog: React Native
- Mixpanel: React Native
User: "I want crash reporting in production and event tracking for my checkout flow."
Agent:
- Recommends Sentry for crashes + PostHog for event analytics
- Installs @sentry/react-native and posthog-react-native with
mobile_installDependency - Configures Sentry plugin in app.json with org and project
- Initializes Sentry in
_layout.tsxwith production-only mode and 20% trace sampling - Sets up source map uploads via EAS Build hooks
- Wraps app in PostHogProvider
- Adds purchase event tracking in checkout flow:
posthog.capture("purchase_completed", {...}) - Implements user identification on login and reset on logout
- Reminds user to set
EXPO_PUBLIC_SENTRY_DSNandEXPO_PUBLIC_POSTHOG_KEYin.env
| Step | MCP Tool | Description |
|---|---|---|
| Install SDKs | mobile_installDependency |
Install @sentry/react-native, posthog-react-native |
| Check build | mobile_checkBuildHealth |
Verify project builds with native Sentry module |
| Validate config | mobile_checkBuildHealth |
Ensure app.json plugins are correctly configured |
| Build for testing | mobile_buildForStore |
Create a production build to verify source map upload |
- Leaving analytics enabled in development - Set
enabled: !__DEV__to avoid polluting production data with dev crashes and test events. - Missing source maps - Without source maps, crash stack traces show minified code. Configure the Sentry post-publish hook and set the auth token in EAS secrets.
- Over-sampling performance traces - A
tracesSampleRateof 1.0 in production generates too much data and slows the app. Use 0.1-0.2 for production. - Not identifying users - Anonymous crash reports are hard to debug. Call
Sentry.setUser()after authentication to associate crashes with user accounts. - Tracking PII in events - Do not log emails, passwords, or payment details in event properties. Sentry and PostHog both have data scrubbing options, but prevention is better.
- Ignoring session recording consent - Session recording captures screen content. Require explicit user consent before enabling it, especially for EU users.
- Firebase Crashlytics requires a dev build - Like most native modules, Crashlytics does not work in Expo Go.
- Mobile Monetization - track purchase and subscription events
- Mobile OTA Updates - track update adoption and crash rates per release
- Mobile Auth Setup - identify users for analytics after authentication