Mobile
React Native module
This page is assembled from
sdks/react-native/README.mdin the repository. See the SDK overview for the choice between native SDKs and wrappers.
Formerly
@dtrackier/react-native. Until 2.0 the deprecatedDTrackier,DTrackierErrorandwithDTrackierexports forward toMetrixed,MetrixedErrorandwithMetrixed; change the dependency and import path to@metrixed/react-native.
@metrixed/react-native is a thin bridge over the native Android and iOS
SDKs. All tracking logic (offline queue, request signing, attribution, SKAdNetwork, consent enforcement) lives in the
native SDKs; this package only validates arguments and forwards them. Method names mirror the native SDKs.
Works with the legacy bridge and (through the interop layer) the new architecture. Not usable in Expo Go: build a
development client (expo prebuild / expo run:*) or a bare app.
Install
npm install @metrixed/react-native
cd ios && pod install # iOS: pulls the Metrixed pod (>= 1.0)
Android resolves com.metrixed:metrixed-android from Maven Central. Until it is published use the local repo built
by make sdk-android-build and point Gradle at it (maven { url "<repo>/sdks/android/metrixed/build/repo" }).
Expo
{ "expo": { "plugins": [["@metrixed/react-native", {
"scheme": "myapp",
"linkHosts": ["go.example.com"],
"userTrackingDescription": "This identifier measures which ads led to installs.",
"skAdNetworkIds": ["cstr6suwn9.skadnetwork"],
"skanReportEndpoint": "https://skan.example.com"
}]] } }
The config plugin adds: Android INTERNET/ACCESS_NETWORK_STATE, a VIEW intent filter for your scheme and verified
App Link filters for every host; iOS NSUserTrackingUsageDescription, SKAdNetworkItems,
NSAdvertisingAttributionReportEndpoint / AdAttributionKitReportEndpoint, CFBundleURLTypes and
applinks: Associated Domains. kidsMode: true removes the AD_ID permission and writes no ATT/SKAN keys. It is
idempotent. Bare apps do the same by hand (see the native READMEs).
Initialise
import { Metrixed } from '@metrixed/react-native';
await Metrixed.initialize({
appToken: 'APP_TOKEN',
environment: 'production', // 'sandbox' is flagged on every payload and excluded from billing
baseUrl: 'https://ingest.example.com',
secret: 'SDK_SECRET', // request signing
});
Call it as early as possible. JavaScript starts after the first Android activity is already visible, so the install is
reported immediately but the very first session starts at the next foreground. To count the first session too,
initialise the native SDK in Application.onCreate instead (and skip initialize here).
Platform-specific options are ignored on the other platform: secretId, consentRequired, collectGaid,
collectAppSetId, collectAndroidId, oaid, preloadKey, referrerTimeoutMs (Android); trackingBaseUrl,
attWaitInterval, readIdfa, readIdfv, linkMe*, skanEnabled, storeKitForwarding (iOS). kidsMode maps to
setKidsMode / coppaCompliant.
Events and ad revenue
Metrixed.trackEvent({ token: 'level_up', callbackParams: { level: '5' } });
Metrixed.trackEvent({ token: 'purchase', revenue: 9.99, currency: 'USD', dedupeId: orderId, partnerParams: { af_content: 'x' } });
Metrixed.trackAdRevenue({ source: 'applovin_max', revenue: 0.012, currency: 'USD', adUnit: 'u1', adType: 'rewarded' });
Metrixed.setCustomerUserId('user-42');
Revenue is a number plus an ISO currency (required together); the native SDK formats it as a 6-decimal string. The
wrapper rejects bad input before it reaches native code. Ad revenue: call trackAdRevenue from your mediation
callback, e.g. AppLovin MAX ad.revenue / ad.networkName / ad.adUnitIdentifier / ad.placement, LevelPlay
impressionData.revenue, and for AdMob paid.value / 1_000_000 (AdMob reports micros) with paid.currencyCode.
Deep links
Metrixed.setDeeplinkHandler((link) => navigate(link.deepLinkValue ?? link.url, link.params));
// links you receive yourself (e.g. from Linking.getInitialURL / addEventListener):
await Metrixed.processDeeplink(url);
Direct (scheme / App Link / Universal Link) and deferred links are delivered with { url, source, clickId, deepLinkValue, params }. Links that arrive before a handler is set are held natively and delivered on subscribe.
On Android, onNewIntent and the launching intent are handled by the module; on iOS forward openURL /
continueUserActivity through Linking and processDeeplink, or use the native Metrixed.processDeeplink.
Consent and privacy
Metrixed.setConsent({ thirdPartySharing: false, measurement: true, adPersonalization: false, gdprApplies: true, tcf: tcString });
Metrixed.setThirdPartySharing(false);
Metrixed.gdprForgetMe(); // server erase + local wipe; the SDK stays off afterwards
tcf, gpp, googleDMA, metaLDU are honoured on iOS; Android carries thirdPartySharing, measurement,
adPersonalization, gdprApplies. setPushToken takes the FCM token (Android) or the hex APNs token (iOS).
Platform differences
| Call | Android | iOS |
|---|---|---|
setExternalDeviceId | yes | set externalDeviceId in the config (call is a no-op) |
setEnabled, setOfflineMode, setSecret | yes | no-op |
getAttribution, setAttributionListener | yes | resolves null / never fires |
Tests
make sdk-rn-test (not part of make test): Jest with a mocked native module and the shared wire vectors in
sdks/test-vectors/wrapper-api.json (Node image), the Android bridge compiled against the real AAR with JVM mapper tests
(Android image), the iOS mapper tested on Linux (Swift image). Request signing is done and tested by the native SDKs
(signing.json). The iOS module and the example app build in .github/workflows/sdk-wrappers.yml (macOS).
Sample: example/ (Expo dev client). Changelog: CHANGELOG.md.