React Native (Bridge) (20.04)

Follow

This documentation applies to the version 20.4.

React Native Bridge is a successor to the React Native SDK

The React Native SDK, which was developed earlier, will soon be end-of-life and will no longer be maintained. Please use this (bridge) SDK for a more complete and more tested version.

This is the Countly SDK for React Native applications. It features bridging, meaning it includes all the functionalities that Android and iOS SDKs provide rather than having those functionalities as React Native code.

Creating a new application

In order to use the React Native SDK, please use the following commands to create a new React Native application.

npm install -g react-native-cli     # Install React Native
react-native init AwesomeProject    # Create a new project

cd AwesomeProject                   # Go to that directory
react-native run-android # OR       # Run the android project
react-native run-ios                # Run the iOS project

# New terminal
adb reverse tcp:8081 tcp:8081       # Link Android port
npm start                           # Run the build server

Installing the Countly SDK

Run the following snippet in the root directory of your React Native project to install the npm dependencies and link native libraries.

# Include the Countly Class in the file that you want to use.
npm install --save https://github.com/Countly/countly-sdk-react-native-bridge.git
# OR
npm install --save countly-sdk-react-native-bridge@19.8.5

# Linking the library to your app

# react-native < 0.60. For both Android and iOS
react-native link countly-sdk-react-native-bridge
cd node_modules/countly-sdk-react-native-bridge/ios/
pod install
cd ../../../

# react-native >= 0.60 for iOS (Android will autolink)
cd ios
pod install
cd ..

Implementation

We will need to call two methods (init and start) in order to set up our SDK. You may also like to specify other parameters at this step (i.e. whether logging will be used). These methods should only be called once during the app's lifecycle and should be done as early as possible. Your main App component's componentDidMountmethod may be a good place. 

See the serverURL value in the code snippet below. If you are using Countly Enterprise trial servers, use https://try.count.ly, https://us-try.count.ly or https://asia-try.count.ly. In other words, use the domain from which you are accessing your trial dashboard.

If you use both Countly Lite and Countly Enterprise, use your own domain name or IP address, such as https://example.com or https://IP (if SSL is setup).

import Countly from 'countly-sdk-react-native-bridge';

// initialize // modify serverURL to your own. var serverURL = "https://mycompany.count.ly"; var appKey = "f0b2ac6919f718a13821575db28c0e2971e05ec5"; var deviceId = null; // or use some string that identifies current app user Countly.init(serverURL, appKey, deviceId); // configure other Countly parameters if needed Countly.enableParameterTamperingProtection("salt");
Countly.enableLogging(); ...

// start session tracking
Countly.start();

After init and start have been called once, you may use the commands in the rest of this document to send additional data and metrics to your server. 

User Location

Countly allows you to send GeoLocation-based push notifications to your users. By default, the Countly Server uses the GeoIP database to deduce a user's location. However, if your app has a better way of detecting location, you may send this information to the Countly Server by using the setLocationInit orsetLocation method.

Minimum Countly SDK Version

setLocationInit feature is only supported by the minimum SDK version 20.04.7.

Recommended using setLocationInit method before initialization to sent location. This include:

  • countryCode a string in ISO 3166-1 alpha-2 format country code
  • city a string specifying city name
  • location a string comma separated latitude and longitude
  • IP a string specifying an IP address in IPv4 or IPv6 format
var countryCode = "us"; 
var city = "Houston";
var latitude = "29.634933";
var longitude = "-95.220255";
var ipAddress = "103.238.105.167";

Countly.setLocationInit(countryCode, city, latitude + "," + longitude, ipAddress);

GeoLocation info recording methods may also be called at any time after the Countly SDK has started.
Use this setLocation method 

var countryCode = "us"; 
var city = "Houston";
var latitude = "29.634933";
var longitude = "-95.220255";
var ipAddress = "103.238.105.167";

Countly.setLocation(countryCode, city, latitude + "," + longitude, ipAddress);

The following will erase any cached location data from the device and stop further location tracking.

If, after disabling location, the setLocationis called with any non-null value, tracking will resume.

//disable location tracking
Countly.disableLocation();

Custom events

You will find a quick summary on how to use custom events recording methods and what information they provide located below. For more information about how custom events and segmentations work, review this guide first.

Note that all data passed to the Countly instance via the SDK or API should be in UTF-8.

// Example for sending basic custom event
var event = {"eventName":"basic_event","eventCount":1};
Countly.sendEvent(event);

// Example for event with sum
var event = {"eventName":"Event With Sum","eventCount":1,"eventSum":"0.99"};
Countly.sendEvent(event);

// Example for event with segment
var event = {"eventName":"Event With Segment","eventCount":1};
event.segments = {"Country" : "Germany", "Age" : "28"};
Countly.sendEvent(event);

// Example for event with segment and sum
var event = {"eventName":"Event With Sum And Segment","eventCount":1,"eventSum":"0.99"};
event.segments = {"Country" : "Germany", "Age" : "28"};
Countly.sendEvent(event);

// Timed events
// Basic timed event
Countly.startEvent("timedEvent");
Countly.endEvent("timedEvent");

// Timed event with a sum
Countly.startEvent("timedEvent");
var event = {
  "eventName": "timedEvent",
  "eventSum": "0.99"
};
Countly.endEvent(event);

// Timed event with segment
Countly.startEvent("timedEvent");
var event = {
  "eventName": "timedEvent"
};
event.segments = {
  "Country": "Germany",
  "Age": "28"
};
Countly.endEvent(event);

// Timed event with segment, sum and count
Countly.startEvent("timedEvent");
var event = {
  "eventName": "timedEvent",
  "eventCount": 1,
  "eventSum": "0.99"
};
event.segments = {
  "Country": "Germany",
  "Age": "28"
};
Countly.endEvent(event);

User Profiles

If you have any details about the user/visitor, you may provide Countly with that information. This will allow you to track each specific user on the "User Profiles" tab, which is available with Countly Enterprise.

In order to set a user profile, use the code snippet below. After you send a user’s data, it may be viewed under Dashboard > User Profiles.

// Example for setting user data
var options = {};
options.name = "Nicola Tesla";
options.username = "nicola";
options.email = "info@nicola.tesla";
options.organization = "Trust Electric Ltd";
options.phone = "+90 822 140 2546";
options.picture = "http://www.trust.electric/images/people/nicola.png";
options.picturePath = "";
options.gender = "M";
options.byear = 1919;
Countly.setUserData(options);

Countly also supports custom user properties where you can attach custom data for each user. In order to set or modify a user's data (e.g., increment, multiply, etc.), the following code sample may be used.

// examples for custom user properties
Countly.userData.setProperty("keyName", "keyValue"); //set custom property
Countly.userData.setOnce("keyName", 200); //set custom property only if property does not exist
Countly.userData.increment("keyName"); //increment value in key by one
Countly.userData.incrementBy("keyName", 10); //increment value in key by provided value
Countly.userData.multiply("keyName", 20); //multiply value in key by provided value
Countly.userData.saveMax("keyName", 100); //save max value between current and provided
Countly.userData.saveMin("keyName", 50); //save min value between current and provided
Countly.userData.setOnce("setOnce", 200);//insert value to array of unique values
Countly.userData.pushUniqueValue("type", "morning");//insert value to array of unique values
Countly.userData.pushValue("type", "morning");//insert value to array which can have duplicates
Countly.userData.pullValue("type", "morning");//remove value from array

Crash reporting

With this feature, the Countly SDK will generate a crash report if your application crashes due to an exception and send it to the Countly server for further inspection.

If a crash report cannot be delivered to the server (e.g., no internet connection, unavailable server), then the SDK stores the crash report locally in order to try again at a later time.

You will need to call the following method before calling init in order to activate automatic crash reporting.

// Using countly crash reports
Countly.enableCrashReporting();
Countly.init(...);

You may also add breadcrumb crash logs to your crash report using addCrashLog and catch and send exceptions manually yourself using logException. Please review the example code below:

Countly.addCrashLog("User Performed Step A");
setTimeout(() => { Countly.addCrashLog("User Performed Step B");}, 1000);
setTimeout(() => { Countly.addCrashLog("User Performed Step C");}, 1500);
setTimeout(() => {
   try {
     var a = {};
     var x = a.b.c; // this will throw an error.
   } catch (exc) {   
     var stack = exc.stack.toString();
     const customSegments = {"external_lib_version": "4.2.7", "theme": "dark"};
     const nonfatal = true;
     Countly.logException(stack, nonfatal, customSegments);
   }
},2000);

logExceptiontakes a string for the stack trace, a boolean flag indicating if the crash is considered fatal or not, and a segments dictionary to add additional data to your crash report.

View tracking

You may manually add your own views in your application, and each view will be visible under Analytics > Views. Below you may see two examples of sending a view using the Countly.recordview function.

// record a view on your application
Countly.recordView("My Home Page");
Countly.recordView("Profile Page");

While tracking views, you may want to add custom segmentation to them.

// record view with segments
Countly.recordView("View with Segment", {"version": "1.0", "_facebook_version": "0.0.1"})

Application Performance Monitoring

Minimum Countly SDK Version

This feature is only supported by the minimum SDK version 20.04.7.

Performance Monitoring feature allows you to analyze your application's performance on various aspects. For more details please see Performance Monitoring documentation.

Here is how you can utilize Performance Monitoring feature in your apps:

First, you need to enable Performance Monitoring feature::

Countly.enableApm(); // Enable APM features.

With this, Countly SDK will start measuring some performance traces automatically. Those include app foreground time, app background time. Additionally, custom traces and network traces can be manually recorded.

Custom trace

You may also measure any operation you want and record it using custom traces. First, you need to start a trace by using the startTrace(traceKey) method:

Countly.startTrace(traceKey);

Then you may end it using the endTrace(traceKey, customMetric)method, optionally passing any metrics as key-value pairs:

String traceKey = "Trace Key";
Map<String, int> customMetric = {
"ABC": 1233,
"C44C": 1337
};
Countly.endTrace(traceKey, customMetric);

The duration of the custom trace will be automatically calculated on ending. Trace names should be non-zero length valid strings. Trying to start a custom trace with the already started name will have no effect. Trying to end a custom trace with already ended (or not yet started) name will have no effect.

You may also cancel any custom trace you started, using cancelTrace(traceKey)method:

Countly.cancelTrace(traceKey);

Additionally, if you need you may cancel all custom traces you started, using clearAllTraces()method:

Countly.clearAllTraces(traceKey);

Network trace

You may record manual network traces using therecordNetworkTrace(networkTraceKey, responseCode, requestPayloadSize, responsePayloadSize, startTime, endTime) method.

A network trace is a collection of measured information about a network request.
When a network request is completed, a network trace can be recorded manually to be analyzed in the Performance Monitoring feature later with the following parameters: 

- networkTraceKey: A non-zero length valid string
- responseCode: HTTP status code of the received response
- requestPayloadSize: Size of the request's payload in bytes
- responsePayloadSize: Size of the received response's payload in bytes
- startTime: UNIX time stamp in milliseconds for the starting time of the request
- endTime: UNIX time stamp in milliseconds for the ending time of the request

Countly.recordNetworkTrace(networkTraceKey, responseCode, requestPayloadSize, responsePayloadSize, startTime, endTime);

Remote Config

Remote config allows you to modify how your app functions or looks by requesting key-value pairs from your Countly server. The returned values may be modified based on the user profile. For more details, please review this  Remote Config documentation.

// remoteConfigUpdate will update all remote config values
Countly.remoteConfigUpdate(function(data){ 
	console.log(data);
});

// updateRemoteConfigForKeysOnly will update only those values which keyname are pass in array
Countly.updateRemoteConfigForKeysOnly(["test1"],function(data){
	console.log(data);
});

// updateRemoteConfigExceptKeys will update only values except which keyname are pass in array
Countly.updateRemoteConfigExceptKeys(["test1"],function(data){
	console.log(data);
});
      
// getRemoteConfigValueForKey will fetch remote config values for keyname sent
Countly.getRemoteConfigValueForKey("test1",function(data){
	console.log(data);
});

Clearing Stored Remote Config values

At some point, you might want to erase all the values downloaded from the server. To do so, you will need to call the following function:

Countly.remoteConfigClearValues();

User Consent management

In an effort to be compliant with GDPR and other data privacy regulations, Countly provides ways to toggle different Countly tracking features on/off depending on a user's given consent. To learn more about how Countly manages this issue and what capabilities we provide to our customers, please visit our guide on the Compliance Hub plugin. You may also find more information about how Countly helps organizations with GDPR regulations in this Countly blog post.

Currently, available features with consent control are as follows:

  • sessions - tracking when, how often and how long users use your app
  • events - allow sending custom events to the server
  • views - allow tracking which views user visits
  • location - allow sending location information
  • crashes - allow tracking crashes, exceptions and errors
  • attribution - allow tracking from which campaign did user come
  • users - allow collecting/providing user information, including custom properties
  • push - allow push notifications
  • star-rating - allow sending their rating and feedback
  • apm - allow application performance monitoring

Since the React Native Bridge SDK employs our IOS and Android SDKs, you may also be interested in reviewing their relevant documentation on this topic (here and here, respectively).

Next we will go over the methods that are available in this SDK.

Method Parameters / Examples Description
setRequiresConsent boolean

The requirement for checking consent is disabled by default. To enable it, you will have to call setRequiresConsentwith truebefore initializing Countly. You may also pass a consent flag as true/false when you call the Countly.init.

giveConsentInit string array of strings

To add consent for a single feature (string parameter) or a subset of features (array of strings parameter). Use this method for giving consent before initializing.

This feature is only supported by the minimum SDK version 20.04.7.

giveConsent string array of strings

To add consent for a single feature (string parameter) or a subset of features (array of strings parameter). Use this method if want to give consent after initializing. 

removeConsent string array of strings

To remove consent for a single feature (string parameter) or a subset of features (array of strings parameter).

giveAllConsent none To give consent for all available features.
removeAllConsent none To remove consent for all available features.
// Usage examples

Countly.setRequiresConsent(true);

// for a single feature
Countly.giveConsentInit("events");
Countly.giveConsent("events");
Countly.removeConsent("events");

// for a subset of features
Countly.giveConsentInit(["events", "views", "star-rating", "crashes"]);
Countly.giveConsent(["events", "views", "star-rating", "crashes"]);
Countly.removeConsent(["events", "views", "star-rating", "crashes"]);

// for all available features
Countly.giveAllConsent();
Countly.removeAllConsent();

The string values corresponding to the features that will be used in the giveConsent or removeConsentmethods may be found here. In addition, please review our platform SDK documents if the feature is applicable or not for that platform.

Device ID

When the SDK is initialized for the first time and no device ID is provided, a device ID will be generated by SDK.

For iOS: the device ID generated by SDK is the Identifier For Vendor (IDFV)
For Android:  the device ID generated by SDK is the OpenUDID or Google Advertising ID

You may provide your own custom device ID when initializing the SDK

Countly.init(SERVER_URL, APP_KEY, DEVICE_ID)

Changing the Device ID

You may configure/change the device ID anytime using:

Countly.changeDeviceId(DEVICE_ID, ON_SERVER);

You may either allow the device to be counted as a new device or merge existing data on the server. If theonServer bool is set to true, the old device ID on the server will be replaced with the new one, and data associated with the old device ID will be merged automatically.
Otherwise, if onServer bool is set to false, the device will be counted as a new device on the server.

Temporary Device ID

You may use a temporary device ID mode for keeping all requests on hold until the real device ID is set later. 

You can enable temporary device ID when initializing the SDK:

Countly.init(SERVER_URL, APP_KEY, "TemporaryDeviceID")

To enable a temporary device ID after init, you would call:

Countly.changeDeviceId("TemporaryDeviceID", ON_SERVER);

 Note: When passing TemporaryDeviceID for deviceID parameter, argument for onServerparameter does not matter.

As long as the device ID value is TemporaryDeviceID, the SDK will be in temporary device ID mode and all requests will be on hold, but they will be persistently stored.

When in temporary device ID mode, method calls for presenting feedback widgets and updating remote config will be ignored.

Later, when the real device ID is set using Countly.changeDeviceId(DEVICE_ID, ON_SERVER); method, all requests which have been kept on hold until that point will start with the real device ID

Enabling/disabling logging

If logging is enabled, our SDK will then print out debug messages regarding its internal state and problems encountered. Logging is disabled by default. Enabling it during development is also advised. Enabling it before init is recommended so you may see the initialization process logs.

Countly.enableLogging();
Countly.init(...); ...
// to disable it again later Countly.disableLogging();

Forcing HTTP POST

If the data sent to the server is short enough, the SDK will use HTTP GET requests. In the event you would like an override so that HTTP POST may be used in all cases, call the "setHttpPostForced" function after you have called "init". You may use the same function later in the app’s life cycle to disable the override. This function has to be called every time the app starts.

  
// enabling the override
Countly.setHttpPostForced(true);
  
// disabling the override
Countly.setHttpPostForced(false);

Checking if init has been called

You may use the following function in the event you would like to check if init has been called:

Countly.isInitialized().then(result => console.log(result)); // true or false

Checking if onStart has been called

For some Android applications there might be a use case where the developer would like to check if the Countly SDK onStart function has been called. To do so, they may use the following call:

Countly.hasBeenCalledOnStart().then(result => console.log(result)); // true or false 

Rich Push Notifications

Please first check our Push Notifications Guide to see how you can use this feature. Since Android and IOS handles notifications differently (from how you can send them externally to how they are handled in native code), we need to provide different instructions for these two platforms.

Android Setup and Usage of Push Notifications

The following setup code is required starting from version 20.4.5. 

  1. First thing you need to do is a FCM id and a google-services.json file. You would input that FCM id into your apps configuration in your countly dashboard. You also need to copy your google-services.json file to your android apps directory, which most likely is in "./android/app".
  2. You need to add firebase dependencies to your android apps gradle file, which most likely is located in "./android/app/build.gradle", so start by opening that file.
  3. Inside the dependency section add  the "firebase-messaging" dependency with a call similar to "implementation 'com.google.firebase:firebase-messaging:20.1.7'"
  4. At the bottom of your gradle file add this line "apply plugin: 'com.google.gms.google-services'"
  5. Open you android projects gradle file, which most likely is located in "./android/build.gradle"
  6. Add the following call in the dependency section "classpath 'com.google.gms:google-services:3.2.0'"

JS Push Method Implementation

First, when setting up push for the React Native SDK, you would first select the push token mode. This would allow you to choose either test or production modes, push token mode should be set before init.

// Important call this method before init method
Countly.pushTokenType(Countly.messagingMode.DEVELOPMENT, "Channel Name", "Channel Description");
// Countly.messagingMode.DEVELOPMENT
// Countly.messagingMode.PRODUCTION
// Countly.messagingMode.ADHOC

When you are finally ready to initialise Countly push, you would call Countly.askForNotificationPermission(), this function should be call after init.

// Call this method any time.
Countly.askForNotificationPermission();
// This method will ask for permission,
// and send push token to countly server.

React Native JS code to receive notification data. Call anywhere or event before init.

Countly.registerForNotification(function(theNotification){
console.log(JSON.stringify(theNotification));
});

iOS Push Notification Documentation

Note: This documentation assumes, that you have created the necessary certificate and you have proper app bundle id.

STEP 1: Make sure you have proper app bundle id and team selected.

STEP 2: Add Capabilities
             1. Push Notification
             2. Background Mode - Remote Notifications
             Go into your AwesomeProject/ios dir and open AwesomeProject.xcworkspace workspace.              Select the top project “AwesomeProject” and select the “Signing & Capabilities” tab. Add 2 new Capabilities using “+” button:
             Background Mode capability and tick Remote Notifications.
             Push Notifications capability

Screenshot_2020-05-05_at_1.43.11_PM.png

Screenshot_2020-05-05_at_1.43.21_PM.png

Screenshot_2020-05-05_at_1.43.36_PM.png

Screenshot_2020-05-05_at_1.43.49_PM.png

STEP 3: Place below code in there respective files.

### AppDelegate.m

Add header file
`#import "CountlyReactNative.h"`
`#import <UserNotifications/UserNotifications.h>`


Before `@end` add these methods:

  -(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse
  *)response withCompletionHandler:(void (^)(void))completionHandler{
   NSLog(@"didReceiveNotificationResponse");
   NSDictionary *notification = response.notification.request.content.userInfo;
   [CountlyReactNative onNotification: notification];
   completionHandler();
} //Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
    NSLog(@"didReceiveNotificationResponse");
   NSDictionary *userInfo = notification.request.content.userInfo;
   [CountlyReactNative onNotification: userInfo];
   completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}

Rich Push Notification

STEP 1: Creating Notification Service Extension
             Editor -> Add Target ->
             Make sure ios is selected
             Make sure Notification Service Extension is selected
             Click Next
             Enter Product Name e.g. CountlyNSE
             Language Objective-C
             Click Finish
             It will ask for a modal / popup Activate “CountlyNSE” scheme?
             Choose Cancel

b0b0f12-f62249f-screen-1.png

04c2353-17d2fec-screen-2.png

STEP 2: Adding Compile Source
              Under TARGETS select CountlyNSE
             Select Build Phases
             Expand Compile Sources
             Drag and Drop CountlyNotificationService.h and CountlyNotificationService.m file
             Note: Make sure you have checked "Copy if necessary"
             Note: You may also find this file in Xcode under Pods(Project) -> Pods(Folder) -> Countly
             Note: You may also find this file in Finder under AwesomeProject/ios/Pods/Countly
             Note: You may also find this file in Xcode under AwesomeProject(Project) -> Libraries(Folder) -> countly-sdk-react-native-bridge(Project)->src(Folder)
             Note: You may also find this file in Finder under node_modules/countly-sdk-react-native-bridge/ios/Pods/Countly

Screenshot_2020-05-05_at_1.44.05_PM.png

 

STEP 3: Updating NotificationService file
              Under AwesomeProject(Project) -> CountlyNSE(Folder) -> NotificationService.m
             Add import header #import "CountlyNotificationService.h"
             Add the following line at the end of didReceiveNotificationRequest:withContentHandler:

    - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler
    {
        self.contentHandler = contentHandler;
        self.bestAttemptContent = [request.content mutableCopy];    
        //delete existing template code, and add this line
        [CountlyNotificationService didReceiveNotificationRequest:request withContentHandler:contentHandler];
    }
    

    Note: Please make sure you configure App Transport Security setting in extension's Info.plist file also, just like the main application. Otherwise media attachments from non-https sources can not be loaded.
    
    Note: Please make sure you check Deployment Target version of extension target is 10, not 10.3 (or whatever minor version Xcode set automatically). Otherwise users running iOS versions lower than Deployment Target value can not get rich push notifications.

    Note: To send push messages to applications that are Debug build use Countly.messagingMode.DEVELOPMENT, for App Store built ones use Countly.messagingMode.PRODUCTION, and for TestFlight/Ad Hoc builds use Countly.messagingMode.ADHOC.    

Attribution analytics & install campaigns 

Minimum Countly SDK Version

This feature is only supported by the minimum SDK version 20.04.6.

Countly Attribution Analytics allows you to measure your marketing campaign performance by attributing installs from specific campaigns. This feature is available for Countly Enterprise.

Call this before init.

// Enable to measure your marketing campaign performance by attributing installs from specific campaigns.
Countly.enableAttribution();

Minimum Countly SDK Version

This feature is only supported by the minimum SDK version 20.04.8.

From version 20.04.8+ for iOS use Countly.recordAttributionID("IDFA") function instead of Countly.enableAttribution()

You can use Countly.recordAttributionID function to specify IDFA for campaign attribution

Countly.recordAttributionID("IDFA_VALUE_YOU_GET_FROM_THE_SYSTEM");

For iOS 14+ apple changes regarding Application tracking, you need to ask the user for permission to track Application.

For IDFA you can use this plugin, this plugin also supports iOS 14+ changes for Application tracking permission:
https://github.com/ijunaid/react-native-advertising-id.git

Here is how to use this plugin with Countly attribution feature:

npm install --save https://github.com/ijunaid/react-native-advertising-id.git

cd ./ios
pod install

NSUserTrackingUsageDescription
Add "Privacy - Tracking Usage Description" in your ios info.plist file.

#Example Code for Countly attribution feature to support iOS 14+.

import RNAdvertisingId from 'react-native-advertising-id';

if (Platform.OS.match("ios")) {
RNAdvertisingId.getAdvertisingId()
.then(response => {
Countly.recordAttributionID(response.advertisingId);
})
.catch(error => console.error(error));
}
else {
Countly.enableAttribution(); // Enable to measure your marketing campaign performance by attributing installs from specific campaigns.
}

Getting user feedback

There are two ways of getting feedback from your users: Star-rating dialog and the feedback widget.

Star-rating dialog allows users to give feedback as a rating from 1 through 5. The feedback widget allows you to receive the same 1 through 5 rating and also a text comment.

Feedback widget

The feedback widget displays a server configured widget to your user devices.

It's possible to configure any of the shown text fields and replace them with a custom string of your choice.

In addition to a 1 through 5 rating, it is possible for users to leave a text comment and an email, should the user like to be contacted by the app developer.

Trying to show the rating widget is a single call,  however, there is a two-set process underneath. Before it is shown, the SDK tries to contact the server to get more information about the dialog. Therefore, a network connection to it is needed.

You may try to display the widget after you have initialized the SDK. To do so, you will first need to get the widget ID from your server:

You may call the function to show the widget popup using the widget ID:

Countly.showFeedbackPopup("WidgetId", "Button Text");

Star-rating dialog

Star-rating integration provides a dialog for getting users’ feedback about the application. It contains a title, a simple message explaining its purpose, a 1 through 5-star meter for getting users rating, and a dismiss button in case the user does not want to give a rating.

This star rating has nothing to do with Google Play Store ratings and reviews. It is simply for getting a brief feedback from your users to be displayed on the Countly dashboard. If the user dismisses the star-rating dialog without giving a rating, the event will not be recorded.

Countly.showStarRating();

Native C++ Crash Reporting

If you have some C++ libraries in your Android app, the React Native Bridge SDK allows you to record possible crashes in your Countly server by integrating the sdk-nativedeveloped within our Android SDK. You may receive more information on how this works here.

As this feature is optional, you will need to uncomment some parts in our SDK files in order to make it available. First, go to android/build.gradleand add the package dependency (all file paths in this section are given relative to the countly-sdk-react-native-bridgewhich was npminstalled above):

dependencies {
    implementation 'ly.count.android:sdk-native:19.02.3'    
}

Next, uncomment the following in the android/src/main/java/ly/count/android/sdk/react/CountlyReactNative.javafile:

import ly.count.android.sdknative.CountlyNative;
    
@ReactMethod
  public void initNative(){
  CountlyNative.initNative(getReactApplicationContext());
}
	
@ReactMethod
  public void testCrash(){
  CountlyNative.crash();
}
    

Now modify Countly.jsto connect from JS to these new methods:

Countly.initNative = function(){
    CountlyReactNative.initNative();
}

Countly.testCrash = function(){
    CountlyReactNative.testCrash();
}

If you are using our sample app in example/App.js, you may also uncomment the following parts in it for easy testing:

initNative(){
  Countly.initNative();
};

testCrash(){
  Countly.testCrash();
}

// ...

            < Button onPress = { this.initNative } title = "Init Native" color = "#00b5ad"> 
            < Button onPress = { this.testCrash } title = "Test Native Crash" color = "crimson"> 

We suggest calling Countly.initNative(); as soon as your app is initialized to be able to catch setup time crashes. Sending crash dump files to the server will be taken care of by the Android SDK during the next app initialization. We also provide a gradle plugin which automatically uploads symbol files to your server (these are needed for the symbolication of crash dumps). You may integrate it to your React Native project as explained in the relevant Android documentation page.

This is what the debug logs will look like if you are going to use this feature:

$ adb logcat -s Countly:V countly_breakpad_cpp:V

# when Countly.initNative() is called 

D/countly_breakpad_cpp(123): breakpad initialize succeeded. dump files will be saved at /Countly/CrashDumps

# when a crash occurs (you may trigger one by Countly.testCrash())

D/countly_breakpad_cpp(123): DumpCallback started
D/countly_breakpad_cpp(123): DumpCallback ==> succeeded path=/Countly/CrashDumps/30f6d9b8-b3b2-1553-2efe0ba2-36588990.dmp

# when app is run again after the crash 

D/Countly (124): Initializing...
D/Countly (124): Checking for native crash dumps
D/Countly (124): Native crash folder exists, checking for dumps
D/Countly (124): Crash dump folder contains [1] files
D/Countly (124): Recording native crash dump: [30f6d9b8-b3b2-1553-2efe0ba2-36588990.dmp]

Pinned Certificate (Call this method before init)

Terminal

openssl s_client -connect try.count.ly:443 -showcerts

Run the above command and copy the content inside begin certificate and end certificate.

Example files are here:
https://github.com/Countly/countly-sdk-react-native-bridge/blob/master/example/android.count.ly.cer
https://github.com/Countly/countly-sdk-react-native-bridge/blob/master/example/ios.count.ly.cer

Both files are different, android only needs the cert string, iOS needs the entire .cer file.

Android

cd AwesomeProject
ls
count.ly.cer
mkdir -p ./android/app/src/main/assets/
cp ./count.ly.cer ./android/app/src/main/assets/

iOS

open ./ios/AwesomeProject.xcworkspace
Right click on AwesomeProject and select `New Group` (ScreenShot 1)
Name it `Resources`
Drag and Drop count.ly.cer file under that folder (ScreenShot 2)
Make sure copy bundle resources has your certificate (Screenshot 4).

Screenshot_2020-07-07_at_11.39.02_AM.png
ScreenShot_Pinned_Certificate_1.png

Screenshot_Pinned_Certificate_2.png

Screenshot_2020-07-07_at_11.39.40_AM.png

JS

Countly.pinnedCertificates("count.ly.cer");

Note: "count.ly.cer" is the name of the file. Replace this file with the one you have.

Looking for help?