React Native SDK

Use RudderStack’s React Native SDK to send events from your React Native application to various destinations.

The RudderStack React Native SDK allows you to track event data from your React Native applications and send it to your specified destinations via RudderStack.

You can check the GitHub codebase to get a more hands-on understanding of the SDK.

Github Badge

SDK setup requirements

To set up the RudderStack React Native SDK, the following prerequisites must be met:

React Native source write key
  • You will also need a data plane URL. Refer to the Glossary for more information on the data plane URL and where to find it.
success
The Setup tab in the RudderStack dashboard (seen above) has an SDK installation snippet containing both the write key and the data plane URL. You can use it to integrate the React Native SDK into your project.

Installing the React Native SDK

The recommended way to install the React Native SDK is through npm.

To add the SDK as a dependency, perform the following steps:

  • Go to the root of your application and add @rudderstack/rudder-sdk-react-native as a dependency as shown:

Initializing the RudderStack client

  1. Import the React Native SDK:
import rudderClient from "@rudderstack/rudder-sdk-react-native"
  1. Initialize the SDK by adding the following code in your application as an async function:
const rudderInitialise = async () => {
  await rudderClient.setup(WRITE_KEY, {
    dataPlaneUrl: DATA_PLANE_URL,
    trackAppLifecycleEvents: true,
    recordScreenViews: true,
  });
};
rudderInitialise().catch(console.error);

Alternatively, you can use the useEffect hook to invoke the SDK’s initialization method in your root level component:

useEffect(() => {
  const rudderInitialise = async () => {
    await rudderClient.setup(WRITE_KEY, {
      dataPlaneUrl: DATA_PLANE_URL,
      trackAppLifecycleEvents: true,
      recordScreenViews: true,
    });
    console.log('SDK is initalised');
  };
  rudderInitialise().catch(console.error);
}, []);
success
It is highly recommended to use the await keyword with the setup method.

The setup method has the following signature:

NameData TypeRequiredDescription
writeKeyStringYesYour React Native source write key
configurationObjectNoContains the RudderStack client configuration

Check the Configuring your RudderStack client section below for a full list of configurable parameters.

Configuring your RudderStack client

You can configure your client based on the following parameters by passing them in the configuration object of your setup call.

ParameterTypeDescriptionDefault value
logLevelintControls how much of the log you want to see from the SDK. Refer to the Debugging section to get a list of all supported values.RUDDER_LOG_LEVEL.ERROR
dataPlaneUrlstringURL of your data-plane. Please refer above to see how to fetch the data plane URL.https://hosted.rudderlabs.com
flushQueueSizeintNumber of events in a batch request to the server.30
dbCountThresholdintThe number of events to be saved in the SQLite database. Once the limit is reached, the older events are deleted from the database.10000
sleepTimeOutintMinimum waiting time to flush the events to the server.10 seconds
configRefreshIntervalintIt will fetch the config from dashboard after this many hours.2
autoSessionTrackingbooleanDetermines if the SDK should automatically track the user sessions.true
sessionTimeoutintMaximum inactivity period before the session expires.300000 ms (5 minutes)
trackAppLifecycleEventsbooleanWhether SDK will capture application life cycle events automatically.true
enableBackgroundModebooleanDetermines if the SDK should send the tracked events for some time before the app is closed or backgrounded.

Note: This option is currently available only for iOS and tvOS.
false
autoCollectAdvertIdbooleanDetermines if the SDK will collect the advertisement ID.false
recordScreenViewsbooleanDetermines if the SDK should capture screen view events automatically.false
dbEncryptionDBEncryptionDetermines whether to encrypt/decrypt the database using the specified key. See Encrypting RudderStack databases for more information.-
controlPlaneUrlstringIf you are using our open-source Control plane lite utility, use this option to point to your hosted sourceConfig. SDK will add /sourceConfig along with this URLhttps://api.rudderlabs.com

Identify

The identify call lets you identify a visiting user and associate them to their actions. It also lets you record the traits about them like their name, email address, etc.

A sample identify event is as shown:

rudderClient.identify(
  "test_userId",
  {
    email: "testuser@example.com",
    location: "UK",
  },
  null
)

The identify method has the following signature:

NameData TypeRequiredDescription
userIdStringYesThe user’s unique identifier
traitsObjectNoTraits information for the user
optionObjectNoExtra options for the identify event

Once a user is identified, the SDK persists all user information and passes it to the successive track or screen calls. To reset the user identification, you can use the reset method.

warning

Note that:

  • For older SDK versions (< v1.9.0), the React Native SDK captures the device ID and uses that as anonymousId for identifying the user. This helps the SDK to track the users across the application installation.
  • Starting from v1.9.0 the SDK uses a UUID as anonymousId instead of the device ID. If you are upgrading from a previous SDK version, see How RudderStack sets anonymous ID for more information on how the SDK collects and sets anonymousId.

Overriding anonymous ID

You can use the putAnonymousId method to override and set your own anonymousId:

rudderClient.putAnonymousId(ANONYMOUS_ID)

How device ID is set for Android and iOS

  • On Android devices, the deviceId is assigned during the first boot. It remains consistent across the applications and installs and changes only after factory reset.
  • According to Apple documentation, multiple apps from the same vendor are assigned the same deviceId. If all applications from the vendor are uninstalled and then reinstalled, then they are assigned a new deviceId.

Disabling device ID collection

Starting from v1.9.0, you can disable the collection of device ID by setting collectDeviceId in the Configuration object to false.

You will observe the following changes when this property is set to false:

  • The SDK does not send context.device.id as a part of the event payload.
  • The SDK replaces the existing anonymousId (if it is equal to the device ID) with a UUID.
info
These changes are introduced to make the SDK more compliant with all policies around the device ID collection.
const config = {
    dataPlaneUrl: 'DATA_PLANE_URL',
    collectDeviceId: false,
  };

await rudderClient.setup('WRITE_KEY', config);
warning

If you are upgrading to the latest SDK from a previous version (< v1.9.0) and disabling device ID collection using collectDeviceId:false:

  • Make sure your user transformations are not dependent on context.device.id as the SDK will not send this value in the event payload.
  • The context.device.id column in your warehouse destination will not be populated henceforth (it will still contain data populated by the previous SDK version).

How SDK sets anonymous ID

For direct/fresh SDK installation

RudderStack uses UUID as anonymousId regardless of whether collectDeviceId is set to true or false.

For updating SDK from older version

If you are updating your React Native SDK from an older version (< v1.9.0), then:

  • RudderStack will continue to use the device ID as anonymousId - it will not break the existing SDK behavior until you set collectDeviceId to false.
  • If you set collectDeviceId to false, the SDK checks if the existing anonymousId is a device ID. If yes, it sets a new UUID as the anonymousId.
  • If you have used the putAnonymousId method to set your own anonymousId, then the SDK will not modify it even if you set collectDeviceId to false.

Setting a custom ID

You can pass a custom ID along with the standard userId in your identify calls. RudderStack adds this value under context.externalId.

warning
RudderStack supports passing externalId only in the identify events. You must not pass this ID in other API calls like track, page, etc.

The following code snippet shows how to add externalId to your identify event:

const options = {
  externalIds: [
    {
      id: "some_external_id_1",
      type: "brazeExternalId",
    },
  ],
}
rudderClient.identify(
  "1hKOmRA4GRlm",
  {
    email: "alex@example.com",
    location: "UK",
  },
  options
)

Track

You can record the user activity through the track method. Every user action is called an event.

A sample track event is shown below:

rudderClient.track("test_track_event", {
  test_key_1: "test_value_1",
  test_key_2: {
    test_child_key_1: "test_child_value_1",
  },
})

The track method has the following signature:

NameData TypeRequiredDescription
nameStringYesName of the tracked event
propertyObjectNoExtra data properties to send along with the event
optionsObjectNoExtra event options
info

RudderStack automatically tracks the following optional application lifecycle events:

You can disable these events by passing trackAppLifecycleEvents as false in the configuration object. However, we recommend keeping them enabled.

Screen

You can use the screen call to record whenever the user sees a screen on the mobile device. You can also send some extra properties along with this event.

An example of the screen event is as shown:

rudderClient.screen("Main Activity", {
  foo: "bar",
})

Alternatively, you can use the following method signature:

NameData TypeRequiredDescription
screenNameStringYesName of the screen viewed by the user.
propertyObjectNoExtra property object to pass along with the screen call.
optionObjectNoExtra options passed along with screen event.

Automatic screen recording

You can enable the automatic recording of screen views by passing recordScreenViews as true while initializing the rudderClient. This automatically sends a screen call for every screen that a user views. By default, recordScreenViews is set to false.

info
The recordScreenViews parameter records the screen views of the native Android Activities or the iOS Views only and not by the React Native Views.

To track the screen views of the React Native Screens, you can use the following code snippet:

import rudderClient from "@rudderstack/rudder-sdk-react-native"
import {
  NavigationContainer
} from '@react-navigation/native';

const App = () => {
  const routeNameRef = React.useRef();
  const navigationRef = React.useRef();
  return ( <
    NavigationContainer ref = {
      navigationRef
    }
    onReady = {
      () => {
        routeNameRef.current = navigationRef.current.getCurrentRoute().name;
      }
    }
    onStateChange = {
      async () => {
        const previousRouteName = routeNameRef.current;
        const currentRouteName = navigationRef.current.getCurrentRoute().name;

        if (previousRouteName !== currentRouteName) {
          rudderClient.screen(currentRouteName);
        }
        routeNameRef.current = currentRouteName;
      }
    } >
    ...
    <
    /NavigationContainer>
  );
};

export default App;

Group

RudderStack’s group method lets you link an identified user with a group, such as a company, organization, or an account. You can also record any traits associated with the group like the company name, number of employees, etc.

A sample group call is shown below:

rudderClient.group("company123", {
  "city": "New Orleans",
  "state": "Louisiana",
  "country": "USA"
})

The group call has the following method signature:

NameData TypeRequiredDescription
groupIdStringYesYour group’s unique identifier
traitsObjectNoThe group’s traits
optionObjectNoExtra options passed along with group event.

Alias

The alias call lets you merge different identities of a known user.

info
alias is an advanced method that lets you change the tracked user’s ID explicitly. This method is useful when managing identities for some of the downstream destinations.

A sample alias call is as shown:

rudderClient.alias("newId")

The alias call has the following method signature:

NameData TypeRequiredDescription
newIdStringYesThe new identifier you want to assign to the user.
optionObjectNoExtra options passed along with alias event.

Reset

You can use the reset method to clear the persisted user traits. It also resets the anonymousId with a new UUID if you call it with true (for SDK v1.19.0 and later).

await rudderClient.reset(true)

To clear only user traits, call reset with false.

info
It is highly recommended to use the await keyword with the reset call.

Encrypting RudderStack databases

info
This feature is available in the React Native SDK from v1.11.0 onwards.

To enable the database encryption feature in the React Native SDK, follow these steps:

  1. Navigate to the root of your application and add @rudderstack/rudder-plugin-db-encryption-react-native as a dependency:
npm install @rudderstack/rudder-plugin-db-encryption-react-native
  1. Import the DBEncryption plugin:
import DBEncryption from '@rudderstack/rudder-plugin-db-encryption-react-native';
  1. Create a DBEncryption object and pass it while initializing the SDK:
const dbEncryption = new DBEncryption('<encryption_key>', true);

const rudderInitialise = async () => {
  await rudderClient.setup(WRITE_KEY, {
    dataPlaneUrl: DATA_PLANE_URL,
    dbEncryption: dbEncryption,
  });
};
rudderInitialise().catch(console.error);

The DBEncryption class accepts the following parameters:

ParameterTypeDescription
keystringKey used to encrypt/decrypt the database.
enablebooleanSpecifies whether to encrypt/decrypt the database

To remove encryption from a database, configure the DBEncryption object with your encryption key and set enable to false.

Instructions for iOS

The rudder-plugin-db-encryption-react-native uses the SQLCipher Cocoapod under the hood to perform encryption. This Cocoapod requires the removal of any references to the standard SQLite system library for it to function as expected.

If you set up a project to inadvertently include a linking reference against the standard SQLite library before SQLCipher, it is possible that the application builds and runs correctly but does not use SQLCipher for encryption. This is not a problem for most projects but there are certain cases where unintentional SQLite linking can occur.

One such example is when using CocoaPods or some other sub-project that declares a dependency on the SQLite3 library. In this case, adding a pod to a project can silently modify the project settings in such a way that SQLCipher is not properly linked.

You can identify and fix the above linking issue during the development stage by looking for the below error log from the SDK:

RSDBPersistentManager: createDB: Cannot encrypt the Database as SQLCipher wasn't linked correctly.

To fix the linking issue, add a linker flag to your project settings to ensure that the Xcode links SQLCipher before SQLite. Follow these steps:

  1. Open the project-level build settings. These are the global project settings, not for the individual application target.
  2. Locate the Other Linker Flags setting and add one of the following commands depending on how you are integrating SQLCipher into the app.
warning
If you are not adding SQLCipher into the app on your own and only using rudder-plugin-db-encryption-react-native, then see only the points 3 and 4 in the below table - depending on whether you are using use_frameworks! in your app’s ios/Podfile.
ScenarioCommandNotes
When using SQLCipher commercial edition static libraries$(PROJECT_DIR)/sqlcipher-static-ios/ios-libs/libsqlcipher-ios.aAdjust according to the path to the libsqlcipher-ios.a you received as a part of the package.
When using the sqlcipher.xcodeproj included in the SQLCipher Git repository$(BUILT_PRODUCTS_DIR)/libsqlcipher.a-
When using the SQLCipher CocoaPod with the use_frameworks Podfile setting enabled-framework SQLCipher-
When using the SQLCipher CocoaPod without the use_frameworks Podfile setting enabled-lSQLCipher-

Once the linker flag is added to the project-level build settings, you should see something like the below image:

Project-level build settings

After adding the linker flag to your project-level build settings, check the target-level build settings to ensure SQLCipher is shown first, as seen below:

Target-level build settings

Enabling/disabling user tracking via the optOut API (GDPR support)

RudderStack gives the users (e.g., an EU user) the ability to opt out of tracking any user activity until the user gives their consent. You can do this by leveraging RudderStack’s optOut API.

The optOut API takes true or false as a Boolean value to enable or disable tracking user activities. This flag persists across device reboots.

The following snippet highlights the use of the optOut API to disable user tracking:

await rudderClient.optOut(true)

Once the user grants their consent, you can enable user tracking once again by using the optOut API with false as a parameter sent to it:

await rudderClient.optOut(false)
info
The optOut API is available in the React Native SDK starting from version 1.0.14.

Sending tracked events before closing or backgrounding apps

info
This feature is available only for the iOS and tvOS platforms as it relies on their background mode capabilities.

To ensure that the events tracked using the React Native SDK just before closing or backgrounding your app are sent to RudderStack immediately and not upon the next app launch, set enableBackgroundMode to true while initializing the SDK.

const rudderInitialise = async () => {
  await rudderClient.setup(WRITE_KEY, {
    dataPlaneUrl: DATA_PLANE_URL,
    enableBackgroundMode: true,
  });
};
rudderInitialise().catch(console.error);

By doing so, your app requests iOS for an additional background run time which allows the SDK to send all the tracked events before the app is closed or backgrounded.

info
There is no fixed background run time for the app as it is completely abstracted by iOS. For more information, see this iOS background modes tutorial.

Tracking user sessions

By default, the React Native SDK automatically tracks user sessions. RudderStack automatically determines the start and end of a user session depending on the inactivity time configured in the SDK (default time is 5 minutes).

warning
To automatically track sessions in the React Native SDK, trackAppLifecycleEvents should also be set to true. This is because RudderStack considers the Application Opened, Application Installed, or Application Updated events as the start of a new session.
const rudderInitialise = async () => {
  await rudderClient.setup(WRITE_KEY, {
    dataPlaneUrl: DATA_PLANE_URL,
    trackAppLifecycleEvents: true,
    autoSessionTracking: true, // Set to false to disable automatic session tracking
    sessionTimeout: 5 * 60 * 1000,
  });
};
rudderInitialise().catch(console.error);

To disable automatic session tracking, set autoSessionTracking to false.

For more information on user sessions and how to track them using the React Native SDK, see Session Tracking.

Getting the session ID

To fetch the session ID of the current session, you can use the getSessionId method of the SDK. If the session ID is unavailable, this method returns a null value.

info
getSessionId() is available in the React Native SDK from v1.10.0 onwards.
const sessionId = await rudderClient.getSessionId();

Registering callbacks

The React Native SDK lets you trigger a callback once any device-mode integration is successful. You can use this callback to perform any operation that you wanted to do once a device-integration is successful.

An example of registering a callback for App Center is as shown:

await rudderClient.registerCallback("App Center", () => {
  console.log("App Center is ready")
})

The registerCallback method has the following signatures:

NameData TypeRequiredDescription
destinationNamestringYesDisplay name of the device-mode destination.
callbackFunctionYesCallback function to be triggered once device-mode integration is successful.

Filtering events

When sending events to a destination via device mode, you can explicitly specify which events should be discarded or allowed to flow through - by allowlisting or denylisting them.

info
Refer to the Client-side Event Filtering guide for more information on this feature.

Enabling/disabling events for specific destinations

The React Native SDK lets you enable or disable sending events to a specific destination or all destinations to which the source is connected. You can specify these destinations by creating an object as shown:

const options = {
  integrations: {
    // default value for `All` is true
    All: false,
    // specifying destination by its display name
    Amplitude: true,
    Mixpanel: false,
  },
}
info
The keyword All in the above snippet represents all destinations the source is connected to. Its value is set to true by default.
info
Make sure the destination names that you pass while specifying the destinations should exactly match the names listed here.

There are two methods in which you can pass the destinations specified in the above snippet to the SDK:

1. Passing destinations while initializing the SDK

This is helpful when you want to enable or disable sending the events across all event calls made using the SDK to the specified destinations.

rudderClient.setup(WRITE_KEY, config, options)

2. Passing destinations while making event calls

This approach is helpful when you want to enable or disable sending only a particular event to the specified destinations, or if you want to override the specified destinations passed with the SDK initialization (as described in the method above) for a particular event.

rudderClient.track(
  "test_track_event",
  {
    test_key_1: "test_value_1",
  },
  options
)
info
If you specify the destinations both while initializing the SDK as well as while making an event call, then the destinations specified at the event level only will be considered.

Setting the device token

You can use your device token to pass push notifications to the destinations that support them. RudderStack sets this token under context.device.token. To set a custom device token, the SDK supports the putDeviceToken method.

An example of setting a custom device token is shown below:

rudderClient.putDeviceToken(<device_token>);

Setting the advertisement ID

RudderStack collects the advertisement ID only if autoCollectAdvertId is set to true during the SDK initialization:

await rudderClient.setup(WRITE_KEY, {
  dataPlaneUrl: DATA_PLANE_URL,
  trackAppLifecycleEvents: true,
  autoCollectAdvertId: true,
  recordScreenViews: true,
})

You can use the putAdvertisingId method to pass your Android and iOS AAID and IDFA respectively. The putAdvertisingId method accepts two string arguments:

  • androidId : Your Android advertisingId (AAID)
  • iOSId : Your iOS advertisingId (IDFA)

A sample snippet highlighting the use of putAdvertisingId is shown below:

rudderClient.putAdvertisingId(AAID, IDFA)
warning
On iOS, you need to call the putAdvertisingId method before calling setup().

flush API

The React Native SDK supports the flush() API. It retrieves all messages present in the database, divides them into individual batches based on the specified queue size, and flushes them to the RudderStack server/backend.

For example, if the flushQueueSize is 30 and there are 180 events in the database when the flush() API is called, the SDK will retrieve all events and divide them into batches of 30 messages each, that is, into 6 batches.

If a batch fails for some reason, the SDK drops the remaining batches to maintain the sequence of the messages. A batch is considered as failed if it isn’t sent to the RudderStack server after 3 retries.

In device mode, the flush() API also calls the destination SDK’s flush() API (if applicable).

Debugging

If you run into any issues regarding the RudderStack React Native SDK, you can turn on the VERBOSE or DEBUG logging to find out what the issue is.

First, make sure you modify your import statement to include RUDDER_LOG_LEVEL with:

import rudderClient, {
  RUDDER_LOG_LEVEL,
} from "@rudderstack/rudder-sdk-react-native"

Then to turn on the logging, change your RudderClient initialization to the following:

await rudderClient.setup(WRITE_KEY, {
  dataPlaneUrl: DATA_PLANE_URL,
  logLevel: RUDDER_LOG_LEVEL.DEBUG, // or VERBOSE
})

You can set the log level to one of the following values:

  • NONE
  • ERROR
  • WARN
  • INFO
  • DEBUG
  • VERBOSE

FAQ

No, you don’t need to link the SDK as it is auto-linked. If you have linked it using react-native link and are facing any issues, use react-native unlink rudder-sdk-react-native to unlink it.

What is the need to use the await keyword?

The functions exposed by the SDK are asynchronous in nature. If you want a synchronous behavior, you must use the await keyword. We highly recommend using the await keyword with the setup call to make sure that the SDK has been properly set up, before any further calls are made.

Do I need to add anything to my ProGuard rules?

If you are using Proguard full mode to optimize your app, add the following lines to your Android ProGuard rules:

// Reporter Module
-keep class com.rudderstack.android.ruddermetricsreporterandroid.models.LabelEntity { *; }
-keep class com.rudderstack.android.ruddermetricsreporterandroid.models.MetricEntity { *; }
-keep class com.rudderstack.android.ruddermetricsreporterandroid.models.ErrorEntity { *; }

// Required for the usage off TypeToken class in Utils.converToMap, Utils.convertToList
-keep class com.google.gson.reflect.TypeToken { *; }
-keep class * extends com.google.gson.reflect.TypeToken

// Required for the serialization of SourceConfig once it is downloaded.
-keep class com.google.gson.internal.LinkedTreeMap { *; }
-keep class * implements java.io.Serializable { *; }
-keep class com.rudderstack.rudderjsonadapter.RudderTypeAdapter { *; }
-keep class * extends com.rudderstack.rudderjsonadapter.RudderTypeAdapter

// Required to ensure the DefaultPersistenceProviderFactory is not removed by Proguard 
// and works as expected even when the customer is not using encryption feature.
-dontwarn net.sqlcipher.Cursor
-dontwarn net.sqlcipher.database.SQLiteDatabase$CursorFactory
-dontwarn net.sqlcipher.database.SQLiteDatabase
-dontwarn net.sqlcipher.database.SQLiteOpenHelper
-keep class com.rudderstack.android.sdk.core.persistence.DefaultPersistenceProviderFactory { *; }

// Required for the usage of annotations across reporter and web modules
-dontwarn com.fasterxml.jackson.annotation.JsonIgnore
-dontwarn com.squareup.moshi.Json
-dontwarn com.fasterxml.jackson.annotation.JsonProperty

// Required for Device Mode Transformations
-keep class com.rudderstack.android.sdk.core.TransformationResponse { *; }
-keep class com.rudderstack.android.sdk.core.TransformationResponseDeserializer { *; }

How do I get the user traits after making an identify call?

You can get the user traits after making an identify call as shown:

const rudderContext = await rudderClient.getRudderContext();
console.log('Traits are : ' + JSON.stringify(rudderContext.traits));

How does the React Native SDK handle events larger than 32KB?

The React Native SDK drops any events greater than 32KB.



Questions? Contact us by email or on Slack