This app tests the Expo config plugin integration for the mParticle React Native SDK.
-
First, build and pack the main library:
cd .. yarn install yarn dev:pack -
Install dependencies in the test app:
cd ExpoTestApp npm install -
Update the API keys in
app.json:{ "expo": { "plugins": [ [ "react-native-mparticle", { "iosApiKey": "YOUR_IOS_API_KEY", "iosApiSecret": "YOUR_IOS_API_SECRET", "androidApiKey": "YOUR_ANDROID_API_KEY", "androidApiSecret": "YOUR_ANDROID_API_SECRET", "logLevel": "verbose", "environment": "development", "iosKits": ["mParticle-Rokt"], "androidKits": ["android-rokt-kit"] } ] ] } }
npm run prebuild
npm run iosnpm run prebuild
npm run androidThe app provides buttons to test various mParticle SDK functionality:
- Log Event: Logs a custom event with the specified name
- Log Screen: Logs a screen view event
- Log Commerce: Logs a commerce event (add to cart)
- Identify: Identifies a test user
- Get User: Gets the current user
- Set Attribute: Sets a user attribute
- Check Opt-Out: Checks the current opt-out status
The app also includes Rokt placement testing via the mParticle Rokt kit:
- Embedded: Loads an embedded Rokt placement that renders in-line within the app content. The placement appears in the designated placeholder area below the buttons.
- Overlay: Loads a full-screen overlay Rokt placement that appears on top of the app content.
- Bottom Sheet: Loads a bottom sheet Rokt placement that slides up from the bottom of the screen.
- Shoppable Ads: Calls
MParticle.Rokt.selectShoppableAdswith a staging placement identifier and checkout-style attributes (see implementation guide below).
The Rokt section also demonstrates:
- Platform-specific attributes (iOS vs Android configurations)
- Rokt event listeners for callbacks and placement events
- Using
RoktLayoutViewas an embedded placeholder component
This mirrors the recent SDK work (Shoppable Ads API on iOS and the Expo test app wiring) and how to pair it with native payment registration.
Use MParticle.Rokt.selectShoppableAds(identifier, attributes, roktConfig?) when you need the Shoppable Ads experience instead of selectPlacements.
- identifier: Rokt page / placement identifier configured for your account (the Expo test app uses a staging example such as
StgRoktShoppableAds; replace with your production identifier). - attributes: String key/value pairs passed to Rokt (shipping, billing, payment hints, sandbox flags, etc.). The demo in
App.tsxincludes fields likecountry,shippingstate,paymenttype,stripeApplePayAvailable,applePayCapabilities, andsandbox—adjust to match your integration and Rokt’s attribute contract. - roktConfig: Optional; the demo uses
MParticle.Rokt.createRoktConfig('system')for color mode. Add a cache config if you use caching elsewhere.
Example (same pattern as ExpoTestApp/App.tsx):
const config = MParticle.Rokt.createRoktConfig('system');
MParticle.Rokt.selectShoppableAds('YOUR_PLACEMENT_ID', attributes, config)
.then(() => {
/* success */
})
.catch(error => {
/* handle */
});Listen for RoktCallback and RoktEvents on RoktEventManager to observe load/unload and Shoppable Ads–related events emitted by the native bridge.
Android: selectShoppableAds is not implemented on Android yet; the native module logs a warning and does not run the Shoppable Ads flow. Plan for iOS-only behavior until Android support ships.
Shoppable Ads flows that use Apple Pay / Stripe integration expect a payment extension to be registered on mParticle’s Rokt interface after the SDK starts.
In ios/MParticleExpoTest/AppDelegate.swift, the test app:
- Imports the Stripe payment extension module provided with the Rokt / kit stack:
import RoktStripePaymentExtension. - After
MParticle.sharedInstance().start(with: mParticleOptions), constructsRoktStripePaymentExtension(applePayMerchantId: "...")with your Apple Pay merchant ID (replacemerchant.dummywith your realmerchant.*identifier from Apple Developer). - Registers it:
MParticle.sharedInstance().rokt.register(paymentExtension).
import RoktStripePaymentExtension
// After MParticle.sharedInstance().start(with: mParticleOptions):
if let paymentExtension = RoktStripePaymentExtension(applePayMerchantId: "merchant.your.id") {
MParticle.sharedInstance().rokt.register(paymentExtension)
}Important:
- The Expo config plugin does not generate the payment extension block today. After
expo prebuild, add or merge this code intoAppDelegate.swift(inside the same app launch path as mParticle init). If you regenerate native projects with--clean, re-apply this snippet. - Ensure the mParticle Rokt kit (and transitive Rokt dependencies) are installed so
RoktStripePaymentExtensionresolves—same as configuringiosKits:["mParticle-Rokt"]inapp.json.
All activity is logged in the Activity Log section at the bottom of the screen.
After running npm run prebuild, you can verify the plugin worked correctly:
Check ios/MParticleExpoTest/AppDelegate.swift for:
-
Import statement:
import mParticle_Apple_SDK -
MParticleOptions initialization in
didFinishLaunchingWithOptions:let mParticleOptions = MParticleOptions(key: "YOUR_IOS_API_KEY", secret: "YOUR_IOS_API_SECRET") mParticleOptions.logLevel = .verbose mParticleOptions.environment = .development let identifyRequest = MPIdentityApiRequest.withEmptyUser() mParticleOptions.identifyRequest = identifyRequest MParticle.sharedInstance().start(with: mParticleOptions)
For Shoppable Ads with Apple Pay / Stripe, you may also need to register RoktStripePaymentExtension after start—see Implementation guide: Shoppable Ads (selectShoppableAds) and iOS payment extensions above.
For older Expo SDK versions, check ios/MParticleExpoTest/AppDelegate.mm for:
-
Import statement:
#import "mParticle.h"
-
MParticleOptions initialization:
MParticleOptions *mParticleOptions = [MParticleOptions optionsWithKey:@"YOUR_IOS_API_KEY" secret:@"YOUR_IOS_API_SECRET"]; mParticleOptions.logLevel = MPILogLevelVerbose; mParticleOptions.environment = MPEnvironmentDevelopment; MPIdentityApiRequest *identifyRequest = [MPIdentityApiRequest requestWithEmptyUser]; mParticleOptions.identifyRequest = identifyRequest; [[MParticle sharedInstance] startWithOptions:mParticleOptions];
Check ios/Podfile for:
-
pre_install hook for mParticle dynamic framework linking:
pre_install do |installer| installer.pod_targets.each do |pod| if pod.name == 'mParticle-Apple-SDK' || pod.name == 'mParticle-Rokt' || pod.name == 'Rokt-Widget' def pod.build_type; Pod::BuildType.new(:linkage => :dynamic, :packaging => :framework) end end end end
-
Kit pods (if specified):
pod 'mParticle-Rokt'
Check android/app/src/main/java/.../MainApplication.kt for:
-
Import statements:
import com.mparticle.MParticle import com.mparticle.MParticleOptions import com.mparticle.identity.IdentityApiRequest
-
MParticleOptions initialization in
onCreate():val mParticleOptions = MParticleOptions.builder(this) .credentials("YOUR_ANDROID_API_KEY", "YOUR_ANDROID_API_SECRET") .logLevel(MParticle.LogLevel.VERBOSE) .environment(MParticle.Environment.Development) .identify(IdentityApiRequest.withEmptyUser().build()) .build() MParticle.start(mParticleOptions)
For older Expo SDK versions, check android/app/src/main/java/.../MainApplication.java for:
-
Import statements:
import com.mparticle.MParticle; import com.mparticle.MParticleOptions; import com.mparticle.identity.IdentityApiRequest;
-
MParticleOptions initialization:
MParticleOptions.Builder optionsBuilder = MParticleOptions.builder(this) .credentials("YOUR_ANDROID_API_KEY", "YOUR_ANDROID_API_SECRET") .logLevel(MParticle.LogLevel.VERBOSE) .environment(MParticle.Environment.Development) .identify(IdentityApiRequest.withEmptyUser().build()); MParticle.start(optionsBuilder.build());
Check android/app/build.gradle for kit dependencies (if specified):
dependencies {
// mParticle kits
implementation "com.mparticle:android-rokt-kit:+"
}| Option | Type | Description |
|---|---|---|
iosApiKey |
string | mParticle iOS API key |
iosApiSecret |
string | mParticle iOS API secret |
androidApiKey |
string | mParticle Android API key |
androidApiSecret |
string | mParticle Android API secret |
logLevel |
string | Log level: none, error, warning, debug, verbose |
environment |
string | Environment: development, production, autoDetect |
useEmptyIdentifyRequest |
boolean | Initialize with empty identify request (default: true) |
dataPlanId |
string | Data plan ID for validation |
dataPlanVersion |
number | Data plan version |
iosKits |
string[] | iOS kit pod names (e.g., ["mParticle-Rokt"]) |
androidKits |
string[] | Android kit dependencies (e.g., ["android-rokt-kit"]) |