Documentation Index

Fetch the complete documentation index at: https://docs.mapp.com/llms.txt

Use this file to discover all available pages before exploring further.

Expo Integration Guide

Prev Next

The Mapp Engage React Native plugin supports Expo through a config plugin. Expo apps get the plugin's native setup — permissions, services, capabilities — applied automatically on every prebuild, without manual native code changes.

Warning

Expo Go does not support this plugin, or any SDK with native code. You need a development build (expo-dev-client) or EAS Build. This is the most common source of confusion when setting up Expo, so it is worth confirming before anything else.


Why a config plugin

Expo regenerates the native android and ios folders on every clean prebuild, which wipes any manual native setup. The config plugin reapplies the Mapp Engage native setup automatically each time you prebuild, so your configuration survives rebuilds — both local and via EAS Build.


Install

npx expo install react-native-mapp-plugin expo-dev-client

Configure app.json

Add the plugin to the plugins array with the options for your project:

{
  "expo": {
    "name": "Mapp app",
    "slug": "mapp-app",
    "newArchEnabled": true,
    "ios": {
      "bundleIdentifier": "com.example.mappapp"
    },
    "android": {
      "package": "com.example.mappapp",
      "googleServicesFile": "./google-services.json"
    },
    "plugins": [
      [
        "react-native-mapp-plugin",
        {
          "android": {
            "enableGeofencing": false,
            "pushHandling": "mapp"
          },
          "ios": {
            "appId": "MAPP_APP_ID",
            "dmcSystemId": 123,
            "sdkKey": "MAPP_SDK_KEY",
            "isEu": true,
            "inAppServerUrl": "MAPP_INAPP_SERVER_URL",
            "openLandingPageInsideApp": false,
            "customFields": ["customString", "customNumber", "customDate"],
            "mediaTimeout": 5,
            "enableGeofencing": false
          }
        }
      ]
    ]
  }
}

Android options

Option

Description

enableGeofencing

Adds fine and background location permissions when true.

pushHandling

"mapp" (default) or "custom". See Android push ownership below.

iOS options

Option

Description

appId

Mapp Engage application ID.

dmcSystemId

Mapp DMC system ID.

sdkKey

Mapp SDK key.

isEu

Whether the application uses Mapp's EU environment.

inAppServerUrl

In-app message server URL.

openLandingPageInsideApp

Opens push landing pages inside the app instead of the system browser.

customFields

Custom attribute keys the native SDK should expose, by type.

mediaTimeout

Rich Push media download timeout, in seconds.

enableGeofencing

Adds location usage descriptions and capabilities when true.

The Android package must match the Firebase Android application in google-services.json. For iOS, configure an APNs-enabled App ID, a matching bundle identifier, and Apple/EAS signing credentials.

Note

Values in app.json and native resources are public application configuration. Do not put service-account keys or signing secrets there.

The Firebase file is your own configuration. Point Expo's built-in expo.android.googleServicesFile field at it — this plugin does not copy, generate, or modify google-services.json.


Build and run

npx expo prebuild --clean
npx expo run:android
npx expo run:ios

# Cloud builds, after configuring EAS
eas build --profile development --platform all
eas build --profile preview --platform all
eas build --profile production --platform all

Changing plugin options or native dependencies requires a new binary. JavaScript-only changes can use EAS Update.

Initialization

Register event listeners at application startup, then initialize Mapp. Since 2.0.0, engage() returns a promise — await it before calling APIs that depend on the native Mapp singleton. On iOS, the generated AppoxeeConfig.plist is the credential source of truth; the engage arguments remain relevant to Android.

import { Mapp, MappEventEmitter } from 'react-native-mapp-plugin';

const events = new MappEventEmitter();
const subscription = events.addListener('com.mapp.deep_link_received', event => {
  // Route the deep link.
});

await Mapp.engage('ANDROID_SDK_KEY', 'FCM_PROJECT_ID', 'EMC', 'APP_ID', 'TENANT_ID');

Android push ownership

pushHandling: "mapp" is the default. It requires expo.android.googleServicesFile and keeps com.reactlibrary.MessageService as the sole Mapp FCM callback owner. The config plugin removes the Mapp SDK v7 service from the merged app manifest.

Use pushHandling: "custom" when another integration — such as your own FirebaseMessagingService — owns callbacks. The plugin then removes both its own service and the Mapp SDK service, so your service owns callbacks. From native Android code, forward through MappPushHelper:

@Override public void onMessageReceived(RemoteMessage message) {
  if (!MappPushHelper.handleMessage(getApplication(), message)) {
    // Handle non-Mapp messages here.
  }
}

@Override public void onNewToken(String token) {
  MappPushHelper.handleNewToken(getApplication(), token);
}

See the MappPushHelper reference for the full method list.

Note

Mapp.setRemoteMessage(...) remains available when JavaScript is guaranteed to be alive, but the native helper is required for reliable background and terminated delivery. If you also use expo-notifications, use custom ownership with explicit native forwarding — a successful manifest merge alone does not forward payloads.


Geofencing

Set enableGeofencing on each platform that needs it. Android then adds fine and background location permissions, and Mapp.requestGeofenceLocationPermission() requests foreground permission before background permission. On iOS, also supply non-empty locationWhenInUsePermission and locationAlwaysPermission messages.

Note

Only request location access when your user-facing feature and store policy justify it.


iOS Rich Push

The config plugin creates a MappNotificationService Notification Service Extension with the bundle identifier <expo.ios.bundleIdentifier>.mappnotificationservice. The extension reads the public Mapp ios_apx_media payload key, downloads the media, and attaches it to the notification. It requires no additional CocoaPod or React Native code.

Warning

The extension must use the same iOS deployment target as your main app, or it loses connection to it. It is set to iOS 15+ by default. If you raise your app's deployment target, verify the extension target matches.

Note

The extension shares an App Group with the main app to connect the two for Rich Push. This is required — a project without a shared App Group cannot deliver Rich Push media.

The extension is also declared in Expo's experimental EAS app-extension metadata, so EAS can prepare its signing credentials. Regenerate the iOS project after changing the application bundle identifier.


Tested compatibility

Component

Tested baseline

Expo SDK

57

React Native

0.86 (Expo SDK 57)

New Architecture

Enabled

Android min / compile / target SDK

24 / 36 / 36

Android Gradle Plugin / Kotlin / JDK

8.12 / 2.1.20 / 21

iOS deployment target

16.4 (library minimum: 15.1)

Mapp Android SDK

7.1.2

Mapp iOS SDKs

Vendored xcframeworks in this package

Mapp Engage Android 7.1.2 currently publishes Android dependencies newer than the Expo SDK 57 toolchain can consume. This release exports bounded compatibility constraints for AndroidX Core, WorkManager, Lifecycle, Play Services Location, and Kotlin stdlib — see Breaking Changes in 2.0.0 for the exact versions.


React Native CLI

Not using Expo? Install the plugin directly; autolinking discovers the Android package and CocoaPod automatically.

npm install react-native-mapp-plugin
cd ios && pod install

Do not run react-native link, edit settings.gradle, or add the pod manually. See Get Started for the full setup.