The Embrace Developer Hub

Welcome to the Embrace documentation. You'll find comprehensive guides and documentation to help you start working with Embrace as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started

Integration Guide

React Native Get Started Guide

To get started with Embrace for React Native, the basic integration is four simple steps and should take less than 15 minutes. If you are in front of your computer and ready to code, please use the self-service flow. To ask us questions directly, join the Embrace Slack community.

You will need to integrate the native SDK as well as the JavaScript one. The native SDKs automatically grab information that is unavailable in the React Native layer. As such, you will be creating two separate AppIDs in Embrace - one for iOS and one for Android. The instructions below assume you will integrate both platforms though it's not a requirement if your app is only on one platform.

You can verify the integration by reviewing events as they happen in real-time. Within the Embrace dashboard, while you are still attached to the debugger, go to the Recent Sessions page on the left-hand menu. Select the Debugger tab in the upper menu. Locate and click into your session under Live Sessions. You should see your events.

To fully realize Embrace's value in (i) development and (ii) post app release, a few more features are recommended. These include integrating logs and moments, defining your customer segments, and uploading dSYMs. Please see the Recommended Configuration guide below.

Step 1: Installation of React Native via NPM or Yarn

(If you do not use npm and would like to integrate directly via JS files, please refer to the Manual Integration instructions)

Open your terminal and navigate to the root of your React Native project. Install the npm package by running the following command:

# For NPM
npm i -S react-native-embrace

# Or for Yarn
yarn add react-native-embrace

Link the native modules with your React Native application:

react-native link react-native-embrace

Step 2: Add the Native iOS and Android SDKs

Embrace collects a lot of data automatically to reduce your implementation steps. A few iOS and Android native steps are required to make the magic work correctly.

iOS Guide

The Embrace SDK is available through CocoaPods. If you do not use CocoaPods, follow the instructions on "Configuring CocoaPods dependencies".

  1. Add a single line to your Podfile.
target 'YourApp' do
   # ...
    pod 'React', :path => '../node_modules/react-native', :subspecs => [
        'Core',
        'CxxBridge',
        'DevSupport',
        'RCTText',
        'RCTNetwork',
        'RCTWebSocket',
        'RCTAnimation'
    ]

    # Add this line in the end of the target block
    pod 'EmbraceIO'
    pod 'RNEmbrace', :path => '../node_modules/react-native-embrace'
  
end
  1. Run the following command in your terminal in the ios directory:
pod install
  1. Initialize the Embrace SDK
    In the iOS project, find a file named AppDelegate.m, (which is usually located in <YourReactNativeProject>/ios/<YourAppName>/AppDelegate.m).
    Initialize the Embrace SDK as early as possible by placing the Embrace start call on the first line of your application:didFinishLaunchingWithOptions callback.
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <Embrace/Embrace.h> // Remember to add the import line

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *) launchOptions
{
    // Replace with your APP_ID, which is a 5-character value, e.g. "aBc45"
    [[Embrace sharedInstance] startWithKey:@"APP_ID" launchOptions: launchOptions framework:EMBAppFrameworkReactNative];
    return YES;
}

@end

The APP_ID is available in the dashboard or by contacting Embrace at [email protected].

Note: If you're currently using Crashlytics, you're all set! If you are not, you will need to add the Embrace-Info.plist file at /ios with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>CRASH_REPORT_ENABLED</key>
    <true/>
  </dict>
</plist>

Android Guide

  1. Add the SDK to your app by making the changes below to your project's build.gradle file. The file path is usually <YourReactNativeProject>/android/build.gradle.
buildscript {
  repositories {
    jcenter()
    google()
  }
  dependencies {
    classpath('embrace-io:embrace-swazzler:4.0.0-beta7')
  }
}
  1. Add the following to your app/build.gradle file. The file path is usually <YourReactNativeProject>/android/app/build.gradle.#
apply plugin: 'com.android.application'
apply plugin: 'embrace-swazzler'
repositories {
  jcenter()
  google()
}
embrace {
  // Replace with your APP_ID, which is a 5-character value, e.g. "aBc45" and the token
  appId = '<EMBRACE_APP_ID>'
  apiToken = '<API_TOKEN>'
}

The APP_ID and APP_TOKEN are available in the dashboard or by contacting Embrace at [email protected].

Add compilation options for older React Native versions

React Native 0.59.0 and later automatically adds the required compileOptions directive to the android/app/build.gradle file. If you are using a version of React Native older than 0.59.0, or your project was created with a version older than 0.59.0, add the following to your android/app/build.gradle file:

android {
    ....

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    ...
}

Embrace requires Android 4.1 (API 16) or later, Gradle 4.4, Android Build Tools Plugin 3.+ and Java 8. The AndroidManifest.xml should have android.permission.INTERNET and android.permission.ACCESS_NETWORK_STATE set so Embrace can send events and monitor connectivity. If you use a version older than any of those listed, please contact us via email or over Slack.

  1. Initialize the Embrace client as early as possible so we can correctly track crashes, OOMs, ANRs and terminations. In the MainApplication.java class, add the following 2 lines. (The file is usually located in <YourReactNativeProject>/android/app/src/main/java/com/<YourAppName>/MainApplication.java.)
import io.embrace.android.embracesdk.Embrace; // Add the import line

public class MainApplication extends Application implements ReactApplication {

    @Override
    public void onCreate() {
        super.onCreate();
        Embrace.getInstance().start(this, false, Embrace.AppFramework.REACT_NATIVE); // Add this line right after the super.onCreate();
    }
}
  1. Define the App Startup (optional)
    Embrace automatically detects the beginning and end of the Startup in the Native layer. However, in the rare case that you wish to manually define your startup in the Native layer, you can override it with the following:
// Add this annotation
@StartupActivity
public class MainActivity extends ReactActivity {
    ...
}

Troubleshooting Note: During the linking process, React Native will add a line to your android app/build.gradle:

...
compile project(':react-native-embrace')

The compile instruction has been deprecated, but React Native still uses compile for the Linking process. If that line causes issues, replace compile with implementation:

...
implementation project(':react-native-embrace')

Recommended Configuration

Crash Reporting

The following documentation refers to capturing JS crashes. If you are looking for native crash reporting solutions for iOS, please refer to this. On Android, we automatically capture native crashes without any additional steps. You'll need to be on the React Native SDK version 2.0.

yarn upgrade [email protected]

Initialize the Embrace SDK in the entry point of the JS app (i.e. index.js, index.ios.js, index.android.js).

import {initialize} from 'react-native-embrace'

initialize();

// You can also optionally pass in a JS patch number.
// initialize({patch: 'v1'});

Crash Symbolication without CodePush

By default, a stack trace will only show memory addresses, so it must be symbolicated to display useful information. To enable symbolication for your builds, you need to upload your sourcemaps. The following are instructions on how to upload your dSYMs without codepush. If you use CodePush, please refer to this.

For iOS

Update the "Bundle React Native code and images" step in Build Phases from this:

export NODE_BINARY=node
../node_modules/react-native/scripts/react-native-xcode.sh

to this:

export NODE_BINARY=node
export EXTRA_PACKAGER_ARGS="--sourcemap-output $CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/main.jsbundle.map"
../node_modules/react-native/scripts/react-native-xcode.sh

For Android

Add extra arguments to the bundle step in android/app/build.gradle

project.ext.react = [
    entryFile: "index.js",
    extraPackagerArgs: ["--sourcemap-output", "$buildDir/generated/sourcemaps/android-embrace.bundle.map"]
]

Note on variants

By default, source maps are uploaded only for the release variant. If you'd like to upload source maps for other variants, be sure to make the following changes:

project.ext.react = [
        ...
        bundleIn<customVariant>: true,
        devDisabledIn<customVariant>: true,
        extraPackagerArgs: ["--sourcemap-output", "$buildDir/generated/sourcemaps/android-embrace.bundle.map"]
]

This creates a bundle, and sets the debuggable flag to false.


Crash Symbolication with CodePush

To upload sourcemaps with CodePush, you will need to generate the bundle and map that will be uploaded with CodePush

appcenter codepush release-react -a MyApp --output-dir ./build --sourcemap-output ./map

If you are integrating on Android there are no further instructions. On iOS, the last step is to use the upload script that comes with the iOS SDK to upload the bundle and map to Embrace. Please note that the upload script is currently unavailable for Windows. Please contact us if you use Windows for development.

ios/Pods/EmbraceIO-EAP/upload --app <your app ID> --token <your token> --rn-bundle ./build/CodePush/main.jsbundle --rn-map ./map

Set Your User Identifiers

User lookup is a useful tool to understand and resolve problems quickly. It can help developers and QA teams debug issues during pre-release. You can also utilize user lookup to triage customer complaints post release.

Set the identifiers for your users by adding one or more of the lines below. The best practice is to set the user identifiers early in the startup and whenever a user logs in or registers.

import {
  setUserIdentifier,
  clearUserIdentifier,
  setUsername,
  clearUsername,
  setUserEmail,
  clearUserEmail
} from 'react-native-embrace';
// User Identifiers: Set (or clear) one or more User Identifiers on app start up or registration
setUserIdentifier("123");
clearUserIdentifier();

setUsername("abc");
clearUsername();

setUserEmail("[email protected]");
clearUserEmail();

Startup Performance

The Embrace SDK automatically records the Startup event with code added to AppDelegate.m on iOS or MainActivity.java on Android. Keep in mind that your Startup can end in multiple locations depending on how the user launched the app (cold start, push notification, deeplink, etc). You should end on Component mount by calling endAppStartup. Feel free to add this call as many times as you like.

import {endAppStartup} from 'react-native-embrace';

export default class App extends Component {
  componentDidMount() {
    endAppStartup();
  }
}

Logging

Log messages are best used to gain visibility into a user's session and to debug issues. Add Error, Warning, and Info log messages to provide additional context to your user timelines and to aggregate on counts of expected issues. Embrace does not limit the number of logs and does not require that you turn them off on app release.† Error logs and warning logs may include a stack trace and screenshot.

//Logs : Logs are aggregated and searchable for insights and finding specific carts, users and other properties.
import {logMessage, WARNING, ERROR} from 'react-native-embrace';

// If only a message is provided, an info message is logged.
logMessage('test info');

// The severity and properties of a log can be specified.
const properties = {foo: 'bar'};
logMessage('test warning', WARNING, properties);

// Screenshots can be enabled by setting the fourth parameter to true.
logMessage('test error', ERROR, {}, true);

Custom properties add even more context around log messages. These are simple key-value attribute pairs that are sent with the log message to provide additional visibility. Both property keys and values function as filters on the App Performance and Logging pages, and are displayed in session timelines. You are limited to 10 properties for any given log message.

For example, if your app has an add-to-cart error message, you can set properties = {item: 'widget'} to understand what item may be causing the error. Info logs can have properties = {share: 'instagram'} to track which media platform a user might have shared content to.

† Important: note that all log messages are sent with a network request immediately as they occur, and not at the end of the session. We highly recommend that you do not define your console logs (i.e. debug and verbose messages) as info logs. Instead, use Breadcrumbs.


Breadcrumbs

Other tools limit breadcrumbs via their pricing models, however, we fundamentally believe this is a mistake. Set your low-level debug and verbose messages as Breadcrumbs to provide rich context within each session on the user timeline. Unlike Error, Warning, or Info logs, Breadcrumbs are neither aggregated nor are they sent with properties or a stack trace.

Additionally, breadcrumbs are sent with the session payload and not as they occur. This allows developers to pipe their console logs to provide additional session context without inflating the overall cost of the SDK.

import {logBreadcrumb} from 'react-native-embrace';
// Breadcrumbs: Log a Breadcrumb to display these on the User Timelines
logBreadcrumb('my breadcrumb');

Views

Views are not automatically tracked within JS. Embrace auto detects those views that are native to iOS or Android, and the native views are used to correlate OOMs, ANRs and Terminations last user action, and to display the path a user took within their timelines. logScreen sets a breadcrumb in the timeline for you to retrace the users steps.

import {logScreen} from 'react-native-embrace';
// Views: Log a Screen as screens are not automatically detected when in JS
logScreen('MyScreen');

Performance Monitoring ("Moments")

App Moments identify and measure the time to completion of key locations and flows in your app. Conceptually, this is like a stopwatch. SLAs, KPIs, and key experiences are often best measured with Moments. Examples include the time it takes for startups to complete or the time it takes to complete a purchase after a "confirm purchase" button is pressed.

Embrace measures time distributions (durations) and incomplete rates. Incomplete rates fall into three categories:

  1. Abandonment Rates - when a user leaves before the predefined 5s threshold
  2. Stall Rates - when a user leaves after 5s
  3. Crash Rates - when a user crashes or OOMs during the moment.

When defining the start and end(s) of the moment, keep in mind that a moment can have multiple endings (feel free to end it as many times as you like). Similar to log data, moment data is sent immediately when it occurs. We also support adding custom properties to moments with the same 10 property limit as log properties. Pass custom properties to the start and/or end of a moment.

import {
  startMoment,
  startMomentAllowingScreenshot,
  endMoment
} from 'react-native-embrace';

// Moments : Start and End a Moment.  
// For ex, a purchase is from click-to-purchase to both success or failure
// For more information on Moments, please refer to the docs in the links below

const name = 'myMoment';
const id = 'myMomentID';
const takeScreenshot = true;
const properties = {foo: 'bar'};

// Start a moment with a name.
startMoment(name); 

// Start a moment with a name and an ID.
startMoment(name, id); 

// Start a moment with properties.
startMoment(name, id, properties);

// Start a moment and take a screenshot.
startMomentAllowingScreensho('myMoment', takeScreenshot, id, properties);

// Close out the moment.
endMoment(name, id)

User Segments ("Personas")

Many mobile teams track users in pre-defined segments or cohorts. Often these segments, like payers or heavy bidders, have specific usage patterns with errors that are not detectable or otherwise hidden when aggregated with all other users. Set and clear Personas as soon as you know when a user belongs to or leaves a specific segment. Please refer to the docs (Personas on iOS | Personas on Android) for categories available to set on a user.

import {setUserPersona, clearUserPersona} from 'react-native-embrace';
// Personas : Include a user in a segment
// User personas are of specific types. For more info, please refer to the docs 
setUserPersona('vip');

clearUserPersona('vip');

Updated 2 days ago

Integration Guide


React Native Get Started Guide

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.