> ## Documentation Index
> Fetch the complete documentation index at: https://docs.userpilot.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Expo

> Userpilot React Native Module enables you to capture user insights and deliver personalized in-app experiences in real time.

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](./mobile-react-native) 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](https://www.npmjs.com/package/@userpilot/expo-config).

**Prerequisites**

1. Ensure the [Userpilot React Native Module](https://www.npmjs.com/package/@userpilot/react-native) is installed in your app and the SDK is initialized:

```javascript theme={null}
import * as Userpilot from '@userpilot/react-native'

await Userpilot.setup('<APP_TOKEN>', { logging: true });
```

2. It is recommended to have [configured your Android and iOS push settings in Userpilot Settings page](https://run.userpilot.io/settings/mobile).
3. Refer to [Android Guide](./android-push-notification-setup-guide) and [iOS Guide](./ios-push-notification-setup-guide) to get needed files and settings.
4. 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](https://docs.expo.dev/versions/latest/config/app/#googleservicesfile-1)) property:

```json theme={null}
{
  "expo": {
    ...
    "android": {
      "googleServicesFile": "./google-services.json",
    }
  }
}
```

Note that Userpilot iOS push notifications do not use Firebase.

## Usage

1. Install the Userpilot expo config plugin

```bash theme={null}
npm install @userpilot/expo-config
```

1. Add `@userpilot/expo-config` to the plugin list in your `app.json` file:

```json theme={null}
{
  "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.

3. Test locally with a new development or EAS build:

```bash theme={null}
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](./mobile-react-native).

```javascript [expandable] theme={null}
 /** 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

```javascript theme={null}
npx expo install expo-notifications
```

Add notifications file to handle notifications on Android

```javascript theme={null}
// notifications.ts
// notifications.ts
import { useEffect, useRef } from 'react';
import { Platform } from 'react-native';
import * as Notifications from 'expo-notifications';
import * as Userpilot from '@userpilot/react-native';

/**
 * Notification handlers for Android platform.
 * 
 * Thanks for Swizzling in iOS, Userpilot's iOS SDK handles notifications automatically.
 * this hook sets up 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 deep link 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.
