React Native SDK - Basic Integration

Prerequisites

Complete these prerequisite steps before installing the Singular React Native SDK to ensure a smooth integration process.

Required Prerequisites:


Installation

Installing the SDK Package

Add the Singular React Native SDK to your project using npm. The SDK provides JavaScript bindings to the native Singular SDKs for iOS and Android.

Install via NPM

  1. Open terminal: Navigate to your project's root directory.
  2. Install package: Run the following command to add the SDK to your project:
    bash
    npm install singular-react-native --save

Linking the Native Modules

How you link the SDK depends on your React Native version and whether you're using Expo.

  • React Native 0.60+: The SDK auto-links automatically. No additional steps required.
  • React Native 0.59 or older: Manually link the native bridge code:
    bash
    react-native link singular-react-native
  • Expo projects: After installing the SDK, add it to your plugins configuration:
    app.json
    {
      "expo": {
        "plugins": ["singular-react-native"]
      }
    }

    Then rebuild your app using Expo's customizing native code guide.


Platform Configuration

iOS Configuration

Complete iOS-specific setup to enable CocoaPods dependencies and ensure proper SDK functionality.

Note: If you are building with Expo, iOS configuration is handled automatically. Skip this section.

Install CocoaPods Dependencies

Run the following command from your project's root directory to install required iOS dependencies:

bash
cd ios && pod install

Android Configuration

Configure your Android build files to add the Singular Maven repository, required permissions, and dependencies.

Note: If you are building with Expo, Android configuration is handled automatically. Skip this section.

Add Maven Repository

Add the Singular Maven repository to your project's build.gradle file to enable SDK dependency resolution.

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

Add Required Permissions

Add these permissions to your AndroidManifest.xml file under the <manifest> tag to enable core SDK functionality.

AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="BIND_GET_INSTALL_REFERRER_SERVICE" />
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />

Important: Exclude the com.google.android.gms.permission.AD_ID permission if you're integrating the Kids SDK. This permission is required for GAID collection in standard apps but must be omitted for apps targeting children under 13.

Samsung Galaxy Store Support

To enable install referrer tracking from Samsung Galaxy Store, add the following to your AndroidManifest.xml:

AndroidManifest.xml
<queries>
   <package android:name="com.sec.android.app.samsungapps" />
</queries>

Transitive Dependencies

If you've disabled transitive dependencies for the Singular SDK in your Gradle configuration, manually add these required dependencies:

app/build.gradle
dependencies {
    // Required for install referrer tracking
    implementation("com.android.installreferrer:installreferrer:2.2")

    // Required for App Set ID
    implementation("com.google.android.gms:play-services-appset:16.0.0")
}

ProGuard Configuration

When building release APKs, ProGuard (or R8) may strip or obfuscate SDK classes. Add these keep rules to preserve Singular functionality.

Why This Matters: ProGuard is enabled by default in React Native Android release builds. Without proper keep rules, the SDK may not function correctly in production.

  1. Locate ProGuard file: Navigate to android/app/proguard-rules.pro in your project.
  2. Add keep rules: Append the following rules to the file:
    proguard-rules.pro
    # Preserve Singular SDK classes
    -keep class com.singular.sdk.** { *; }
    
    # Preserve Android Install Referrer library
    -keep public class com.android.installreferrer.** { *; }
    
    # Uncomment if using Singular revenue tracking with Google Play Billing Library
    #-keep public class com.android.billingclient.** { *; }

SDK Integration

Privacy Compliance: Comply with privacy laws in your operating regions, including GDPR, CCPA, COPPA, and others when implementing the Singular SDK. See SDK Opt-In and Opt-Out Practices.

Compatibility Note: Singular React Native SDK v4.0+ supports both the legacy Bridge and TurboModule architectures. For most developers, no migration or refactor is required: upgrade React Native and/or the SDK, and both old and new code will function as expected. To take advantage of direct TurboModule APIs, see the new initialization example below.

Import SDK Classes

Import the Singular SDK classes at the top of your main application file (typically App.tsx or App.js).

New ArchitectureOld Architecture

// Direct TurboModule API initialization (React Native 0.76+)

// Import Native API and EventEmitter
import NativeSingular from 'singular-react-native/js/NativeSingular';
import { NativeEventEmitter } from 'react-native';

Initialize the SDK

Basic Initialization

  1. Get credentials: Log into your Singular account and navigate to Developer Tools > SDK Integration > SDK Keys to find your SDK Key and Secret.
  2. Create config: Instantiate a SingularConfig object, or a plain object for TurboModule API, with your credentials.
  3. Add configuration: Optionally chain configuration methods (legacy) or add properties directly in the config object (TurboModule).
  4. Initialize SDK: Call Singular.init() or NativeSingular.init() to start the SDK.

Initialization Example

Initialize the SDK in your app's entry point, typically within a useEffect hook to ensure it runs once on app start.

New ArchitectureOld Architecture

// TurboModule direct API (React Native 0.76+ New Architecture)
import React, { useEffect } from 'react';
import NativeSingular from 'singular-react-native/js/NativeSingular';

export default function App() {
  useEffect(() => {
    const config: SingularConfig = {
      apikey: 'YOUR_SDK_KEY',
      secret: 'YOUR_SDK_SECRET',
      enableLogging: true,
      logLevel: 3,
    };

    NativeSingular.init(config);

  }, []);
  
  return (
    // Your app components
  );
}

Direct TurboModule API:
When using the NativeSingular TurboModule API, configuration is simplified to a plain JavaScript object and direct event emitter setup. This is recommended only for apps targeting the New Architecture (React Native 0.76+). All other apps should continue using the wrapper (SingularConfig/Singular.init) for maximum compatibility.

Advanced Configuration Example

Configure multiple SDK features during initialization by chaining configuration methods before calling init().

New ArchitectureOld Architecture
// TurboModule direct API (React Native 0.76+ New Architecture)
import React, { useEffect } from 'react';
import NativeSingular from 'singular-react-native/js/NativeSingular';
import { NativeEventEmitter } from 'react-native';

export default function App() {
  useEffect(() => {
    const config: SingularConfig = {
      apikey: 'YOUR_SDK_KEY',
      secret: 'YOUR_SDK_SECRET',
      customUserId: 'user_123456',
      limitDataSharing: false,
      waitForTrackingAuthorizationWithTimeoutInterval: 300
    };

    NativeSingular.init(config);

    // Register event listener
    const emitter = new NativeEventEmitter(NativeSingular);
    emitter.addListener('SingularLinkHandler', (params) => {
      console.log('Singular: Deep link:', params.deeplink);
      console.log('Singular: Passthrough:', params.passthrough);
      console.log('Singular: Is deferred:', params.isDeferred);
      console.log('Singular: urlParameters:', params.urlParameters);
    });

  }, []);
  
  return (
    // Your app components
  );
}

Configuration Reference: For a complete list of available configuration options, see the React Native SDK Configuration Reference.

Critical: Do NOT use the Singular Reporting API Key. Only use the SDK-specific credentials from the SDK Integration page. Using wrong credentials prevents data from reaching Singular.