React Native SDK Integration

 

Adding the SDK to Your Project

To add the Singular React SDK to your project:

  1. Open the terminal in the root directory of your project.
  2. Download the SDK package to your project with the following command:

    npm install singular-react-native --save
  3. If you are using React Native 0.60+, the Singular package will auto-link to your project.

    If you are using React Native version 0.59 or older, run the following to link the native bridge code from the Singular package to your project:

    react-native link singular-react-native
  4. If you are using Expo: After installing the Singular SDK as described above, add the package to the plugins array of your app.json or app.config.js:  
    "expo": {
      "plugins": ["singular-react-native"]
    }
    Then rebuild your app using Expo's guide for customizing native code

Setting Up Prerequisites

iOS Prerequisites

In the project’s root directory, run the following command:

cd ios; pod install

Android Prerequisites

In the build.gradle file inside allprojects section, add the following to your app's Maven repositories:

allprojects {
  repositories {
    maven { url 'https://maven.singular.net/' }
  }
}

Add the following permissions to your app’s AndroidManifest.xml file:

<!-- Permission to access the internet -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Permission to access network state -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permission needed to retrieve Google Play Referrer data -->
<uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE" />
<!-- Permission needed to retrieve data from the Google licensing API -->
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
<!-- Permission to access the Google Advertising ID (for Android 12/API level 31 or higher) -->
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />

If you have disabled transitive dependencies for the Singular SDK, add the following to your app's build.gradle.

implementation 'com.android.installreferrer:installreferrer:2.2'
implementation 'com.google.android.gms:play-services-appset:16.0.0'

Initializing the SDK

Note: Remember to remain compliant with the various privacy laws enacted in regions where doing business, including but not limited to GDPR, CCPA and COPPA when implementing the Singular SDKs. For more information, see SDK Opt-In and Opt-Out Practices.

The SDK initialization code should be called every time your app is opened. It is a prerequisite to all Singular attribution functionality, and it also sends a new user session to Singular. Sessions are used to calculate user retention.

Importing Required Classes

In your App.js file, add the following code to import the Singular and SingularConfigs classes.

import {Singular, SingularConfig, Events, Attributes} from 'singular-react-native';

Configuring and Initializing the SDK

  1. Before you initialize the Singular SDK, you have to create a SingularConfig object. The object contains your SDK key and SDK secret (you can get them by logging into your Singular account and going to "Developer Tools > SDK Integration > SDK Keys").
  2. Optionally, you can add settings to enable various SDK features.
  3. META Install Referrer Attribution Support

    Required SDK configuration to enable "Meta Install Referrer" attribution:

    1. Provide your Facebook App Id in the Singular Configuration Object.
      // To enable META Install Referrer
      config.withFacebookAppId('INSERT YOUR FACEBOOK APP ID HERE');
    Where can I find an app's Facebook App ID?
  4. Then, use the init method to initialize the SDK, passing the SingularConfig object.

For example:

const config = new SingularConfig('<SDK KEY>', '<SDK SECRET>');
  
// Optional settings:
// Set user ID if known at time of initialization config.withCustomUserId('274e9db5c836093499df921be5');
// To enable META Install Referrer config.withFacebookAppId('Insert your Facebook App ID here');
// Enables deep linking config.withSingularLink(callBackFunction);
// iOS - Enable SKAdNetwork config.withSkAdNetworkEnabled(true);
// iOS - Wait 5m for tracking authorization before sending any events config.withWaitForTrackingAuthorizationWithTimeoutInterval(300); Singular.init(config);
Singular.init Method
Description Initialize the Singular SDK.
Usage Example
Singular.init(config);

SingularConfig Options

".with" Method Description
withCustomUserId(user_id) Send the User ID to Singular (learn more)
withFacebookAppId(FACEBOOK_APP_ID)

Note: Provide your Facebook App ID in the Singular Configuration Object to enable META Install Referrer Attribution.

withSingularLink(callBackFunction) Enable deep linking (learn more)
withSessionTimeoutInSec(seconds) Modify the session timeout (learn more)

Sending the User ID to Singular (Optional)

You may send your internal User ID to Singular using a Singular SDK method.

Note: If you use Singular's Cross-Device solution, you must collect the User ID across all platforms.

  • The User ID can be any identifier and should not expose PII (Personally Identifiable Information). For example, you should not use a User's email address, username, or phone number. Singular recommends using a hashed value unique only to your first-party data.
  • The User ID value passed to Singular should also be the same internal User ID you capture across all platforms (Web/Mobile/PC/Console/Offline).
  • Singular will include the User ID in user-level exports, ETL, and Internal BI postbacks (if configured). The User ID is first-party data, and Singular does not share it with other parties.
  • The User ID value, when set with the Singular SDK Method, will persist until it is unset using the unsetCustomUserId method or until the app is uninstalled. Closing or restarting the app does not unset the User ID.

To set the User ID, use the setCustomUserId method. To unset it (for example, if the User "logs out" of the account), call unsetCustomUserId.

Note: If multiple Users use a single device, we recommend implementing a logout flow to set and unset the User ID for each login and logout.

If you already know the user ID when the app opens, call setCustomUserId before initializing the Singular SDK. This way, Singular can have the User ID from the first Session. However, the User ID is typically unavailable until the User registers or performs a login. In that case, call setCustomUserId after the registration flow is complete.

Singular.setCustomUserId Method
Description Send the user ID to Singular.
Signature static setCustomUserId(customUserId)
Usage Example
Singular.setCustomUserId('custom_user_id');
Singular.unsetCustomUserId Method
Description Unset the user ID that has been sent to Singular.
Signature static unsetCustomUserId()
Usage Example
Singular.unsetCustomUserId();

Optional: Custom User ID Device Mapping

Important: This advanced Enterprise feature is only available in exceptional cases. Please consult with one of Singular’s Solution Engineers before implementing it.

Singular can receive additional mobile event tracking data via a server-to-server integration. To utilize this feature, you must map the User ID to Singular’s Mobile Device tracking identifier.

Note: Call this method as soon as possible after initializing the Singular SDK or once you have the User ID.

Singular.SetDeviceCustomUserId Method
Description Sets the Custom User Id the same as login and maps it to Singular’s tracking identifier.
Signature static setDeviceCustomUserId(customUserId)
Usage Example
Singular.setDeviceCustomUserId('CustomUserId');

Introduction: SKAdNetwork and SKAN

SKAdNetwork is Apple's new framework for attributing mobile installs without compromising the end-user's privacy. Singular's new version of the iOS SDK helps you implement SKAdNetwork seamlessly and with minimal engineering effort. This SKAdNetwork implementation is based on SKAN - a standard developed by Singular for a smooth implementation of SKAdNetwork.

For a full guide to Singular's SKAdNetwork implementation, see the iOS SDK SKAdNetwork implementation guide.

Enabling SKAdNetwork Tracking

To enable SKAdNetwork tracking for your app, turn on the skAdNetworkEnabled configuration option before initializing Singular:

// Enable SKAdNetwork
config.withSkAdNetworkEnabled(true);

// Register to a callback for when the conversion value is updated
config.conversionValueUpdatedHandler(value => {
	console.log(`Updated conversion value: ${value}`);
  });

Handling AppTrackingTransparency Consent

Starting with iOS 14.5, you are required to ask for user consent (using ATTrackingManager) before you can access the device's IDFA for tracking.

If you want to initialize the Singular SDK before you ask the user for consent, you can delay the SDK from firing events without IDFA for a specified interval of time, in order to wait for user consent.

To do so, initialize the Singular SDK with the waitForTrackingAuthorizationWithTimeoutInterval option, as in the following example:

// Wait 5m for tracking authorization before sending any events
config.withWaitForTrackingAuthorizationWithTimeoutInterval(300);

Adding Deep Linking Support

Deep links are links that lead into specific content inside an app. When a user clicks a deep link on a device that has the app installed, the app opens and shows a specific product or experience.

Singular tracking links can include deep linking as well as deferred deep linking (see our Deep Linking FAQ and the Singular Links FAQ for more information).

Enabling Singular Links

To activate Singular Links on both iOS and Android platforms, refer to the Singular Links Prerequisites section and ensure the completion of the following requirements.

iOS Prerequisites

In the project’s AppDelegate.m, add the following:

// Top of the AppDelegate.m
  #import <Singular-React-Native/SingularBridge.h>
  
  - (BOOL)application:(UIApplication *)application 
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Add inside didFinishLaunchingWithOptions [SingularBridge startSessionWithLaunchOptions:launchOptions]; return YES; } - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler { [SingularBridge startSessionWithUserActivity:userActivity]; return YES; }

Android Prerequisites

In the project’s MainActivity, add the following:

Java (MainActivity.java) Kotlin (MainActivity.kt)
// Add as part of the imports at the top of the class
  import android.content.Intent;
  import net.singular.react_native.SingularBridgeModule;

  // Add to the MainActivity class
  @Override
  public void onNewIntent(Intent intent) {
    if(intent.getData() != null) {
      setIntent(intent);
      super.onNewIntent(intent);
      SingularBridgeModule.onNewIntent(intent);
    }
  }

Handling Singular Links

The Singular SDK provides a handler mechanism to read the details of the tracking link that led to the app being opened.

To use the handler:

  1. Call withSingularLinks when you create the SingularConfig object, as in the example below. This registers a Singular Links handler.
  2. Inside the handler, call or define a callback function that receives a SingularLinksParams object, as in the example below. The SingularLinksParams object contains the following fields:
    • deeplink - the deep link address provided in the _dl query parameter. This is what you need to parse in order to show the users the right product or experience.
    • passthrough - all parameters included in the _p query parameter of the Singular Link.
    • isDeferred - true if this is a deferred deep link.
    • urlParameters - all query string parameters from the Singular Tracking Link. 
      • You must append the _forward_params=1 key/value pair to the Singular Tracking Link in order for all query string parameters to be available in the SDK.
const config = new SingularConfig('<SDK KEY>', '<SDK SECRET>');
  config.withSingularLink(singularLinkParams => {
      const deeplink = singularLinkParams.deeplink;
      const passthrough = singularLinkParams.passthrough;
      const isDeferred = singularLinkParams.isDeferred;
      const urlParameters = singularLinkParams.urlParameters;
      
      // Add your code here to handle the deep link
  });
  //...
  Singular.init(config);

Tracking Events

Singular can collect data about in-app events to help analyze the performance of your campaigns and measure KPIs. For example, your organization may want to collect data about user logins, registrations, tutorial completions, or leveling up in a gaming app.

Singular supports a variety of standard events. These commonly used events are often supported by ad networks for reporting and optimization. Another advantage is that when you use standard event names, Singular recognizes them automatically and adds them to the Events list without you having to define them manually. We recommend using standard events whenever possible.

The list of events sent to Singular (with the accompanying attributes) should be compiled by the UA/marketing/business team based on your organization's marketing KPIs. The business team can follow the guide at How to Track In-App Events: Guide For Singular Attribution Customers.

With each event you track, you can pass various attributes. See the recommended standard attributes per event.

In your code, send events to Singular using the event or eventWithArgs methods.

Note: For standard events, use the event's React Native name as it appears in the React Native SDK: List of Standard Events and Attributes, e.g., sngLogin.

For custom events, events that your organization wants to measure that do not match any of Singular's standard events, use any custom name (maximum of 32 characters). We recommend using names in English for compatibility with any ad network partners that may receive the event from Singular for optimization purposes.

Singular.event Method
Description Report a user event to Singular, passing the name of the event.
Usage Example
/* Send the Standard Event Login */
Singular.event(sngLogin);
/* Send the Custom Event Signup */
Singular.event('Signup');
Singular.eventWithArgs Method
Description Report a user event to Singular, passing the name of the event and any additional information you want to add, in the form of a map/object.
Usage Example
/* Send the Standard Event Content View with the recommended attributes */
Singular.eventWithArgs(sngContentView, {
sngAttrContentType: 'PrivacyController',
sngAttrContentId: '130',
sngAttrContent: 'GDPR Opt-Out Options'
});

Tracking Revenue

Singular can collect data about revenue gained through the app to help analyze the performance and ROI of your campaigns. Singular will make the data available to you in reports, log export, and postbacks.

When reporting revenue events to Singular, we recommend passing the purchase object as returned from Android's or iOS's In-App Purchase (IAP) process. This way, Singular gets all the details of the transaction, which enriches your Singular reports with data. In addition, Singular gets the transaction receipt from Google which can be used to validate the transaction in the context of fighting in-app fraud.

Passing the Purchase Object in React Native

This method requires using React Native's In-App Purchase package to manage transactions in your app.

Singular.inAppPurchase Method
Description Report an IAP event to Singular.
Usage Example
// Add the Singular Purchase classes imports
import {
   Singular,
   SingularConfig,
   SingularIOSPurchase,
   SingularAndroidPurchase,
  } from 'singular-react-native';
  
  let singularPurchase = null;
  
  if (Platform.OS === 'ios') {
   singularPurchase = new SingularIOSPurchase(
     product.revenue,
     product.currency,
     purchase.productId,
     purchase.transactionId,
     purchase.transactionReceipt,
   );
  } else if (Platform.OS === 'android'){
   singularPurchase = new SingularAndroidPurchase(
     product.revenue,
     product.currency,
     purchase.transactionReceipt,
     purchase.signatureAndroid,
   );
  }
  
  Singular.inAppPurchase('report iap', singularPurchase);

Note: Pass currency as a three-letter ISO 4217 currency code, e.g., "USD," "EUR", "INR".

Passing the Purchase Object Using Native Code

If you don't use a React Native In-App Purchase package, you can still send revenue events to Singular with the purchase object, but you have to use native iOS and Android code.

Note: Pass currency as a three-letter ISO 4217 currency code, e.g., "USD," "EUR", "INR".

Read more...

iOS

iapComplete:transaction Method
Description Report an IAP event to Singular with all the details, optionally adding a name for the event.
Usage Example
// report the transaction details to Singular
[Singular iapComplete:transaction];
  
// report the transaction details to Singular with a custom name
[Singular iapComplete:transaction withName:@"MyCustomRevenue"];

Android

To take advantage of Android's IAP functionality, first add the following to your app's build.gradle file:

implementation 'com.singular.sdk:singular_sdk:9.+
Singular.revenue Method
Description Report a revenue event to Singular with the purchase object that is received from the Google Billing Library.
Usage Example
Singular.revenue('USD', 5.50, purchase);
Singular.customRevenue Method
Description Report a revenue event to Singular with a custom name for the event and with the purchase object that is received from the Google Billing Library.
Usage Example
Singular.customRevenue('MyCustomRevenue', 
'USD', 5.50, purchase);

Reporting Revenue Events without the Purchase Object

While we strongly recommend reporting revenue events the way described above, you can also send revenue events to Singular just by passing the currency and transaction amount. Note that this way, Singular does not get the purchase receipt and cannot validate the transaction.

Read more...
Singular.revenue Method
Description Report a revenue event to Singular with the revenue currency and amount.
Usage Example
Singular.revenue('USD', 5.50);
Singular.customRevenue Method
Description Report a revenue event to Singular with the revenue currency and amount as well as a custom name for the event.
Usage Example
Singular.customRevenue('MyCustomRevenue', 'USD', 5.50);

Note: Pass currency as a three-letter ISO 4217 currency code, e.g., "USD," "EUR", "INR".

Hybrid Event Tracking (Advanced)

Singular recommends sending all events and revenue through the Singular SDK integrated into your app. However, Singular can collect events and revenue from other sources.

Any event NOT sent from the Singular SDK must comply with Singular's Server-to-Server Event documentation requirements and provide the matching device identifier to correctly attribute an event.

Important:

Discrepancies will occur if device identifiers used on Server-to-Server event requests do not have a matching device identifier in Singular. Be aware of the following possibilities:

  • If an event request is received "before" the Singular SDK has recorded the device identifier, from an App Session, then the event request will be considered the "first session" for the unknown device, and Singular will attribute the device as an organic attribution.
  • If the Singular SDK did record a device identifier, but the Singular SDK identifier differs from the device identifier specified in the Server-to-Server Event request then the event will be attributed incorrectly.

Hybrid Event Tracking Guides

Sending Events from an Internal Server

Singular can collect data about revenue from your Server to help analyze the performance and ROI of your campaigns.

Requirements:

  • From an in-app Registration or Login Event, capture and pass the device identifiers and store this data with the User ID on your server. Because device identifiers may change for a user, be sure to update the identifiers when a user generates an app session. This guarantees the server-side event will be attributed to the correct device.
  • Server-side events are platform specific and should only be sent with the device identifier matching the device platform (e.g., IDFA or IDFV for iOS devices).
  • You can use the Singular Internal BI postback mechanism to push an event in real time to your internal endpoint so that you can update the data set on the server side. See the Internal BI Postback FAQ.
  • Review the "Tracking Revenue" section in the Server-to-Server Integration guide for details.
Sending Events from a Revenue Provider
Third-party providers like RevenueCat or adapty can provide Purchase and Subscription Revenue to Singular.

Follow the links below for details on how to enable these partners.

Sending Events from Segment

To enable Segment to send events to Singular, in parallel with the Singular SDK, you must add a "Cloud-Mode" Destination in Segment. Follow our guide HERE.

Creating Short Referrer Links

Note: This functionality is available in SDK version 3.1.8+.

Use short links to transform long, parameter-filled Singular Links into shorter and more secure links that are convenient for sharing.

Typically, you will want to create short links dynamically so that your app's users can share them with friends to invite them to use the app.

To create a short link, you need:

  • A Singular Link that leads to your app download (see the Singular Links FAQ).
  • Any parameters you want to add to the link dynamically (see Tracking Link Parameters for the list of options).
  • The name and ID of the referring user, if you want to be able to track new app installs back to the user who shared the link.

Use the createReferrerShortLink method to create a short link as in the example below.

Singular.createReferrerShortLink (
    "https://sample.sng.link/B4tbm/v8fp?_dl=https%3A%2F%2Fabc.com",
    "John Doe", // Referrer Name
    "aq239897", // Referrer ID
    {"channel": "sms"}, // Any parameters you want to add to the link
    (shortLinkURL,error) => {
      /* Add your share logic here if shortLinkURL is not null. If there was an error, add logic to retry/abort/modify the params passed to the function, based on the cause of the error. */
    }
)

Handling Conversion Value Updates

Managed Mode

By default, the SKAdNetwork implementation manages the conversion value directly from the Singular server side.

This allows for maximum flexibility as you can set and change your conversion values through the Singular platform, without modifying your client-side code.

This server-side managed mode also helps you deal with the SKAdNetwork timers. SKAdNetwork allows you to update the conversion value within 24 hours from the time of registration to SKAdNetwork. Any call to update the conversion value extends the timer by 24 more hours. Therefore, when choosing your conversion events, you'll have to make sure the events happen within that update window. In managed mode, you can change the conversion event configuration at any time, without releasing a new version of your app.

Manual Mode

If you want to update the conversion value on your own in the app code, call withManualSkanConversionManagement when you initialize the SDK:

const config = new SingularConfig('<SDK KEY>', '<SDK SECRET>');
// Enable SKAdNetwork
config.withSkAdNetworkEnabled(true);

// Enable manual conversion value updates
config.withManualSkanConversionManagement();

Singular.init(config);

Then, to update the conversion value, use the skanUpdateConversionValue method wherever needed in your app's lifecycle:

skanUpdateConversionValue Method (JavaScript)
Description Manually update the SKAdNetwork conversion value.
Signature Singular.skanUpdateConversionValue(conversionValue)
Usage Example
// signup event happened
Singular.event('SignUp');

// update conversion value to 7
Singular.skanUpdateConversionValue(7);

Note: The skanUpdateConversionValue method will not function if you have not set the SDK to manual updates on initialization. 

Retrieving the Conversion Value

To get the current conversion value, use the skanGetConversionValue method. This method works in both managed and manual mode.

skanGetConversionValue Method (JavaScript)
Description Get the current conversion value tracked by the Singular SDK.
Signature Singular.skanGetConversionValue()
Usage Example
const conversionValue = Singular.skanGetConversionValue();

Tracking Uninstalls

To let Singular track uninstalls for your app:

  1. First, configure the app in the Singular platform, as detailed in Setting Up Uninstall Tracking [Android][iOS].
  2. Use your preferred method to retrieve the APNS/FCM tokens in React Native.
  3. Call the setUninstallToken method, passing the APNS/FCM token to as in the example below. Be sure to pass the right token based on the device platform.
Singular.setUninstallToken Method
Description Send Singular the APNS/FCM token in order to let it track app uninstalls.
Usage Example
if (Platform.OS === 'ios') {
  Singular.setUninstallToken(apnsToken);
} else if (Platform.OS === 'android'){
  Singular.setUninstallToken(fcmToken);
}

Modifying the Session Timeout

The Singular SDK manages user sessions automatically, so you don't need to add any code to handle sessions. However, you can modify the session timeout value if you want.

By default, if the app runs in the background for 60 seconds or more before returning to the foreground, the SDK registers a new session.

To change the timeout value, use .withSessionTimeoutInSec when you create the SingularConfig object. For example:

const config = new SingularConfig('<SDK KEY>', '<SDK SECRET>')
    .withSessionTimeoutInSec(120); // Set timeout to 120 seconds
Singular.init(config);

Complying with Data Privacy Laws

Singular provides privacy-safeguarding functionality to help you cooperate with any partners who may be complying with consumer privacy laws such as GDPR and CCPA (California Consumer Privacy Act). These partners want to be notified if the end-user has consented to share their private information.

LimitDataSharing

If you have implemented a way to ask users for consent to share their information, use the limitDataSharing method to notify Singular of the user's choice:

  • Use limitDataSharing:NO to indicate that the user consented (opted in) to share their information.
  • Use limitDataSharing:YES if the user did not consent.

Singular uses LimitDataSharing in "User Privacy Postbacks" as well as passing this information on to partners who require it in order to comply with relevant regulations. See "User Privacy and Limit Data Sharing" for more information.

Note: The use of the method is optional, but there may be attribution information that the partner will share with Singular only if specifically notified that the user has opted in.

Singular.limitDataSharing Method
Signature Singular.limitDataSharing(shouldLimitDataSharing)
Description Notify Singular of user consent (opt-in) for sharing private data.
Usage Example
// User has opted into sharing data
Singular.limitDataSharing(false);

Additional Methods for GDPR Compliance

The Singular SDK provides several methods to help you comply with GDPR policies and let Singular know about user consent or non-consent for tracking.

Singular.trackingOptIn Method
Description Let Singular know of user consent (opt-in) for tracking.
Usage Example
Singular.trackingOptIn();
Singular.stopAllTracking Method
Description

Stop all tracking activities for this user on this app.

Important: This effectively disables the Singular SDK, even after you restart the app. The only way to re-enable the SDK is by calling resumeAllTracking.

Usage Example
Singular.stopAllTracking();
Singular.resumeAllTracking Method
Description Resume tracking activities for this user on this app.
Usage Example
Singular.resumeAllTracking();
Singular.isAllTrackingStopped Method
Description Check the tracking status for this user on this app. Returns true if tracking has been stopped.
Usage Example
Singular.isAllTrackingStopped();