UNPKG

react-native-flurry-sdk

Version:
506 lines (390 loc) 21 kB
# React Native Flurry SDK (react-native-flurry-sdk) [![npm](https://img.shields.io/npm/v/react-native-flurry-sdk.svg?colorB=blue&)](https://www.npmjs.com/package/react-native-flurry-sdk) ![platform](https://img.shields.io/badge/platform-android%20%7C%20ios%20%7C%20tvos-lightgrey) [![licence](https://img.shields.io/npm/l/react-native-flurry-sdk.svg?colorB=orange)](https://www.npmjs.com/package/react-native-flurry-sdk) A React Native plugin for Flurry SDK - **Tutorial and sample project** are now available at [https://github.com/flurry/React-Native-Tutorial](https://github.com/flurry/React-Native-Tutorial). - **Flurry Push** for messaging and **Flurry Config** for remote configuration are now supported by our plugin! - If you are using Apple Xcode < 12, please use release [v6.3.0](https://www.npmjs.com/package/react-native-flurry-sdk/v/6.3.0). - If you are using React Native < 0.60, please use release [v6.0.9](https://www.npmjs.com/package/react-native-flurry-sdk/v/6.0.9). ## Table of contents - [Installation](#installation) - [Android](#android) - [iOS](#ios) - [tvOS](#tvos) - [Example](#example) - [API Reference](#api-reference) - [Support](#support) - [License](#license) ## Installation 1. Install Flurry SDK module by `npm` ```bash npm install react-native-flurry-sdk --save ``` 2. If you are using React Native >= 0.60, install CocoaPods dependency ```bash cd ios && pod install && cd .. ``` If you are using React Native < 0.60, link React Native dependency ```bash react-native link react-native-flurry-sdk ``` 3. Add Flurry JS code ```javascript import Flurry from 'react-native-flurry-sdk'; ``` ### Android - By default, Flurry adds `INTERNET` and `ACCESS_NETWORK_STATE` permissions to optimize analytics data. Please see [Manual Flurry Android SDK Integration](https://developer.yahoo.com/flurry/docs/integrateflurry/android-manual/) for the other recommended options. - To improve analytics identities, please see [Manual Flurry Android SDK Integration](https://developer.yahoo.com/flurry/docs/integrateflurry/android-manual/) for adding Google Play Services library in your app by including the following in your `build.gradle` file: ```groovy dependencies { // Recommended to add Google Play Services implementation 'com.google.android.gms:play-services-ads-identifier:17.1.0' } ``` - **Flurry Push**</br> In order to use [Flurry Push](https://developer.yahoo.com/flurry/docs/push/) for [Android](https://developer.yahoo.com/flurry/docs/push/integration/android/), please follow the additional steps below: 1. Follow [Set up a Firebase Cloud Messaging client app on Android](https://firebase.google.com/docs/cloud-messaging/android/client). Complete "Set up Firebase and the FCM SDK" step for adding Firebase to your Android project. There should be a file `google-services.json` in your project's `android/app` folder now. You do not need to provide any setup codes here. Your `build.gradle` will look like: ```groovy // android/build.gradle (project-level) buildscript { dependencies { classpath 'com.google.gms:google-services:4.3.10' } } ``` ```groovy // android/app/build.gradle (app-level) apply plugin: 'com.google.gms.google-services' dependencies { implementation 'com.google.firebase:firebase-messaging:21.1.0' } ``` 2. If you want to customize Flurry Push notification, please do the Flurry setup in `MainApplication.onCreate()`. With the same APIs as the JavaScript version. ```java import com.flurry.android.reactnative.FlurryModule; public class MainApplication extends Application implements ReactApplication { @Override public void onCreate() { super.onCreate(); new FlurryModule.Builder() .withCrashReporting(true) .withLogEnabled(true) .withLogLevel(Log.VERBOSE) .withReportLocation(true) .withMessaging(true, options_or_listener) // optional user's native `FlurryMarketingOptions` or `FlurryMessagingListener`. .build(this, FLURRY_ANDROID_API_KEY); ``` 3. Add notification permission in the Android manifest file. (required on the Android 13 and above devices.) ```xml <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> ``` 4. Set up "Android Authorization" in Flurry [Push Authorization](https://developer.yahoo.com/flurry/docs/push/authorization/). ### iOS - Please note that starting from [React Native 0.60](https://facebook.github.io/react-native/blog/2019/07/03/version-60), [CocoaPods](https://cocoapods.org) is now the default integration approach for React Native iOS projects. If you are not using CocoaPods, please stick to `react-native-flurry-sdk@6.0.9`. - **Flurry Push**</br> To set up Flurry Push, please take the following steps. 1. Open your Podfile, which is located under the `ios` folder of your project. 2. Add the following line in your target section before `use_native_modules!` ```ruby pod 'react-native-flurry-sdk', :path => '../node_modules/react-native-flurry-sdk/ios', :subspecs => ['FlurrySDK-Push'] ``` Your target section of Podfile should now look like this: ```ruby target 'YourTarget' do # Pods for your target pod 'React', :path => '../node_modules/react-native/' pod 'React-Core', :path => '../node_modules/react-native/React' # ... other React dependencies # Add react-native-flurry-sdk pod 'react-native-flurry-sdk', :path => '../node_modules/react-native-flurry-sdk/ios', :subspecs => ['FlurrySDK-Push'] # ... other targets target 'YourTargetTests' do # ... end use_native_modules! end ``` 3. Install the dependencies again by executing ```bash cd ios && pod install && cd .. ``` 4. Open your `.xcworkspace` file which is under the `ios` folder. Go to "Capabilities" tab and enable Push Notifications. ![push_ios_1](images/push_ios_1.png) 5. Enable Background Modes (Background Fetch and Remote Notifications turned on). ![push_ios_2](images/push_ios_2.png) Now your `Info.plist` should contain the following items. For more information, please see [Push Setup](https://developer.yahoo.com/flurry/docs/push/integration/ios/). ![push_ios_3](images/push_ios_3.png) 6. Set up "iOS Authorization" in Flurry [Push Authorization](https://developer.yahoo.com/flurry/docs/push/authorization/). 7. In order to handle notifications from a cold start, Flurry Push requires to be initialized from AppDelegate as early as possible. Please open `AppDelegate.m`, import the header file ```objc #import "ReactNativeFlurry.h" ``` And add this line right after `- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions` ```objc [ReactNativeFlurry enableMessaging]; ``` ### tvOS - Please note that Flurry Messaging and Flurry Config are currently not available on tvOS. For the detailed list of unavailable APIs, please see API reference below. ## Example - `index.js` ```javascript import { AppRegistry } from 'react-native'; import { name as appName } from './app.json'; import App from './App'; import Flurry from 'react-native-flurry-sdk'; // Init Flurry once as early as possible recommended in index.js. // For each platform (Android, iOS) where the app runs you need to acquire a unique Flurry API Key. // i.e., you need two API keys if you are going to release the app on both Android and iOS platforms. // If you are building for TV platforms, you will need two API keys for Android TV and tvOS. new Flurry.Builder() .withCrashReporting(true) .withLogEnabled(true) .withLogLevel(Flurry.LogLevel.DEBUG) .withReportLocation(true) .build(FLURRY_ANDROID_API_KEY, FLURRY_IOS_API_KEY); AppRegistry.registerComponent(appName, () => App); ``` - `App.js` ```javascript import React, { Component } from 'react'; import { Platform, StyleSheet, Text, View } from 'react-native'; import Flurry from 'react-native-flurry-sdk'; type Props = {}; export default class App extends Component<Props> { constructor(props) { super(props); // Example to get Flurry versions. Flurry.getVersions().then((versions) => { console.log('Versions: ' + versions.agentVersion + ' : ' + versions.releaseVersion + ' : ' + versions.sessionId); }); // Example to get Flurry Publisher Segmentation. Flurry.getPublisherSegmentation(true).then((segmentations) => { console.log('Publisher Segmentation: ' + segmentations.segments); }); } render() { // Set Flurry preferences. Flurry.setLogEnabled(true); Flurry.setLogLevel(Flurry.LogLevel.VERBOSE); // Set user preferences. Flurry.setAge(36); Flurry.setGender(Flurry.Gender.FEMALE); Flurry.setReportLocation(true); // Set user properties. Flurry.UserProperties.set(Flurry.UserProperties.PROPERTY_REGISTERED_USER, 'True'); // Log Flurry events. Flurry.logEvent('React Native Event'); Flurry.logEvent('React Native Timed Event', {param: 'true'}, true); ... Flurry.endTimedEvent('React Native Timed Event'); // Log Flurry standard events. Flurry.logStandardEvent(Flurry.Event.APP_ACTIVATED); var params = new Map([ [Flurry.EventParam.TOTAL_AMOUNT, 34.99], [Flurry.EventParam.SUCCESS, true], [Flurry.EventParam.ITEM_NAME, 'book 1'], ['note', 'This is an awesome book to purchase !!!'] ]); Flurry.logStandardEvent(Flurry.Event.PURCHASED, params); return ( <View style={styles.container}> ... </View> ); } } ... ``` - `index.js / Config.js` ```javascript Flurry.addConfigListener((event) => { if (event.Type === Flurry.ConfigStatus.SUCCESS) { // Data fetched, activate it. Flurry.activateConfig(); } else if (event.Type === Flurry.ConfigStatus.ACTIVATED) { // Received cached data, or newly activated data. Flurry.getConfigString('welcome_message', 'Welcome!').then((value) => { console.log((event.isCache ? 'Received cached data: ' : 'Received newly activated data: ') + value.welcome_message); }); } else if (event.Type === Flurry.ConfigStatus.UNCHANGED) { // Fetch finished, but data unchanged. Flurry.getConfigString('welcome_message', 'Welcome!').then((value) => { console.log('Received unchanged data: ' + value.welcome_message); }); } else if (event.Type === Flurry.ConfigStatus.ERROR) { // Fetch failed. console.log('Fetch error! Retrying: ' + event.isRetrying); } }); Flurry.fetchConfig(); ``` - `index.js / Messaging.js` ```javascript // To customize Flurry Push for Android, please duplicate Builder setup in your MainApplication.java. new Flurry.Builder() .withMessaging(true) ... // Optionally add a listener to receive messaging events, and handle the notification. // Please call required Flurry.willHandleMessage(boolean) when received event types of // MessageType.RECEIVED or MessageType.CLICKED as soon as possible to avoid delay. Flurry.addMessagingListener((message) => { if (message.Type === Flurry.MessageType.RECEIVED) { Flurry.willHandleMessage(false); } else if (message.Type === Flurry.MessageType.CLICKED) { Flurry.willHandleMessage(false); } Flurry.printMessage(message); }); ``` ## API Reference See [Android](https://flurry.github.io/flurry-android-sdk/analytics/index.html)-[(FlurryAgent)](https://flurry.github.io/flurry-android-sdk/analytics/com/flurry/android/FlurryAgent.html) / [iOS](https://flurry.github.io/flurry-ios-sdk/Flurry%20Analytics%20API%20Documentation/index.html)-[(Flurry)](https://flurry.github.io/flurry-ios-sdk/Flurry%20Analytics%20API%20Documentation/interface_flurry.html) for the Flurry references. - **Methods to initialize Flurry** ```javascript Flurry.Builder.withAppVersion(versionName = '1.0'); // iOS only. For Android, please use Flurry.setVersionName() instead. Flurry.Builder.withContinueSessionMillis(sessionMillis = 10000); Flurry.Builder.withCrashReporting(crashReporting = true); Flurry.Builder.withGppConsent(gppString: string, gppSectionIds: number[]); Flurry.Builder.withDataSaleOptOut(isOptOut = false); Flurry.Builder.withIAPReportingEnabled(enableIAP = true); // iOS only. Flurry.Builder.withIncludeBackgroundSessionsInMetrics(includeBackgroundSessionsInMetrics = true); Flurry.Builder.withLogEnabled(enableLog = true); Flurry.Builder.withLogLevel(logLevel = Flurry.LogLevel.WARN); // LogLevel = { VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT } Flurry.Builder.withReportLocation(reportLocation = true); // Android only Flurry.Builder.withPerformanceMetrics(performanceMetrics = Flurry.Performance.ALL); // Performance = { NONE, COLD_START, SCREEN_TIME, ALL } Flurry.Builder.withSslPinningEnabled(sslPinningEnabled = false); // Android only Flurry.Builder.withMessaging(enableMessaging = true); // not available on tvOS Flurry.Builder.build(apiKeyAndroid: string, apiKeyIos: string); // preferred; passing null if not available Flurry.Builder.build(apiKey: string); // use when only single platform is supported, or shared (not recommended) // tvOS only Flurry.Builder.withTVSessionReportingInterval(interval = 5); Flurry.Builder.withTVEventCountThreshold(threshold = 10); ``` - **Methods to set Flurry preferences** ```javascript Flurry.setContinueSessionMillis(sessionMillis = 10000); Flurry.setCrashReporting(crashReporting = true); Flurry.setIncludeBackgroundSessionsInMetrics(includeBackgroundSessionsInMetrics = true); Flurry.setLogEnabled(enableLog = true); Flurry.setLogLevel(logLevel = Flurry.LogLevel.WARN); // LogLevel = { VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT } Flurry.setSslPinningEnabled(sslPinningEnabled = false); // Android only ``` - **Methods to set user preferences** ```javascript Flurry.setAge(age: number); Flurry.setGender(gender: Flurry.Gender); // Gender = { MALE, FEMALE } Flurry.setReportLocation(reportLocation: boolean); Flurry.setSessionOrigin(originName: string, deepLink: string); Flurry.setUserId(userId: string); Flurry.setVersionName(versionName: string); // Android only. For iOS, please use Flurry.Builder.withAppVersion() instead. Flurry.addOrigin(originName: string, originVersion: string); Flurry.addOrigin(originName: string, originVersion: string, originParameters: { [key: string]: string; }); Flurry.addSessionProperty(name: string, value: string); ``` - **Methods to set privacy preferences** ```javascript Flurry.setGppConsent(gppString: string, gppSectionIds: number[]); Flurry.setDataSaleOptOut(isOptOut: boolean); Flurry.deleteData(); Flurry.openPrivacyDashboard(); ``` - **Methods to set user properties** ```javascript // Standard User Properties: Flurry.UserProperties = { // PROPERTY_CURRENCY_PREFERENCE, PROPERTY_PURCHASER, PROPERTY_REGISTERED_USER, PROPERTY_SUBSCRIBER } Flurry.UserProperties.set(propertyName: string, propertyValue: string); Flurry.UserProperties.set(propertyName: string, propertyValues: string[]); Flurry.UserProperties.add(propertyName: string, propertyValue: string); Flurry.UserProperties.add(propertyName: string, propertyValues: string[]); Flurry.UserProperties.remove(propertyName: string); Flurry.UserProperties.remove(propertyName: string, propertyValue: string); Flurry.UserProperties.remove(propertyName: string, propertyValues: string[]); Flurry.UserProperties.flag(propertyName: string); ``` - **Methods to get Flurry versions and publisher segmentation** ```javascript Flurry.getVersions(): Promise<{ agentVersion: number; releaseVersion: string; sessionId: string; }>; Flurry.getVersions(errorCallback: (errorMessage: string) => void, successCallback: (agentVersion: number, releaseVersion: string, sessionId: string) => void); Flurry.getPublisherSegmentation(refresh?: boolean): Promise<{ segments: string }>; Flurry.fetchPublisherSegmentation(); ``` - **Methods to log Flurry events** ```javascript Flurry.logEvent(eventId: string); Flurry.logEvent(eventId: string, parameters: { [key: string]: string; }); Flurry.logEvent(eventId: string, timed: boolean); Flurry.logEvent(eventId: string, parameters: { [key: string]: string; }, timed: boolean); Flurry.logEvent(eventId: string, timedId: string); Flurry.logEvent(eventId: string, parameters: { [key: string]: string; }, timedId: string); Flurry.endTimedEvent(eventId: string); Flurry.endTimedEvent(eventId: string, parameters: { [key: string]: string; }); Flurry.endTimedEvent(eventId: string, timedId: string); Flurry.endTimedEvent(eventId: string, parameters: { [key: string]: string; }, timedId: string); Flurry.logStandardEvent(eventId: Flurry.Event); Flurry.logStandardEvent(eventId: Flurry.Event, parameters: { [key: Flurry.EventParam]: object; }); Flurry.onPageView(); // Deprecated, API removed, no longer supported by Flurry. Flurry.onError(errorId: string, message: string, errorClass: string); Flurry.onError(errorId: string, message: string, errorClass: string, errorParams: { [key: string]: string; }); Flurry.logBreadcrumb(crashBreadcrumb: string); Flurry.logPayment(productName: string, productId: string, quantity: number, price: number, currency: string, transactionId: string, parameters: { [key: string]: string; }); ``` - **Methods to enable IAP reporting (iOS and tvOS)** ```javascript Flurry.setIAPReportingEnabled(enableIAP: boolean); ``` - **Methods to set the iOS conversion value sent to Apple through SKAdNetwork (iOS)** ```javascript Flurry.updateConversionValue(conversionValue: number) Flurry.updateConversionValueWithEvent(flurryEvent: Flurry.SKAdNetworkEvent); // SKAdNetworkEvent = { NO_EVENT, REGISTRATION, LOGIN, SUBSCRIPTION, IN_APP_PURCHASE } ``` - **Methods for Flurry Performance Metrics** ```javascript Flurry.Performance.startResourceLogger(); Flurry.Performance.logResourceLogger(id: string); Flurry.Performance.reportFullyDrawn(); ``` - **Methods for Flurry Config** ```javascript // Event.Type: Flurry.ConfigStatus = { SUCCESS, UNCHANGED, ERROR, ACTIVATED } // Event.isRetrying: true if it is still retrying fetching, for ERROR type // Event.isCache: true if activated from the cached data, for ACTIVATED type Flurry.addConfigListener (callback: (event: { Type: string; isCache?: boolean; isRetrying?: boolean; }) => void); Flurry.removeConfigListener(callback: (event: { Type: string; isCache?: boolean; isRetrying?: boolean; }) => void); Flurry.fetchConfig(); Flurry.activateConfig(): Flurry.getConfigString(key: string, defaultValue: string): Promise<{ [key: string]: string; }>; Flurry.getConfigString(keysAndDefaults: { [key: string]: string; }): Promise<{ [key: string]: string; }>; ``` - **Methods for Messaging (Flurry Push)** ```javascript // Message.Type: Flurry.MessageType = { RECEIVED, CLICKED, // CANCELLED, REFRESH } (Android only) // Message.Title: message title // Message.Body: message body // Message.Data: message data (Map) // Message.ClickAction: click action (Android only) // Message.Token: refreshed token Flurry.addMessagingListener(callback: (message: { Type: string; Title?: string; Body?: string; Data?: { [key: string]: string; }; ClickAction?: string; Token?: string; }) => void); Flurry.removeMessagingListener(callback: (message: { Type: string; Title?: string; Body?: string; Data?: { [key: string]: string; }; ClickAction?: string; Token?: string; }) => void); Flurry.willHandleMessage(handled: boolean); Flurry.printMessage(message: { Type: string; Title?: string; Body?: string; Data?: { [key: string]: string; }; ClickAction?: string; Token?: string; }); ``` ## Support - [Flurry Developer Support Site](https://developer.yahoo.com/flurry/docs/) ## License Copyright 2022 Yahoo Inc. This project is licensed under the terms of the [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) open source license. Please refer to [LICENSE](LICENSE) for the full terms.