Install Userpilot on Your Expo-React Native App

Userpilot React Native Module enables you to capture user insights and deliver personalized in-app experiences in real time. With just a one-time setup, you can immediately begin leveraging Userpilot’s analytics and engagement features to understand user behaviors and guide their journeys in-app.

The Userpilot SDK is fully compatible with Expo apps. To get started, refer to the React Native integration guide for detailed instructions on configuring and using the Userpilot React Native SDK within your Expo project.

Gettings started

For push notification support, we provide an expo-config plugin that automatically configures the necessary settings for seamless integration with the Userpilot SDK.

You can fetch the latest version from here.

Prerequisites

  1. Ensure the Userpilot React Native Module is installed in your app and the SDK is initialized:
import * as Userpilot from '@userpilot/react-native'

await Userpilot.setup('<APP_TOKEN>', { logging: true });
  1. It is recommended to have configured your Android and iOS push settings in Userpilot Settings page.
  2. Refer to Android Guide and iOS Guide to get needed files and settings.
  3. Copy your Firebase configuration file into your project and set the path to the file in your app.json file, in the android.googleServicesFile (doc) property:
{
  "expo": {
    ...
    "android": {
      "googleServicesFile": "./google-services.json",
    }
  }
}

Note that Userpilot iOS push notifications do not use Firebase.

Usage

  1. Install the Userpilot expo config plugin
npm install @userpilot/expo-config
  1. Add @userpilot/expo-config to the plugin list in your app.json file:
{
  "expo": {
    ...
    "plugins": [
      [
        "../app.plugin.js",
        {
          "scheme": "userpilot_push_notification"
        }
      ]
    ]
	...
  }
}

The Userpilot Expo plugin injects the necessary configuration to properly handle push notifications.

Make sure to set the scheme key in your plugin configuration.

  1. Test locally with a new development or EAS build:
npx expo prebuild

SDK callbacks

To handle deep link triggers from push notifications, you can listen to SDK events as shown below.

For more information, refer to the Userpilot React Native SDK.

 /** Userpilot SDK callbacks */
  useEffect(() => {
    const eventEmitter = new NativeEventEmitter(
      NativeModules.UserpilotReactNative
    );
    const listeners = [
      eventEmitter.addListener('UserpilotAnalyticsEvent', (event) =>
        console.log('Analytics Event:', event)
      ),
      eventEmitter.addListener('UserpilotExperienceEvent', (event) =>
        console.log('Experience Event:', event)
      ),
      eventEmitter.addListener('UserpilotNavigationEvent', (event) => {
        console.log('Navigation Event', event);
      }),
    ];
    return () => listeners.forEach((listener) => listener.remove());
  }, []);

Android Handling

In order to catch Usrpilot push notification and handle it through Userpilot SDK, add expo notification library

npx expo install expo-notifications

Add notifications file to handle notifications on Android

// notifications.ts
import { useEffect, useRef } from 'react';
import { Platform } from 'react-native';
import * as Notifications from 'expo-notifications';

/**
 * Notification handlers for Android platform.
 * 
 * Thanks for Swizzling in iOS, Userpilot's iOS SDK handles notifications automatically.
 * this hook sets up request notification permission and listeners for notification events from Android devices.
 * It listens for notifications received while the app is in the foreground,
 * and for responses when the user taps on a notification.
 * It also checks if the app was launched from a notification.
 * 
 * Pass the data from the notification to the `handleNotificationData` and `handleNotificationResponse` functions,
 * which call Userpilot SDK API.
 * If its Userpilot's SDK, it will return true, otherwise it will return false.
 * 
 * Listen for Deeplink triggering from NativeEventEmitter
 */
export function useNotificationHandlers() {
  const responseListener = useRef<Notifications.Subscription>();

  useEffect(() => {
    if (Platform.OS !== 'android') return;

    // Request permission on mount
    requestNotificationPermissions();

    // This is for when the user taps on the notification
    responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
      console.log('Notification response:', response);
      const data = response.notification.request.content.data;
      handleNotificationResponse(data);
    });

    // Check if app was launched via notification
    checkInitialNotification();

    return () => {
      if (responseListener.current) {
        Notifications.removeNotificationSubscription(responseListener.current);
      }
    };
  }, []);
}

async function requestNotificationPermissions() {
  const { status } = await Notifications.getPermissionsAsync();
  if (status !== 'granted') {
    const { status: newStatus } = await Notifications.requestPermissionsAsync();
    console.log('Notification permission status:', newStatus);
  } else {
    console.log('Notification permission already granted');
  }
}

async function checkInitialNotification() {
  if (Platform.OS !== 'android') return;

  const response = await Notifications.getLastNotificationResponseAsync();
  if (response) {
    console.log('App opened from notification:', response);
    const data = response.notification.request.content.data;
    handleNotificationResponse(data);
  }
}

function handleNotificationResponse(data: Record<string, any>) {
  console.log('Handling notification response:', data);
  // Pass intent data to Userpilot SDK to handle it, return false incase
  // it's not Userpilot push notification
  Userpilot.didHandleIntent(data);
}

No iOS configuration needed, thanks for Swizzling in iOS, Userpilot's iOS SDK handles notifications automatically.

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.