React Native
Ensure you have completed the Prerequisites section before continuing.
Requirements
- React Native: 0.71+
- Android: SDK 26+ (Android 8.0+)
- iOS: 13.0+
- Node.js: 16+
This SDK uses native modules and is not compatible with Expo Go. If you're using Expo, use a development build.
Installation
If you're using npm:
npm install @dashx/react-native
If you're using yarn:
yarn add @dashx/react-native
Native setup (Push / FCM)
DashX push notifications are delivered via Firebase Cloud Messaging (FCM).
- Android
- iOS
- Add the Google Services plugin in
android/build.gradle:
buildscript {
dependencies {
// ...
classpath 'com.google.gms:google-services:4.4.2'
}
}
- Apply the plugin in
android/app/build.gradle:
apply plugin: 'com.google.gms.google-services'
-
Create/choose a Firebase project and add an Android app in the Firebase console.
-
Download
google-services.jsonand place it atandroid/app/google-services.json.
On Android 13+, you must request the runtime notification permission (POST_NOTIFICATIONS) before notifications can be shown.
- Add the DashX iOS SDK and Firebase Messaging to your
ios/Podfile:
pod 'DashX', :git => 'https://github.com/dashxhq/dashx-ios.git', :tag => '1.1.9'
pod 'FirebaseMessaging', :modular_headers => true
The DashX iOS SDK is not published to CocoaPods trunk. You must add it from GitHub as shown above.
- Install pods:
cd ios && pod install
-
Create/choose a Firebase project and add an iOS app in the Firebase console.
-
Download
GoogleService-Info.plistand add it to your Xcode project (Copy items if needed). In the File Inspector, under Target Membership, enable your main iOS app target so the plist is bundled with the app (see Receive push notifications).
Option A: DashXRCTAppDelegate (recommended)
The SDK ships a DashXRCTAppDelegate class that handles Firebase configuration, token management, and notification rendering. Subclass it in your AppDelegate:
import DashXReactNative
@main
class AppDelegate: DashXRCTAppDelegate {
override func sourceURL(for bridge: RCTBridge) -> URL? {
bundleURL()
}
override func bundleURL() -> URL? {
#if DEBUG
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
}
override func notificationClicked(message: [AnyHashable: Any], actionIdentifier: String) {
// Handle notification tap
}
override func notificationDeliveredInForeground(message: [AnyHashable: Any]) -> UNNotificationPresentationOptions {
return [.banner, .sound]
}
override func handleLink(url: URL) {
// Handle deep link / universal link
}
}
DashXRCTAppDelegate automatically:
- Requests notification permission on launch
- Displays notifications with banner + sound (even in foreground)
- Tracks notification delivered, clicked, and dismissed events
- Forwards universal links to the JS
onLinkReceivedlistener
You can customise behaviour by overriding these methods:
| Override | Purpose |
|---|---|
notificationDeliveredInForeground(message:) | Return UNNotificationPresentationOptions for foreground notifications |
notificationClicked(message:actionIdentifier:) | Handle notification taps |
handleLink(url:) | Handle deep links / universal links natively |
If you don't need Firebase, you can omit the Firebase pods and GoogleService-Info.plist. DashXRCTAppDelegate still handles APNs permission and notification display.
Option B: manual Firebase setup
If you prefer manual control, wire up Firebase in AppDelegate as per the SDK README.
Configuration
Initialize the SDK once, as early as possible (module-level initialization is recommended):
import DashX from '@dashx/react-native';
DashX.configure({
publicKey: 'your-public-key',
// baseURI: 'https://api.dashx.com/graphql', // optional
// targetEnvironment: 'production', // optional
});
Usage
Identify a user
DashX.identify({
firstName: 'John',
lastName: 'Doe',
email: 'john@example.com',
});
Set identity token
setIdentity)You can set uid without token and still use public features/resources. The second argument is the DashX Identity Token: a JWT from your backend, signed with your workspace private key (see User management). Setting token grants access to your private resources in DashX—only set it for users who need that access, and treat it as sensitive. Omit the token when the app only needs public features/resources.
Pass both when you need access to private resources:
DashX.setIdentity('user-uid', 'user-token');
Reset
DashX.reset();
Track events
DashX.track('Button Clicked', { placement: 'top' });
Track screen views
DashX.screen('HomeScreen', { referrer: 'DeepLink' });
Messaging (push + preferences)
Subscribe/unsubscribe the device:
DashX.subscribe();
DashX.unsubscribe();
Request and check notification permissions (iOS only):
// Request permission to show notifications
await DashX.requestNotificationPermission();
// Check current permission status without prompting
const status = await DashX.getNotificationPermissionStatus();
getNotificationPermissionStatus and requestNotificationPermission return a numeric status mapping to UNAuthorizationStatus:
| Value | Status |
|---|---|
| 0 | Not determined |
| 1 | Denied |
| 2 | Authorized |
| 3 | Provisional |
| 4 | Ephemeral |
Fetch and save stored preferences (requires an identified user via setIdentity with uid + JWT when private resources require it):
const prefs = await DashX.fetchStoredPreferences();
await DashX.saveStoredPreferences({
'new-post': { enabled: true },
'new-bookmark': { enabled: false },
});
Listen for incoming messages:
const subscription = DashX.onMessageReceived((message) => {
console.log('Message received', message);
});
// later
subscription.remove();
CMS
Fetch a record by URN (the URN must be in the form {resource}/{uuid}):
const record = await DashX.fetchRecord('email/550e8400-e29b-41d4-a716-446655440000', {
preview: true,
language: 'en_US',
});
Search records:
const records = await DashX.searchRecords('email', {
filter: { identifier: { eq: 'welcome' } },
limit: 10,
preview: true,
language: 'en_US',
});
Assets (iOS only)
Upload a file:
const asset = await DashX.uploadAsset('/path/to/file', 'users', 'avatar');
Fetch an asset's status and URL:
const asset = await DashX.fetchAsset('asset-id');
iOS-specific features
The following methods are available only on iOS:
// Automatically track app lifecycle events (installed, updated, opened, backgrounded)
DashX.enableLifecycleTracking();
// Request App Tracking Transparency permission and enable IDFA collection
DashX.enableAdTracking();
// Listen for deep links / universal links
const subscription = DashX.onLinkReceived((link) => {
console.log('Link received', link);
});
// later
subscription.remove();
Track deep link opens
Record a dx_deep_link_opened analytics event and optionally forward the URL to the onLinkReceived listener:
DashX.processURL('https://example.com/promo', {
source: 'universal_link', // optional attribution source
forwardToLinkHandler: true, // default: true — forwards to onLinkReceived
});
| Option | Type | Default | Description |
|---|---|---|---|
source | string | undefined | Attribution source (e.g. "universal_link", "notification", "scene_url") |
forwardToLinkHandler | boolean | true | Whether to also forward the URL to the onLinkReceived listener |
Track notification navigation
Record a dx_notification_navigated event when the user taps a notification. Pass a navigation action describing where the tap leads:
// Deep link
DashX.trackNotificationNavigation(
{ type: 'deepLink', url: 'https://example.com/item/42' },
'notification-id-123'
);
// In-app screen
DashX.trackNotificationNavigation(
{ type: 'screen', name: 'OrderDetails', data: { orderId: '42' } },
'notification-id-456'
);
// Rich landing (in-app browser)
DashX.trackNotificationNavigation(
{ type: 'richLanding', url: 'https://promo.example.com' },
'notification-id-789'
);
// Click action
DashX.trackNotificationNavigation(
{ type: 'clickAction', action: 'OPEN_SETTINGS' },
'notification-id-000'
);
// Default (no specific action)
DashX.trackNotificationNavigation(null, 'notification-id-111');
| Action type | Fields | Description |
|---|---|---|
deepLink | url: string | Opens the URL externally |
screen | name: string, data?: Record<string, string> | In-app navigation to a named screen |
richLanding | url: string | Opens the URL in an in-app browser |
clickAction | action: string | Intent action (Android) or notification category (iOS) |
Error Handling
All promise-based methods reject with an error containing code and message properties:
try {
await DashX.fetchRecord('blog/invalid');
} catch (error) {
console.log(error.code); // 'EUNSPECIFIED'
console.log(error.message); // description of what went wrong
}
The SDK exports a DashXErrorCode enum for type-safe comparisons.
Troubleshooting
Logging
DashX.setLogLevel(2); // 0 = off, 1 = errors, 2 = debug