React Native Source

Analytics for React Native makes it dead simple to send your data to any analytics or marketing tool without having to learn, test or implement a new API every time.

All of our libraries are open-source, so you can view Analytics for React Native on Github, or check out our browser and server-side libraries too.

Want to stay updated on releases? Subscribe to the release feed.

Getting Started

Install the SDK

The recommended way to install Analytics for React Native is via npm, since it means you can create a build with specific destinations, and because it makes it dead simple to install and upgrade.

First, add the @segment/analytics-react-native dependency to your dependencies and link it using react-native-cli, like so:

$ yarn add @segment/analytics-react-native
$ yarn react-native link

Then somewhere your application, setup the SDK like so:

await analytics
  .configure()
  .recordScreenViews() // Record screen views automatically!
  .trackAppLifecycleEvents() // Record certain application events automatically!
  .setup("YOUR_WRITE_KEY")

And of course, import the SDK in the files that you use it with:

import analytics from '@segment/analytics-react-native'

Dynamic Framework for Manual Installation

We highly recommend using Cocoapods.

However, if you cannot use Cocoapods, you can manually install our dynamic framework allowing you to send data to Segment and on to enabled cloud-mode destinations. We do not support sending data to bundled, device-mode integrations outside of Cocoapods.

Here are the steps for installing manually:

  1. Download the latest built iOS SDK, and unzip the zip file.
  2. Drag the unzipped Analytics.framework folder into your Xcode project. Make sure to check Copy items if needed. Add Analytics.framework
  3. In the General tab for your project, search for Embedded Binaries and add the Analytics.framework. Embed Analytics.framework

Please note, if you are choosing to not use a dependency manager, you must keep files up-to-date with regularly scheduled, manual updates.

Including SDKs for destinations with Device-based Connection Modes

In the interest of keeping our SDK lightweight, Analytics only installs the Segment destination. This means that all your data will be sent via Segment’s servers to any tools you’ve enabled by the default Cloud-based Connection Mode.

As described here, some integrations require or offer Device-based Connection Modes. In those cases, you’ll need to take some additional steps as shown in the source documentation here.

Now that the SDK is installed and setup, you’re ready to…

Identify

identify lets you tie a user to their actions and record traits about them. It includes a unique User ID and any optional traits you know about them.

We recommend calling identify a single time when the user’s account is first created, and only identifying again later when their traits are changed.

Note: We automatically assign an anonymousId to users before you identify them. The userId is what connects anonymous activities across devices.

Example identify call:

analytics.identify("a user's id", {
  email: "a user's email address"
})

This call identifies a user by his unique User ID (the one you know him by in your database) and labels him with name and email traits.

The identify call has the following arguments:

userId stringThe database ID for this user. If you don’t know who the user is yet, you can omit the userId and just record traits. You can read more in the identify reference.
traits JSONMap, optionalA dictionary of traits you know about the user, like their email or name. You can read more about traits in the identify reference.

Analytics works on its own background thread, so it will never block the main thread for the UI or the calling thread.

Calling identify with a userId will write that ID to disk to be used in subsequent calls. That ID can be removed either by uninstalling the app or by calling reset.

Find details on the identify method payload in our Spec.

Track

track lets you record the actions your users perform. Every action triggers what we call an “event”, which can also have associated properties.

To get started, our SDK can automatically track a few key common events with our Native Mobile Spec, such as the Application Installed, Application Updated and Application Opened. These events are required for attribution tracking in several commonly used Segment destinations. Simply enable this option during initialization.

You’ll also want to track events that are indicators of success for your mobile app, like Signed Up, Item Purchased or Article Bookmarked. We recommend tracking just a few important events. You can always add more later!

Example track call:

analytics.track('Item Purchased', {
  item: 'Sword of Heracles',
  revenue: 2.95
})

This example track call tells us that your user just triggered the Item Purchased event recording the item name of “Sword of Hercales” and revenue of 2.95.

track event properties can be anything you want to record. In this case, item and revenue.

The track call has the following fields:

event stringThe name of the event. We recommend human-readable names like Song Played or Status Updated.
properties JSONMap, optionalA dictionary of properties for the event. If the event was Product Added to cart, it might have properties like price and productType.

Screen

The screen method lets you you record whenever a user sees a screen of your mobile app, along with optional extra information about the page being viewed.

You’ll want to record a screen event an event whenever the user opens a screen in your app. This could be a view, fragment, dialog or activity depending on your app.

Example screen call:

analytics.screen('Photo Feed', {
  'Feed Type': 'private'
})

The screen call has the following fields:

name stringThe name of the screen, for example Signup or Home.
properties JSONMap, optionalA dictionary of properties for the screen. A screen Photo Feed might have properties like Feed Type or Sort Order.

Find details on the screen payload in our Spec.

Group

group lets you associate an identified user user with a group. A group could be a company, organization, account, project or team! It also lets you record custom traits about the group, like industry or number of employees.

This is useful for tools like Intercom, Preact and Totango, as it ties the user to a group of other users.

Example group call:

analytics.group('group123', {
  name: 'Initech',
  description: 'Accounting Software'
})

The group call has the following fields:

groupId stringThe ID for this group in your database.
traits JSONMap, optionalA dictionary of traits you know about the group. Things like: name or website.

Find more details about group including the group payload in our Spec.

Alias

alias is how you associate one identity with another. This is an advanced method, but it is required to manage user identities successfully in some of our destinations.

In Mixpanel it’s used to associate an anonymous user with an identified user once they sign up. For KISSmetrics, if your user switches IDs, you can use ‘alias’ to rename the ‘userId’.

Example alias call:

analytics.alias('some new id')

The alias call has the following fields:

newId stringThe newId of the user you want to map to.

For more details about alias, including the alias call payload, check out our Spec

Reset

The reset method clears the SDK’s internal stores for the current user and group. This is useful for apps where users can log in and out with different identities over time.

Clearing all information about the user is as simple as calling:

analytics.reset()

Submitting to the App Store

When you submit to the app store, be aware that Segment collects the IDFA for use in doing mobile install attribution with destinations like Mobile App Tracking. Even if you’re not currently doing mobile install attribution, if you get asked, “Does this app use the Advertising Identifier (IDFA)?” on this page, you’ll want to check the following three boxes:

  1. “Attribute this app installation to a previously served advertisement”
  2. “Attribute an action taken within this app to a previously served advertisement”
  3. “I, YOUR_NAME, confirm that this app, and any third party…”

Note, you should not check the box labeled “Serve advertisements within the app” unless you are actually going to display ads.

Destinations in Debugger

If you are seeing any of your destinations turned off in the raw version of requests in the Segment live debugger, but you haven’t added those to your requests, like this:

"integrations": {
  "Segment.io": false,
  "Google Analytics": false,
  "Localytics": false,
  "Mixpanel": false
}

These flags tell the Segment servers that a request was already made directly from the device through a packaged SDK. That way we don’t send a duplicate request via our servers to those services.

Configuration

The Configuration interface provides a set of properties that control various policies of the Analytics instance. You can configure using the configure method and then calling the setup method with a writeKey like so:

analytics
  .configure()
  // ...
  .setup('YOUR_WRITE_KEY')
writeKey stringYour Segment source’s Write Key.

Native configuration

You can also use the native Analytics API to configure it. Just make sure to call analytics.useNativeConfiguration() in your JavaScript code so that Analytics doesn’t wait for you to configure it.

Flushing

You can set the number of events should queue before flushing. Setting this to 1 will send events as they come in (i.e. not send batched events) and will use more battery. 20 by default.

await analytics
    .configure()
    .flushAt(1)
    .setup("YOUR_WRITE_KEY")

You can also manually flush the queue:

analytics.alias('glenncoco')
analytics.flush()

Application Lifecycle Tracking

Our SDK can automatically instrument common application lifecycle events such as “Application Installed”, “Application Updated” and “Application Opened”. Simply enable this option when you initialize the SDK.

await analytics
    .configure()
    .trackAppLifecycleEvents()
    .setup("YOUR_WRITE_KEY")

Logging

To see a trace of your data going through the SDK, you can enable debug logging with the debug method:

await analytics
    .configure()
    .debug()
    .setup("YOUR_WRITE_KEY")

By default debug logging is disabled.

Opt-out

Depending on the audience for your app (e.g. children) or the countries where you sell your app (e.g. the EU), you may need to offer the ability for users to opt-out of analytics data collection inside your app. You can turn off forwarding to ALL destinations including Segment itself:

analytics.disable()

Or if they opt-back-in, you can re-enable data collection:

analytics.enable()

Note: disabling the Segment SDK ensures that all data collection method invocations (eg. track, identify, etc) are ignored; however, it does not tear down inititialized SDKs. If your packaged SDKs are collecting data automatically or outside of Segment, disabling Segment does not address that. We recommend invoking corresponding disable methods in each of your packaged SDKs in response to user opt-out to ensure any automatic data collection is stopped.

Packaging Destinations with Device-based Connection Modes

By default, our @segment/analytics-react-native npm packages no external SDKs.

If you would like to add any destinations with Device-based Connection Modes, first add the dependencies you need. You can find these in our app when you open the destination sheet for any mobile destination with a Device-based Connection Mode option.

yarn add @segment/analytics-react-native-{bugsnag,branch,google-analytics}

After adding the dependency, you must register the destination with our SDK.

import analytics from '@segment/analytics-react-native'
import Bugsnag from '@segment/analytics-react-native-bugsnag'
import Branch from '@segment/analytics-react-native-branch'
import GoogleAnalytics from '@segment/analytics-react-native-google-analytics'

await analytics
    .configure()
    // Add any of your Device-based destinations.
    .using(Bugsnag, Branch, GoogleAnalytics)
    // ...
    .setup("YOUR_WRITE_KEY")

We recommend using Device-based destinations and Connection Modes sparingly to reduce the size of your application.

Anonymizing IP

We collect IP address for client-side (iOS, Android, Analytics.js and Xamarin) events automatically.

If you don’t want us to record your tracked users’ IP in destinations and S3, you can set your event’s context.ip field to 0.0.0.0 . Our server won’t record the IP address of the client for libraries if the context.ip field is already set.

FAQ

How big is the Segment SDK?

The core Segment SDK is extremely lightweight! On iOS it weighs in at about 212kb. On Android it contains just under 1k methods, the JAR weighs in at 123kb and the dex size is 113kb.

Can I also use the native Analytics API?

Yes! You can use the native Analytics API, just note that:

  • We only support singleton instances, use SEGAnalytics.sharedAnalytics on iOS or Analytics.with(context) on Android.
  • You cannot call the native singleton before it has been configured. If you need the native Analytics before you call analytics.configure().setup('your write key') on your JavaScript code you will need to configure it natively instead.
  • If you configure Analytics using its native API you will need to use analytics.useNativeConfiguration() on your JavaScript code.

How Do I Use Push Notifications?

As of today, React Native doesn’t provide an official JavaScript API to handle push notifications. For this reason, Analytics for React Native doesn’t provide an API to do so, you can workaround this by using the underlying native SDK.

On iOS

For services that send push notifications, you first want to create a Push SSL certificate following these steps. You then want to configure your application delegate to look like the code below, and replace your Segment source write key.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  SEGAnalyticsConfiguration* configuration = [SEGAnalyticsConfiguration configurationWithWriteKey:@"YOUR_WRITE_KEY"];

  // Use launchOptions to track tapped notifications
  configuration.launchOptions = launchOptions;
  [SEGAnalytics setupWithConfiguration:configuration];

  if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerForRemoteNotifications)]) {
    UIUserNotificationType types = UIUserNotificationTypeAlert | UIUserNotificationTypeSound |
    UIUserNotificationTypeBadge;
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types
    categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    [[UIApplication sharedApplication] registerForRemoteNotifications];
  } else {
    UIRemoteNotificationType types = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound |
    UIRemoteNotificationTypeBadge;
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:types];
  }
  return YES;
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  [[SEGAnalytics sharedAnalytics] registeredForRemoteNotificationsWithDeviceToken:deviceToken];
}

// A notification has been received while the app is running in the foreground
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
  [[SEGAnalytics sharedAnalytics] receivedRemoteNotification:userInfo];
}

// iOS 8+ only
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
  // register to receive notifications
  [application registerForRemoteNotifications];
}

On Android

If you’re using a Device-based Connection Mode for a mobile destination, you can always access features from that tool’s native SDK.

To make sure you use the same instance of these destinations as we do, you can register a listener that notifies you when the destinations are ready. This will be called synchronously if the destinations are notified, and asynchronously if the destinations aren’t yet ready.

analytics.onIntegrationReady("Crittercism", new Callback() {
  @Override public void onReady(Object instance) {
    // Crittercism uses static methods only, so the instance returned is null.
    Crittercism.leaveBreadcrumb();
  }
});
analytics.onIntegrationReady("Mixpanel", new Callback() {
  @Override public void onReady(Object instance) {
    MixpanelAPI mixpanelAPI = (MixpanelAPI) instance;
    mixpanelAPI.clearSuperProperties();
  }
});

For the destinations that return Void, they simply use a shared instance. You can call into the SDK directly. With this API, you’re guaranteed that they’ve been initialized first, and if you ever decide to change the settings for the destination on our dashboard, they’ll be reflected here.

analytics.onIntegrationReady(BundledIntegration.FLURRY, new Callback() {
  @Override public void onReady(Object instance) {
    // Flurry uses static methods only, so the instance returned is null.
    Flurry.setLogEnabled(true);
  }
});

How Do You Handle Unique Identifiers?

A key component of any analytics platform is consistently and accurately identifying users. Some kind of ID must be assigned and persisted on the device so that user actions can be effectively studied. This is especially important for funnel conversion analysis and retention analysis. Naturally the Analytics SDK needs a unique ID for each user.

iOS

To protect end-users’ privacy, Apple places restrictions on how these IDs can be generated and used. Here’s an explanation of these policies from Apple, and how we generate IDs in compliance.

Before iOS 5 developers had access to uniqueIdentifier which was a hardware-specific serial number that was consistent across different apps, vendors and installs. Starting with iOS 5, however, Apple deprecated access to this identifier. In iOS 6 Apple introduced the identifierForVendor which protects end-users from cross-app identification. In iOS 7 Apple restricted access to the device’s MAC address, which was being used by many developers as a workaround to get a device-specific serial number similar to like uniqueIdentifier.

Segment’s iOS library supports iOS 7+ by generating a UUID and storing it on disk. This is in line with the privacy policies required by Apple, maintains compatibility, and leaves open the option for multiple users on one device since the UUID can be regenerated.

Android

Our SDK also collects the Advertising ID provided by Play Services. Make sure the Play Services Ads library is included as a dependency for your application. This is the ID that should be used for advertising purposes. This value will be set to context.device.advertisingId.

We also collect the Android ID as context.device.id. Some destinations rely on this field being the Android ID, so take care if you choose to override the default value.

How does the SDK queue API calls?

Our library queues API calls and uploads them in batches so that we don’t drain your user’s battery life by making a network request for each event tracked.

As soon as you send as an event, we’ll save it to disk, and if queue size reaches your specified maximum queue size (which is 20 by default), we flush the queue and upload all the events in a single batch. Since the data is persisted right away, there is no data loss even if the app is killed, or the operating system crashes.

The queue behavior may differ for Device-based destinations. For instance, Mixpanel’s SDK queues events and then flushes them when the app goes to the background only.

This is why even if you see events in the debugger, the Device-based destination may not show them on their dashboards yet, simply because their mobile SDK may still have them queued. The opposite may also happen, that we have some events queued so they haven’t shown up in the debugger, but the Device-based destination has already sent the events to their servers.

Can I help develop a destination?

Yep! Our SDK is open-source. If you’d like to contribute, fix a bug, or add a destination - here’s documentation on how to do so. to add a destination, make sure you contact our partners team first.

IDFA

Some destinations, particularly mobile attribution tools (e.g. Kochava), require the IDFA (identifier for advertisers). The IDFA shows up in Segment calls in the debugger under context.device.advertisingId. In order for this value to be captured by the Segment SDK, ensure that you include the iAd framework.

Once you enable this, you will see the context.device.advertisingId populate and the context.device.adTrackingEnabled flag set to true.

Note: While the network is deprecated, the relevant framework is not.

Troubleshooting

No events in my debugger

  1. Verify you have followed all Getting Started steps
  2. Verify you have entered the correct writeKey for your source
    • If the writeKey you have entered is something other than a string or an empty string your app may crash
    • If the writeKey you have entered is a valid form but not the correct writeKey for your specific source, you will not see an error response. Data will be accepted by Segment but not able to be correctly routed to your source (debugger).
  3. Enable logging to confirm if call is being sent to Segment

No events in my destinations

  1. Verify that your destination is enabled
  2. Verify your destination credentials entered in your Segment dashboard are correct
  3. Make sure the destination can accept what you’re sending:
    • Does the integration have device-mode/cloud-mode support? Confirm you are sending via the correct connection mode.
    • Does the destination accept the type of call you are sending? Not all destinations accept all calls: page, track, etc.
  4. If you are still not seeing data in your destination, continue debugging based on which type of connection mode you are using.

Debugging Device-Based Connection Mode Destinations

If you are using device-based connection mode, you should see the value of that integration set to false in the integrations object. That means that the data is being sent from the device to the destination SDK, and not through Segment’s servers. This is expected if you elected to use a device-based connection mode destination’s SDK with Segment’s during installation.

Enable verbose logging and trigger the call in question. You should see a call to Segment triggered as well as to the partner SDK. It will show you exactly which partner method was invoked and the arguments it was invoked with!

Debugging Cloud-Based Connection Mode Destinations

Look at the raw JSON in your debugger. Does the call look like what is expected?

Read through the docs for that destination to see expected event format, behavior and caveats for that destination.

Still having issues?

Feel free to reach out to us with the following information:

  • The version of our SDK you are using
  • Whether you are using device-based or cloud-based connection mode
  • Logs of the call in question
  • Screenshots of the event in the Segment debugger
  • Screenshots of what you are seeing in your destination

If you have any questions, or see anywhere we can improve our documentation, please let us know!