npm package: @nawatech-co-dev/rn-md-analytics-sdk
Description: React native install SDK
Author: nandanurseptama
Latest version: 0.4.2

# @nawatech-co-dev/rn-md-analytics-sdk

React native installation tracker SDK.

## Capabilities

- Capture custom event with custom data
- Capture user
- Register device
- Receive silent notification
- Send ping with background manager to notify server the installation status (Android Only)

## Dependencies

This SDK use some dependencies in order to work properly.

- [`react-native-device-info`](https://www.npmjs.com/package/react-native-device-info)
- [`react-native-aes-crypto`](https://www.npmjs.com/package/react-native-aes-crypto)

## Integration

If you want to integrate this SDK, please see the [`guide`](#guide) section.

# Guide

## Installation

Yarn :

```bash
yarn add @nawatech-co-dev/rn-md-analytics-sdk
```

NPM :

```bash
npm install @nawatech-co-dev/rn-md-analytics-sdk
```

This package automatically linking to native platform (IOS and Android) on React native >= 0.63!

## Initialize SDK

This SDK need :

- Api Base URL.
- API KEY (to identify who the sender data)
- Aes Secret and IV to encrypt request data

We will inform you this configuration.

```js
import { InstallationTrackerSdk } from '@nawatech-co-dev/rn-md-analytics-sdk';
// since we dont to expose our API base url. you must to set it manually
// do not end base url with slash
const sdkApiBaseUrl = 'https://example.com';

// api key that registered in our record. it will identify your app
const sdkApiKey = 'xxx-xx';

// aes secret that we give to you
const aesSecret = 'exampleSecret';

// aes IV that we give it to you
const aesIV = 'exampleIV';

// initialize SDK
const sdk = new InstallationTrackerSdk({
  baseUrl: sdkApiBaseUrl,
  apiKey: sdkApiKey,
  aesSecret: aesSecret,
  aesIV: aesIV,
});
```

## Usages

### Register Device

When you want to track user device, you need to call `registerDevice` function from our SDK. For example you can track user device in your main Component.

```js
// App.tsx

// using useEffect to trigger register device function
useEffect(() => {
  function registerDevice() {
    sdk.registerDevice();
  }
  registerDevice();
}, []); // register device App component after first render. in dev mode it will called twice
```

### Capture User

When you capture a user, it will automatically sending the time when user install the application for first time. So, you dont need to send it manually.

```js
// capture user with no properties
const id = 'xx-xx-xxx'; // id is user id. this is required
const properties = null; // properties of user. can be null
sdk.captureUser(id, properties);

// capture user with properties
const id = 'xx-xx-xxx'; // id is user id. this is required
const properties = { email: 'johndoe@gmail.com' }; // properties of user
sdk.captureUser(id, properties);
```

Example :

You can `captureUser` with `useEffect` that listen whenever user properties change.

```js
// example when use redux to handle your state
const authedUser = useSelector((state: RootState) => state.user);

useEffect(()=>{
  function captureUser(){
    // when authed user is undefined or null
    // dont capture user
    if(authedUser === undefined || authedUser === null){
      return;
    }
    sdk.captureUser(authedUser.id, authedUser.properties);
    return;
  }
  captureUser();
}, [authedUser, authedUser.id, authedUser.properties])
```

### Capture First Login

To capture first login data, you need to send it manually with `captureEvent` function. However, this functionality will depend `time` value that you send. If the `first_login` record already exist with current device and user, it will ignored by our API, otherwise it will created.

```js
// LoginPage.tsx
function LoginPage() {
  // handle login button pressed
  const handleLogin = () => {
    return yourHandleLoginApiFunction().then((result) => {
      // capture first login
      // event name must be `first_login`
      // and time field value must be in ISO string
      sdk.captureEvent('first_login', { time: '2024-08-01T04:25:36.970Z' });
    });
  };
  return (
    <View>
      . . .
      <TouchableOpacity title="Login" onPress={handleLogin}></TouchableOpacity>
    </View>
  );
}
```

### Subscribe Installation Tracker Notification

To receive silent notification that track installation, you need to `installation_tracker` subscribe topic. For example you can register it at `index.js` or `index.ts` before `AppRegistry.registerComponent(appName, () => App);` called.

```js
// index.js / index.ts
import messaging from '@react-native-firebase/messaging';
messaging().subscribeToTopic('installation_tracker');
```

### Register Notification Listener

In order to track device installation status, you notification listener that ping server.

#### Receive notification at Foreground

When firebase send push notification, you can use sdk `ping` function to send installation status.

```js
// Send ping to server when receive any notification
messaging().onMessage(async (remoteMessage) => {
  sdk.ping();
});
```

#### Receive notification at Background and Quited App.

In order to receive notification when application at background or quited, you need to register listener as soon as possible. For example you can register it at `index.js` or `index.ts` before `AppRegistry.registerComponent(appName, () => App);` called.

```js
// Register background handler
messaging().setBackgroundMessageHandler(async (remoteMessage) => {
  sdk.receiveInstallationTrackerNotification(remoteMessage);
});

// Your app registry
AppRegistry.registerComponent(appName, () => App);
```

### Register Background Worker (OPTIONAL)

Background worker used to send ping message to our server. Register background work as soon as possible. For example you can register it at `index.js` or `index.ts` before `AppRegistry.registerComponent(appName, () => App);` called.

Example :

```js
// register device ping worker
// it will register background manager
// that run task to ping server and
// run exactly one for every day
sdk.registerDevicePingWorker();

// Your app registry
AppRegistry.registerComponent(appName, () => App);
```

Our configuration for background worker, is guaranteed that only registered once. When you register multiple time, it will cancel and replace it. So you dont need to worry about memory leak.
Take a look on this [`docs`](<https://developer.android.com/reference/androidx/work/WorkManager#enqueueUniquePeriodicWork(kotlin.String,androidx.work.ExistingPeriodicWorkPolicy,androidx.work.PeriodicWorkRequest)>)

But, background worker may not run when the device in these conditions :

- `Saver Mode` or `Battery Low`
- `App Killed` by Task Manager or `Force Quitted`

In some device manufactures, when you close the from `Recent Tasks` it will `Force Quitted` app. So, it's not very reliable and just optional functionality.

### Integrate with Firebase/Google Analytics

When you want to integrate your data with Firebase/Google Analytic, you have to capture custom event with event name `capture_user`.

Example :

```js
// example when use redux to handle your state
import * as FA from '@react-native-firebase/analytics';

const authedUser = useSelector(
  (state: RootState) => state.user,
);

useEffect(()=>{
  function captureUser(){
    // when authed user is undefined or null
    // dont capture user
    if(authedUser === undefined || authedUser === null){
      return;
    }
    // After you capture user to OUR SDK
    // you can capture custom event
    return sdk.
      captureUser(authedUser.id, authedUser.properties).then((currentUserSession)=>{
        FA.getAnalytics()
          .logEvent('capture_user', currentUserSession);
    });
  }
  captureUser();
}, [authedUser, authedUser.id, authedUser.properties])
```