Respectlytics Respect lytics
Menu
React Native Notification permission granted Privacy-first

How to track notification permission grants in React Native without personal data

Notification permission outcomes — beyond the simple opt-in moment — include OS-level permission revocations, deferred prompts, and provisional grants. Respectlytics helps developers avoid collecting personal data in the first place: in React Native, each permission outcome is its own named event, fired at the moment the system delivers the result. Below: how to wire the call to platform-specific permission callbacks, how to distinguish the states, and what to leave to your push-delivery backend.

Wire each callback path to its own event_name: granted, denied, provisional, deferred. The platform permission API delivers the result asynchronously — fire on the result, not on the request.

Install the React Native SDK

bash Respectlytics
npm install @respectlytics/react-native
# or
yarn add @respectlytics/react-native

JavaScript-only — no native modules, no auto-linking, no New Architecture migration concerns. Bundle size: ~14KB minified+gzipped. Works in any Expo project (managed or bare) without expo prebuild.

Initialize Respectlytics in React Native

js Respectlytics
// App.tsx (or App.js)
import { useEffect } from 'react';
import Respectlytics from '@respectlytics/react-native';

export default function App() {
  useEffect(() => {
    Respectlytics.configure({ appKey: '<YOUR_APP_KEY>' });
  }, []);
  return <YourApp />;
}

Initialize once in your top-level component. No native config; no Info.plist or AndroidManifest changes. The SDK is Hermes- and JSC-compatible.

Track the event in React Native

js Respectlytics
import Respectlytics from '@respectlytics/react-native';
import messaging from '@react-native-firebase/messaging';

export async function reportPermissionState() {
  const status = await messaging().hasPermission();
  if (status === messaging.AuthorizationStatus.AUTHORIZED) {
    Respectlytics.track('push_optin');
  } else if (status === messaging.AuthorizationStatus.PROVISIONAL) {
    Respectlytics.track('push_provisional_optin');
  } else if (status === messaging.AuthorizationStatus.DENIED) {
    Respectlytics.track('push_decline');
  }
  // NOT_DETERMINED → don't fire — user hasn't been asked.
}

Call this on each app foreground via AppState change listener so settings-screen flips are caught.

Privacy & implementation notes

Notification permission state is asymmetric: granting and revoking go through different OS pathways. Granting fires through your prompt callback; revoking happens silently in Settings, with no event delivered to your app. Detect revocation lazily on next foreground if you need it.

If you prompt at multiple points in the funnel (onboarding, post-first-session, after key feature), use distinct event names per timing — push_prompt_at_onboarding, push_prompt_post_session. Conversion-rate-by-timing falls out of session-grouped event counts.

The React Native SDK is JavaScript-only — no Objective-C/Swift bridging on iOS, no Java/Kotlin bridging on Android. Side effects: no react-native link, no auto-linking, no New Architecture migration concerns, no platform-channel exception surfaces. Trade-off: no access to platform-only metadata (which we don't want to collect anyway).

Works in Expo managed workflow without expo prebuild. No config plugin is required. EAS Build users: nothing to configure. This is the smoothest integration path on RN — most analytics SDKs require ejecting from managed.

How this compares to other analytics SDKs

Notification permission eventFirebase AnalyticsMixpanelRespectlytics
Per-user permission stateYes (user property)Yes (profile)Out of scope
Push token / FCM ID storedYesYesNever
Permission outcome states distinguishableManual (params)Manual (params)Distinct event_name per outcome
Time-to-grant after first promptPer-userPer-userSession-scoped

Frequently asked questions

Should we track when the user revokes permission later?

Hard to detect reliably from the app. The OS doesn't deliver an explicit revocation event — you only learn at the next foreground when getNotificationSettings() returns denied. If you do detect it, fire push_revoked_detected (with no metadata) and use it for rate analysis only.

What's the right event for re-prompting after a deferred decision?

If you prompt twice, fire distinct events for each prompt: push_prompt_v1, push_prompt_v2. Apple and Google both have anti-spam policies — a second prompt is allowed only after meaningful product context, and you should instrument that decision point.

How does this differ from `push-opt-in`?

push-opt-in is the narrow event that fires on grant. notification-permission is the broader category that includes all permission outcomes — granted, denied, provisional, deferred, revoked. Use both, with non-overlapping event names per outcome.

What about silent / background-only notification capability?

On iOS, notification permission is independent from background-fetch capability. On Android 13+, POST_NOTIFICATIONS is required for visible notifications regardless of background fetch. If you care about background-only delivery, fire a separate push_background_only event when relevant.

Related guides

Track what matters. Collect nothing you don't.

Five-field event schema, RAM-only event queue, no IDFA, no AAID, no persistent user IDs. Helps developers avoid collecting personal data in the first place.