# React-native v3.3.X

### Introduction

#### SDK overview

> 🚧 Flagship React SDK only works with React hooks
>
> Our React SDK only works with react hooks, if you want to use without it, you should use our [Javascript SDK](https://docs.developers.flagship.io/docs/js-sdk)

Welcome to the Flagship React Native SDK documentation!

The following documentation helps you to run Flagship on your React Native environment.

Flagship React Native SDK provides a `<FlagshipProvider />`, which makes Flagship features available to the rest of your app.\
Flagship features are accessible using Flagship hooks, have a look at the documentation for details.

Feel free to [contact us](mailto:product.feedback@abtasty.com?subject=Flagship%20Developer%20Documentation) if you have any questions regarding this documentation.

#### SDK features

This SDK version helps you:

* Set a [visitor ID](doc:glossary#visitor-id)
* Update [visitor context](doc:glossary#user-context)
* Assign campaigns via the [Decision API](doc:decision-api) or via the [Bucketing](doc:bucketing)
* Get Flags
* Manage visitor consent
* Activate campaigns
* Send hits to our [Universal Collect](doc:universal-collect-documentation)
* Manage visitor cache

#### Prerequisites

* **Node.js**: version 6.0.0 or later
* **Npm**: version 5.2.0 or later
* **React**: version 16.8.0 or later (the SDK only supports hooks for now)

#### Good to know

* [Github repository](https://github.com/flagship-io/flagship-react-native-sdk)
* Typescript code supported

### Getting started

#### Initialization

There are four steps to follow to get started with the React Flagship SDK.

1. **Install** the node module

```shell
npm install @flagship.io/react-native-sdk
```

> 📘 Information
>
> Please ensure that you have also installed the [@react-native-async-storage/async-storage](https://www.npmjs.com/package/@react-native-async-storage/async-storage) package. If it's not already in your project, you'll need to add it separately.

2. **Import** the Flagship React provider

*In most cases, do this in your`App.js` file to wrap your entire app with the provider.*

```javascript
import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider>{/* [...] */}</FlagshipProvider>
  </>
);
```

3. **Initialize** the provider

*You must at least include the required props like`envId`, `apiKey`, `visitorData`.*

```javascript
import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdkk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY"
      visitorData={{
        id: "YOUR_VISITOR_ID",
        context: {
          // some context
        },
        isAuthenticated: false,
      }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);
```

4. Use a **Flagship hook** in a component

*In most case, you will get the desired flags.*

```javascript
import React from "react";
import { useFsFlag } from "@flagship.io/react-native-sdk";
import { View, Text } from "react-native";

export const MyReactComponent = () => {
  const flagBackgroundColor = useFsFlag("backgroundColor","green")
  return (
    <View
      style={{
        height: "200px",
        width: "200px",
        backgroundColor: flagBackgroundColor.getValue(),
      }}
    >
      <Text>{"I'm a square with color=" + flagBackgroundColor.getValue()}</Text>
    </View>
  );
};
```

### API Reference

#### `FlagshipProvider`

Here is the full list of props available to use inside the `FlagshipProvider` React component:

```
  <th style={{ textAlign: "left" }}>
    Type
  </th>

  <th style={{ textAlign: "left" }}>
    Default
  </th>

  <th style={{ textAlign: "left" }}>
    Description
  </th>
</tr>
```

```
  <td style={{ textAlign: "left" }}>
    string
  </td>

  <td style={{ textAlign: "left" }}>
    Required
  </td>

  <td style={{ textAlign: "left" }}>
    Environment id provided by Flagship.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    apiKey
  </td>

  <td style={{ textAlign: "left" }}>
    string
  </td>

  <td style={{ textAlign: "left" }}>
    Required
  </td>

  <td style={{ textAlign: "left" }}>
    Api authentication key provided by Flagship.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    visitorData
  </td>

  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    null
  </td>

  <td style={{ textAlign: "left" }}>
    This is the data to identify the current visitor using your app. **[See arguments](#visitordata)**
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    onInitStart
  </td>

  <td style={{ textAlign: "left" }}>
    function():void
  </td>

  <td style={{ textAlign: "left" }}>
    null
  </td>

  <td style={{ textAlign: "left" }}>
    Callback function called when the SDK starts initialization.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    onInitDone
  </td>

  <td style={{ textAlign: "left" }}>
    function():void
  </td>

  <td style={{ textAlign: "left" }}>
    null
  </td>

  <td style={{ textAlign: "left" }}>
    Callback function called when the SDK ends initialization.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    onUpdate
  </td>

  <td style={{ textAlign: "left" }}>
    function(object): void
  </td>

  <td style={{ textAlign: "left" }}>
    null
  </td>

  <td style={{ textAlign: "left" }}>
    Callback function called when the SDK is updated. For example, after a synchronize is triggered or visitor context has changed. **[See arguments](#onupdate)**
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    onBucketingSuccess
  </td>

  <td style={{ textAlign: "left" }}>
    function(object): void
  </td>

  <td style={{ textAlign: "left" }}>
    null
  </td>

  <td style={{ textAlign: "left" }}>
    Define a callable in order to get callback when the first bucketing polling succeed. <br/> [see arguments](#onbucketingsuccess)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    onBucketingFail
  </td>

  <td style={{ textAlign: "left" }}>
    function(object): void
  </td>

  <td style={{ textAlign: "left" }}>
    null
  </td>

  <td style={{ textAlign: "left" }}>
    Define a callable to get callback when the first bucketing polling failed. <br/> [see arguments](#onbucketingfail)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    onBucketingUpdated
  </td>

  <td style={{ textAlign: "left" }}>
    function(Date): void
  </td>

  <td style={{ textAlign: "left" }}>
    null
  </td>

  <td style={{ textAlign: "left" }}>
    Define a callable to get callback each time bucketing data from Flagship has updated. <br/> [see arguments](#onbucketingupdated)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    initialFlagsData
  </td>

  <td style={{ textAlign: "left" }}>
    Array(object)
  </td>

  <td style={{ textAlign: "left" }}>
    undefined
  </td>

  <td style={{ textAlign: "left" }}>
    This is a set of [flag data](#flag-data-shape) provided to avoid the SDK to have an empty cache during the first initialization.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    initialCampaigns
  </td>

  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    undefined
  </td>

  <td style={{ textAlign: "left" }}>
    This is an object of the data received when fetching the Flagship decision API (decisionMode="API").\
    Providing this property avoid the SDK to have an empty cache during first initialization.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    initialBucketing
  </td>

  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    undefined
  </td>

  <td style={{ textAlign: "left" }}>
    This is an object of the data received when fetching bucketing endpoint. <br/> Providing this prop will make bucketing ready to use and the first polling will immediatly check for an update.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    loadingComponent
  </td>

  <td style={{ textAlign: "left" }}>
    React.ReactNode
  </td>

  <td style={{ textAlign: "left" }}>
    undefined
  </td>

  <td style={{ textAlign: "left" }}>
    This component will be rendered when Flagship is loading at first initialization only. By default, the value is undefined. It means it will display your app and it might display default flags value for a very short moment.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    fetchNow
  </td>

  <td style={{ textAlign: "left" }}>
    boolean
  </td>

  <td style={{ textAlign: "left" }}>
    true
  </td>

  <td style={{ textAlign: "left" }}>
    `Decide to fetch automatically flags when SDK is initialized.`  

    * \*NOTE\*\*:  When `fetchNow=false` the property `loadingComponent` will be ignored.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    enableClientCache
  </td>

  <td style={{ textAlign: "left" }}>
    boolean
  </td>

  <td style={{ textAlign: "left" }}>
    true
  </td>

  <td style={{ textAlign: "left" }}>
    Indicates whether enables or disables the client cache manager.  

    By enabling the client cache, it will allow you to keep cross sessions visitor experience.  

    * \*Note\*\*: The client cache is useful only when you do not specify a visitor id when creating a visitor. From there, you only need to be focus on handling the visitor context and whether he is authenticated or not. That's it.  
    * \*Note 2\*\*: Not available on server side, this setting  will be ignored
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    decisionApiUrl
  </td>

  <td style={{ textAlign: "left" }}>
    string
  </td>

  <td style={{ textAlign: "left" }}>
    [https://decision.flagship.io/v2](https://decision.flagship.io/v2)
  </td>

  <td style={{ textAlign: "left" }}>
    This setting can be useful if you need to simulate the API for tests such as end-to-end or if you want to move to an earlier version of the Flagship API.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    decisionMode
  </td>

  <td style={{ textAlign: "left" }}>
    `DECISION-API` \| `Bucketing`
  </td>

  <td style={{ textAlign: "left" }}>
    `DECISION-API`
  </td>

  <td style={{ textAlign: "left" }}>
    `Indicates the behavior of the SDK.` In <code>API</code> mode, it will get the modifications using the Flagship decision API.  

    With <code>Bucketing</code>, it will load all campaigns once  and compute the variation assignment of the visitor locally.  

    [learn more](#decision-mode)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    pollingInterval
  </td>

  <td style={{ textAlign: "left" }}>
    number
  </td>

  <td style={{ textAlign: "left" }}>
    1
  </td>

  <td style={{ textAlign: "left" }}>
    Indicates the polling interval period in seconds when SDK is running Bucketing mode (<code>decisionMode="Bucketing"</code>).  

    For example, if <code>pollingInterval=5</code>, a bucketing call will be\
     trigger in background every 5 seconds.  

    * \*Note 1**:**pollingInterval\*\* can't be lower than 1 second.  

    **Note 2**: if bucketing is enabled and **pollingInterval**\
    value is **0**, the polling will be done once.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    timeout
  </td>

  <td style={{ textAlign: "left" }}>
    number
  </td>

  <td style={{ textAlign: "left" }}>
    2
  </td>

  <td style={{ textAlign: "left" }}>
    Specify timeout in seconds for api request. <br/>**Note:** timeout can't be lower than 0 second.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    logLevel
  </td>

  <td style={{ textAlign: "left" }}>
    number
  </td>

  <td style={{ textAlign: "left" }}>
    9
  </td>

  <td style={{ textAlign: "left" }}>
    Set the maximum log level to display <br />[see`LogLevel`](#loglevel)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    logManager
  </td>

  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    Defined
  </td>

  <td style={{ textAlign: "left" }}>
    Specify a custom implementation of LogManager in order to receive logs from the SDK.  

    * \*Note:\*\* The object must fill Interface [`IFlagshipLogManager`](#iflagshiplogmanager)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    activateDeduplicationTime
  </td>

  <td style={{ textAlign: "left" }}>
    number
  </td>

  <td style={{ textAlign: "left" }}>
    2.5
  </td>

  <td style={{ textAlign: "left" }}>
    Specify delay in seconds of activate deduplication. After an activate is sent, all future sending of this activate will be blocked until the expiration of the delay.  

    * \*Note:\*\* if 0 is given, no deduplication process will be used
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    hitDeduplicationTime
  </td>

  <td style={{ textAlign: "left" }}>
    number
  </td>

  <td style={{ textAlign: "left" }}>
    2.5
  </td>

  <td style={{ textAlign: "left" }}>
    Specify delay in seconds of hit deduplication. After a hit is sent, all future sending of this hit will be blocked until the expiration of the delay.  

    * \*Note:\*\* if 0 is given, no deduplication process will be used
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    visitorCacheImplementation
  </td>

  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    Defined
  </td>

  <td style={{ textAlign: "left" }}>
    Define an object that implement the interface [`visitorCacheImplementation`](#visitor-cache), to handle the visitor cache. [see cache-manager](#managing-visitor-cache)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    hitCacheImplementation
  </td>

  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    Defined
  </td>

  <td style={{ textAlign: "left" }}>
    Define an object that implement the interface [`IHitCacheImplementation`](#hit-cache), to handle the visitor cache. [see cache-manager](#managing-visitor-cache)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    disableCache
  </td>

  <td style={{ textAlign: "left" }}>
    boolean
  </td>

  <td style={{ textAlign: "left" }}>
    false
  </td>

  <td style={{ textAlign: "left" }}>
    if it's set to true, hit cache and visitor cache will be disabled otherwise will be enabled. [see cache-manager](#cache-manager)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    statusChangedCallback
  </td>

  <td style={{ textAlign: "left" }}>
    function(number):void
  </td>

  <td style={{ textAlign: "left" }}>
    undefined
  </td>

  <td style={{ textAlign: "left" }}>
    Define a callable in order to get callback when the SDK status has changed. <br/> [see arguments](#statuschangedcallback).
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    onUserExposure `deprecated`
  </td>

  <td style={{ textAlign: "left" }}>
    function(object):void
  </td>

  <td style={{ textAlign: "left" }}>
    undefined
  </td>

  <td style={{ textAlign: "left" }}>
    Optional\
    Define a callable to get callback each time a Flag have been exposed to a visitor (activation hit has been sent) by SDK\
    [see arguments](#onuserexposure)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    onLog
  </td>

  <td style={{ textAlign: "left" }}>
    function(level: LogLevel, tag: string, message: string):void
  </td>

  <td style={{ textAlign: "left" }}>
    undefined
  </td>

  <td style={{ textAlign: "left" }}>
    **Optional**\
    Define a callable to get a callback whenever the SDK needs to report a log\
    [see arguments](#onlog)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    trackingManagerConfig
  </td>

  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    defined
  </td>

  <td style={{ textAlign: "left" }}>
    Define options to configure hit batching\
    [trackingManagerConfig](#trackingmanagerconfig)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    onVisitorExposed
  </td>

  <td style={{ textAlign: "left" }}>
    function(object):void
  </td>

  <td style={{ textAlign: "left" }}>
    undefined
  </td>

  <td style={{ textAlign: "left" }}>
    **Optional**\
    Define a callable to get callback each time a Flag has been exposed to a visitor (When a flag has been seen by your visitor) and succeeded.\
    [see arguments](#onvisitorexposed)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    fetchThirdPartyData
  </td>

  <td style={{ textAlign: "left" }}>
    boolean
  </td>

  <td style={{ textAlign: "left" }}>
    false
  </td>

  <td style={{ textAlign: "left" }}>
    **Optional**\
    **Bucketing mode only**\
    If true, will fetch the visitor's segment from [universal data connector](https://developers.abtasty.com/docs/data/universal-data-connector) each time [fetchFlags](#fetching-flags) is called and append those segments 
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    fetchFlagsBufferingTime
  </td>

  <td style={{ textAlign: "left" }}>
    number
  </td>

  <td style={{ textAlign: "left" }}>
    2
  </td>

  <td style={{ textAlign: "left" }}>
    **Optional**  

    You can specify a delay in seconds for fetch flags call buffering. This means that after the SDK has fetched flags, they will be buffered for the specified delay. During this delay, any subsequent fetch flags calls will return the same flags.  

    Note:  

    \- If a value of 0 is given, no buffering process will be used.  

    * If visitor data has changed, the SDK bypass the buffering.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    disableDeveloperUsageTracking
  </td>

  <td style={{ textAlign: "left" }}>
    boolean
  </td>

  <td style={{ textAlign: "left" }}>
    false
  </td>

  <td style={{ textAlign: "left" }}>
    Our SDK will collect `usage` and `troubleshooting` data to help us improve our product and help you in case there is any issue in the implementation.  

    If you set this method to `true` we won't collect data and won't be able to help you investigate in case of issues.
  </td>
</tr>
```

| Props |
| ----- |
| envId |

\\

> 📘
>
> When bucketing is running (`decisionMode="BUCKETING"`), the polling will restart its interval period based on the moment when one of the following props changes after first rendering :
>
> * envId
> * apiKey
> * decisionMode

> 📘
>
> Any change of props **`visitorData`** will [fetch flags](#useflagship-output-fetchflags) automatically.
>
> On SDK initialization, if the props **`visitorData`** is null, no visitor will be initialized until set

\\

**visitorData**

The `visitorData` object takes the following arguments:

```
  <th style={{ textAlign: "left" }}>
    Type
  </th>

  <th style={{ textAlign: "left" }}>
    Default
  </th>

  <th style={{ textAlign: "left" }}>
    Description
  </th>
</tr>
```

```
  <td style={{ textAlign: "left" }}>
    string
  </td>

  <td style={{ textAlign: "left" }}>
    undefined
  </td>

  <td style={{ textAlign: "left" }}>
    **Optional**\
    Unique identifier for the current visitor. This can be an ID from\
     your database or a session ID.\ <b><a href="/docs/glossary#visitor-id">Learn more</a></b>  

    <b>NOTE</b>: The visitor id must be a <code>string</code> and can't be a <code>number</code>.  

    <b>NOTE 2</b>: If you do not specify a value, the id will be either\
     automatically generated or will be the visitor id from previous session\
    (if <code>enableClientCache</code> equals <code>true</code>).
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    context
  </td>

  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    \{}
  </td>

  <td style={{ textAlign: "left" }}>
    **Optional**\
    JSON object of key-value pairs describing the visitor and device context. **[Learn more](doc:glossary#user-context)**
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    isAuthenticated
  </td>

  <td style={{ textAlign: "left" }}>
    boolean
  </td>

  <td style={{ textAlign: "left" }}>
    false
  </td>

  <td style={{ textAlign: "left" }}>
    **Optional**\
    Indicates if the visitor is authenticated (true) or not (false, by default).  

    <b>NOTE</b>: The SDK will listen the change of this value (switching from <code>true</code> to <code>false</code> or from <code>false</code> to <code>true</code>).  

    This attribute is used for the experience continuity.\ <b><a href="#experience-continuity">Learn more</a></b>
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    hasConsented
  </td>

  <td style={{ textAlign: "left" }}>
    boolean
  </td>

  <td style={{ textAlign: "left" }}>
    true
  </td>

  <td style={{ textAlign: "left" }}>
    Specify if visitor has consented for protected data usage.
  </td>
</tr>
```

| Argument |
| -------- |
| id       |

\\

**Decision Mode**

**`DECISION-API`Mode** (by default)

When the SDK is running in `API` mode, the campaign assignments and targeting validation will be run through our [Decision API](https://github.com/flagship-io/Gitbook/blob/main/docs/decision-api/README.md#campaigns). In this mode, each time a new Decision is required, it will create an HTTPS request to the API.\
This mode is used by default for all our SDK.

**`Bucketing`Mode**

When the SDK is running in `Bucketing` mode, the SDK downloads all the campaigns configurations at once in a single bucketing file so that variation assignment can be computed client-side by the SDK. This bucketing file is stored in cache and will only be downloaded again when campaign configurations are modified in the Flagship interface. [**Learn more**](https://github.com/flagship-io/Gitbook/blob/main/bucketing/README.md)

`DecisionMode` is an enum defined decision type

| Key           | Value     | Type   | Description                    |
| ------------- | --------- | ------ | ------------------------------ |
| DECISION\_API | API       | string | Flagship SDK mode Decision API |
| BUCKETING     | BUCKETING | string | Flagship SDK mode bucketing    |

\\

**onUpdate**

The `onUpdate` object has one argument with the following shape:

| Key/Property    | Description                                                                                                                                                          |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| fsModifications | Array or null. It contains the last modifications saved in cache. When `null`, it means the SDK still not ready. You can check the SDK status with other attributes. |
| config          | Object. The current configuration running on the SDK.                                                                                                                |
| status          | Object. Contains informations about the actual SDK status. (Details below 👇)                                                                                        |

`status` object shape:

| Key/Property     | Description                                                                                                                           |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| isLoading        | Boolean. When `true`, the SDK is still not ready to render your App otherwise it'll use default modifications.                        |
| isSdkReady       | Boolean. `true` after it has fully finished initialization tasks, `false` otherwise.                                                  |
| isVisitorDefined | Boolean. When `true` the flagship visitor instance is truthy, false otherwise.                                                        |
| hasError         | Boolean. `true` when an error occured inside the SDK, `false` otherwise.                                                              |
| lastRefresh      | String or null. The last update date occured on the flagship visitor instance.                                                        |
| firstInitSuccess | String or null. When `null` no initialization succeed yet. When `string` contains stringified date of last successful initialization. |

\\

**onBucketingSuccess**

The `onBucketingSuccess` function has one argument with the following shape:

| Key/Property | Description                                                       |
| ------------ | ----------------------------------------------------------------- |
| status       | String. Returns either `200` (fresh update) or `304` (no change). |
| payload      | Object. The latest bucketing data received.                       |

\\

**onBucketingFail**

The onBucketingFail function has one argument

| Argument | Type   | Description                |
| -------- | ------ | -------------------------- |
| error    | object | Returns the error occurred |

\\

**onBucketingUpdated**

The onBucketingUpdated function has one argument

| Argument   | Type | Description                       |
| ---------- | ---- | --------------------------------- |
| lastUpdate | Date | Get the date of the latest update |

\\

**statusChangedCallback**

The statusChangedCallback function has one argument

| Argument | Type   | Description                                               |
| -------- | ------ | --------------------------------------------------------- |
| status   | number | Status of the SDK. [see`FlagshipStatus`](#flagshipstatus) |

\\

**onUserExposure**

The `onUserExposure` function has one argument with the following shape:

| Argument | Type             | Description                |
| -------- | ---------------- | -------------------------- |
| param    | UserExposureInfo | Get data from exposed flag |

UserExposureType shape

```typescript
type UserExposureInfo = {
  flagData: {
    key: string
    value: unknown
    metadata: IFlagMetadata
  },
  visitorData: {
    visitorId: string
    anonymousId: string|null
    context: Record<string, string|number|boolean>
  }
 }
```

```
  <th style={{ textAlign: "left" }}>
    Type
  </th>

  <th style={{ textAlign: "left" }}>
    Description
  </th>
</tr>
```

```
  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    * \*key\*\*: flag key  
    * \*value\*\*: flag value  
    * \*metadata\*\*: Campaign information metadata [see](#getting-flags-campaigns-metadata) 
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    visitorData
  </td>

  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    * \*visitorId\*\*: visitor id  
    * \*anonomousId\*\*: anonymous id  
    * \*context\*\*: visitor context
  </td>
</tr>
```

| Key/Property |
| ------------ |
| flagData     |

\\

**OnVisitorExposed**

In some cases, you'll need to send information about the exposure (When a flag has been seen by your visitor), like sending visitor and flag data to third parties.

To centralize it, we provide a callback in the configuration option of the SDK.

The `OnVisitorExposed` function has one argument with the following shape:

| Argument | Type             | Description                |
| -------- | ---------------- | -------------------------- |
| param    | OnVisitorExposed | Get data from exposed flag |

**OnVisitorExposed** shape

```javascript
type OnVisitorExposed ={
    exposedVisitor: {
      id: string
      anonymousId?:string|null
      context: Record<string, string|number|boolean>
  },
    fromFlag: {
      key: string
      value: unknown
      defaultValue: unknown
      metadata: IFlagMetadata
  }
}
```

```
  <th style={{ textAlign: "left" }}>
    Type
  </th>

  <th style={{ textAlign: "left" }}>
    Description
  </th>
</tr>
```

```
  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    This object represent the exposed visitor
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    fromFlag
  </td>

  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    This object represent the exposed flag.\
    (The flag that has triggered the exposure)
  </td>
</tr>
```

| Key/Property   |
| -------------- |
| exposedVisitor |

**exposedVisitor** object shape

| Key/Property | Type                                     | Description     |
| ------------ | ---------------------------------------- | --------------- |
| id           | string                                   | visitor id      |
| anonomousId  | string                                   | anonymous id    |
| context      | Record\<string, string\|number\|boolean> | visitor context |

**fromFlag** object shape

| Key/Property | Type          | Description                                             |
| ------------ | ------------- | ------------------------------------------------------- |
| key          | string        | flag key                                                |
| value        | unknown       | flag value                                              |
| defaultValue | unknown       | flag default value                                      |
| metadata     | IFlagMetadata | Campaign information metadata [see](#metadata-property) |

\\

Here is an example on how to use this callback:

[Example with Mixpanel integration](https://docs.developers.flagship.io/docs/integrate-with-mixpanel)\
[Example with Segment integration](https://docs.developers.flagship.io/docs/integrate-with-segmentcom)

Learn more about [getting flags](#getting-flags)

\\

**onLog**

The `onLog` function has 3 arguments

| Argument | Type   | Description                                    |
| -------- | ------ | ---------------------------------------------- |
| level    | number | Get the log level. [see `LogLevel`](#loglevel) |
| tag      | string | Get the function that triggered the log        |
| message  | string | Get a description of the log                   |

Usage :

```javascript
import React from "react";
import { FlagshipProvider, LogLevel } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY" // <= Required in next major release
      visitorData={{
        id: "YOUR_VISITOR_ID",
        context: {
          // some context
        },
        isAuthenticated: false,
      }}
      onLog={(level, tag, message) => {
        console.log(`[${LogLevel[level]}] [${tag}] : ${message}`);
      }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);
```

\\

**FlagshipStatus**

`FlagshipStatus` is an enum defining the different status of Flagship SDK

| Key              | Value | Type | Description                                                                                                             |
| ---------------- | ----- | ---- | ----------------------------------------------------------------------------------------------------------------------- |
| NOT\_INITIALIZED | 0     | int  | It is the default initial status. This status remains until the sdk has been initialized successfully.                  |
| STARTING         | 1     | int  | Flagship SDK is starting.                                                                                               |
| POLLING          | 2     | int  | Flagship SDK has been started successfully but is still polling campaigns.                                              |
| READY\_PANIC\_ON | 3     | int  | Flagship SDK is ready but is running in Panic mode: All features are disabled except the one which refresh this status. |
| READY            | 4     | int  | Flagship SDK is ready to use.                                                                                           |

\\

**Flag data shape:**

```typescript
type FlagDTO = {
  key: string;
  campaignId: string;
  variationGroupId: string;
  variationId: string;
  isReference?: boolean;
  campaignType?: string;
  slug?:string|null;
  value: any;
}
```

| Key\Property       | Type    | Description                              |
| ------------------ | ------- | ---------------------------------------- |
| key                | string  | Flag name                                |
| campaignId         | string  | Campaign ID                              |
| campaignName       | string  | Campaign name                            |
| variationGroupId   | string  | Variation group ID                       |
| variationGroupName | string  | Variation group name                     |
| variationId        | string  | The variation ID assigned to the visitor |
| variationName      | string  | Variation name                           |
| isReference        | boolean | Specify if its the reference variation   |
| slug               | string  | campaign slug                            |
| value              | any     | Value of flag                            |

\\

**LogLevel**

LogLevel is an enum defined the level of log to receive

| Key       | Value | Type | Description                               |
| --------- | ----- | ---- | ----------------------------------------- |
| NONE      | 0     | int  | Logging will be disabled.                 |
| EMERGENCY | 1     | int  | Only emergencies will be logged           |
| ALERT     | 2     | int  | Only alerts and above will be logged.     |
| CRITICAL  | 3     | int  | Only critical and above will be logged.   |
| ERROR     | 4     | int  | Only errors and above will be logged.     |
| WARNING   | 5     | int  | Only warnings and above will be logged.   |
| NOTICE    | 6     | int  | Only notices and above will be logged.    |
| INFO      | 7     | int  | Only info logs and above will be logged.  |
| DEBUG     | 8     | int  | Only debug logs and above will be logged. |
| ALL       | 9     | int  | Everything will be logged.                |

\\

**IFlagshipLogManager**

The aims of this Interface is to define methods that an object must have in order to receive Flagship SDK logs

```typescript
interface IFlagshipLogManager {
  emergency(message: string, tag: string): void;
  alert(message: string, tag: string): void;
  critical(message: string, tag: string): void;
  error(message: string, tag: string): void;
  warning(message: string, tag: string): void;
  notice(message: string, tag: string): void;
  info(message: string, tag: string): void;
  debug(message: string, tag: string): void;
  log(level: LogLevel, message: string, tag: string): void;
}
```

```
  <th style={{ textAlign: "left" }}>
    Type
  </th>

  <th style={{ textAlign: "left" }}>
    Description
  </th>
</tr>
```

```
  <td style={{ textAlign: "left" }}>
    string
  </td>

  <td style={{ textAlign: "left" }}>
    Get a description of the log
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    tag
  </td>

  <td style={{ textAlign: "left" }}>
    string
  </td>

  <td style={{ textAlign: "left" }}>
    Get the function that triggered the log
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    level
  </td>

  <td style={{ textAlign: "left" }}>
    number
  </td>

  <td style={{ textAlign: "left" }}>
    Get the log level.  

    * \*Note: *only for log method*\*\* [see `LogLevel`](#loglevel)
  </td>
</tr>
```

| Argument |
| -------- |
| message  |

Usage :

```javascript
import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdk";
import * as Sentry from "@sentry/react-native";

const customLog = {
  emergency(message, tag) {
    this.log(LogLevel.EMERGENCY, message, tag);
  },

  alert(message, tag) {
    this.log(LogLevel.ALERT, message, tag);
  },

  critical(message, tag) {
    this.log(LogLevel.CRITICAL, message, tag);
  },

  error(message, tag) {
    this.log(LogLevel.ERROR, message, tag);
  },

  warning(message, tag) {
    this.log(LogLevel.WARNING, message, tag);
  },

  notice(message, tag) {
    this.log(LogLevel.NOTICE, message, tag);
  },

  info(message, tag) {
    this.log(LogLevel.INFO, message, tag);
  },

  debug(message, tag) {
    this.log(LogLevel.DEBUG, message, tag);
  },

  log(level, message, tag) {
    Sentry.captureMessage(`[${LogLevel[level]}] [${tag}] : ${message}`);
  },
};

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY" // <= Required in next major release
      visitorData={{
        id: "YOUR_VISITOR_ID",
        context: {
          // some context
        },
        isAuthenticated: false,
      }}
      logManager={customLog},
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);
```

\\

**trackingManagerConfig**

The SDK allows you to send hits with a batching system, there is 3 options to configure it : `cacheStrategy`, `poolMaxSize` and `batchIntervals`.

The advantage of batch processing with the TrackingManager is to use less network traffic, avoid loss of hits with cache, and catch all hits that would failed and resend them.

All hits will first be added into an internal pool as they are emitted by visitors. And This pool is going to be emptied by batching all hits from the pool and then sending the batch when the `poolMaxSize` is reached or when the `batchIntervals` timer is triggered.

If a batch fails, all of the hits inside the failed batch will be added back into the pool for future iteration, the cache will be updated depending on the cache strategy used.

At any time, when your app is about to close or crash, you should call [`useFlagship().close()`](#useflagship) or `Flagship.close()` to batch and send all hits that are in the pool.

**options:**

```
  <th style={{ textAlign: "left" }}>
    Type
  </th>

  <th style={{ textAlign: "left" }}>
    Default value
  </th>

  <th style={{ textAlign: "left" }}>
    Description
  </th>
</tr>
```

```
  <td style={{ textAlign: "left" }}>
    CacheStrategy | number
  </td>

  <td style={{ textAlign: "left" }}>
    `CONTINUOUS_CACHING`: 0
  </td>

  <td style={{ textAlign: "left" }}>
    Define the strategy that will be used for hit caching\
    [see cacheStrategy](#cachestrategy)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    poolMaxSize
  </td>

  <td style={{ textAlign: "left" }}>
    number
  </td>

  <td style={{ textAlign: "left" }}>
    `10`
  </td>

  <td style={{ textAlign: "left" }}>
    Define the minimum number of hits the pool must reach to automatically batch all hits in the pool and send it  

    * \*Note\*\*:  
    * Must be greater than 5 otherwise default value will be used  
    * Having a large poolMaxSize can lead to performance issues
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    batchIntervals
  </td>

  <td style={{ textAlign: "left" }}>
    number
  </td>

  <td style={{ textAlign: "left" }}>
    `5s`
  </td>

  <td style={{ textAlign: "left" }}>
    Define a regular interval in seconds to trigger batch processing  

    * \*Note\*\*:  
    * The process will batch all hits from the pool whether poolMaxSize is reached or not  
    * Must be between 1sec and 10800s (3hours). Otherwise default value will be applied
  </td>
</tr>
```

| Key           |
| ------------- |
| cacheStrategy |

\\

**CacheStrategy**

`cacheStrategy` is an enum defining the different caching strategies

```
  <th style={{ textAlign: "left" }}>
    Type
  </th>

  <th style={{ textAlign: "left" }}>
    value
  </th>

  <th style={{ textAlign: "left" }}>
    Description
  </th>
</tr>
```

```
  <td style={{ textAlign: "left" }}>
    number
  </td>

  <td style={{ textAlign: "left" }}>
    0
  </td>

  <td style={{ textAlign: "left" }}>
    When a hit is emitted, it will be first cached in database using [IHitCacheImplementation](#hit-cache) and added into the pool, then after batching and sending, it will also be flushed from database using [IHitCacheImplementation](#hit-cache).  

    * \*Note\*\*: the SDK has a default cache implementation for React-Native using `@react-native-async-storage/async-storage`  
    * \*Note\*\*: recommended
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    PERIODIC\_CACHING
  </td>

  <td style={{ textAlign: "left" }}>
    number
  </td>

  <td style={{ textAlign: "left" }}>
    1
  </td>

  <td style={{ textAlign: "left" }}>
    When a hit is emitted, it will be added into the pool, then after batching and sending, all database hits will be flushed, then the entire pool will be cached using [IHitCacheImplementation](#hit-cache) for both actions.
  </td>
</tr>
```

| Key                   |
| --------------------- |
| CONTINUOUS\\\_CACHING |

```typescript
import React from "react";
import { FlagshipProvider, CacheStrategy } from "@flagship.io/react-sdk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY" 
      visitorData={{
        id: "YOUR_VISITOR_ID",
        context: {
          // some context
        },
        isAuthenticated: false,
      }}
      trackingManagerConfig={{
        cacheStrategy: CacheStrategy.CONTINUOUS_CACHING,
        poolMaxSize: 10,
        batchIntervals: 5
    }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);
```

> 📘
>
> * The `CONTINUOUS_CACHING strategy` (`recommended` ) should be used when your application is running in an environment where the probability of data loss is high.
>
> Keep in mind that this strategy can do a lot of database I/O depending on how many hits your visitor can send.
>
> * The `PERIODIC_CACHING strategy` should be used when your application sends a lot of hits and the probability of data loss is low.
>
> In this strategy, the number of I/Os in the database is low.

\
\\

#### `useFlagship`

Demo:

* [to get flags](#getting-flags)
* [to fetch flags](#fetching-flags)
* [manage consent](#managing-visitor-consent)
* [experience continuity](#experience-continuity)
* [to send hits tracking](#hit-tracking)

This is the most used hook from the Flagship React Native SDK. It gives further functionalities such as getting current flags of your actual visitor, sending hit tracking, checking SDK status...

Returns an object. *(Typescript: UseFlagshipOutput)*

**`useFlagship output`**

```
  <th style={{ textAlign: "left" }}>
    Type
  </th>

  <th style={{ textAlign: "left" }}>
    Description
  </th>
</tr>
```

```
  <td style={{ textAlign: "left" }}>
    string
  </td>

  <td style={{ textAlign: "left" }}>
    A unique identifier for the current visitor
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    anonymousId
  </td>

  <td style={{ textAlign: "left" }}>
    string
  </td>

  <td style={{ textAlign: "left" }}>

  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    context
  </td>

  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    A dataset (object) that defines the current visitor.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    setConsent
  </td>

  <td style={{ textAlign: "left" }}>
    function(hasConsented: boolean): void
  </td>

  <td style={{ textAlign: "left" }}>
    Set if visitor has consented for protected data usage.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    hasConsented
  </td>

  <td style={{ textAlign: "left" }}>
    boolean
  </td>

  <td style={{ textAlign: "left" }}>
    Return True if the visitor has consented for private data usage, otherwise return False.
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    updateContext
  </td>

  <td style={{ textAlign: "left" }}>
    function(context: Record\<string, boolean|string|number>): void
  </td>

  <td style={{ textAlign: "left" }}>
    Update the visitor context values, matching the given keys, used for targeting. A new context value associated with this key will be created if there is no previous matching value. Context keys must be String, and values types must be one of the following : Number, Boolean, String.\
    [See description](#useflagship-output-updatecontext).
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    clearContext
  </td>

  <td style={{ textAlign: "left" }}>
    function(): void
  </td>

  <td style={{ textAlign: "left" }}>
    Clear the actual visitor context.\
    [See description](#useflagship-output-clearcontext).
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    getFlag
  </td>

  <td style={{ textAlign: "left" }}>
    function\<T>(key: string, defaultValue: T): object
  </td>

  <td style={{ textAlign: "left" }}>
    Retrieve a Flag object by its key. If no flag match the given key an empty flag will be returned.\
    [See description](#useflagship-output-getflag)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    fetchFlags
  </td>

  <td style={{ textAlign: "left" }}>
    function(): Promise\<void>
  </td>

  <td style={{ textAlign: "left" }}>
    In DecisionApi Mode this function calls the Flagship Decision API to run campaign assignments according to the current visitor context and retrieve applicable flags.  

    In bucketing Mode, it checks bucketing file, validates campaigns targeting the visitor, assigns a variation and retrieve applicable flags.\
    [See description](#useflagship-output-fetchflags)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    authenticate
  </td>

  <td style={{ textAlign: "left" }}>
    function(visitorId: string): void
  </td>

  <td style={{ textAlign: "left" }}>
    Authenticate anonymous visitor\
    [See description](#useflagship-output-authenticate)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    unauthenticate
  </td>

  <td style={{ textAlign: "left" }}>
    function(): void
  </td>

  <td style={{ textAlign: "left" }}>
    This function change authenticated Visitor to anonymous visitor.\
    [See description](#useflagship-output-unauthenticate)
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    status
  </td>

  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    Gives you information about SDK current state. **[See description](#useflagship-output-status)**
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    flagsData
  </td>

  <td style={{ textAlign: "left" }}>
    array\<object>
  </td>

  <td style={{ textAlign: "left" }}>
    An array of [flag data](#flag-data-shape)"
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    hit
  </td>

  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    Gives you functions to send one or further hits. **[See description](#useflagship-output-hit)**
  </td>
</tr>

<tr>
  <td style={{ textAlign: "left" }}>
    close
  </td>

  <td style={{ textAlign: "left" }}>
    function(): Promise
  </td>

  <td style={{ textAlign: "left" }}>
    Most of the time you don't need to manually close the SDK, but when your application is about to terminate, you should call the close method of the Flagship class to avoid data loss.  

    When called, it will batch and send all hits that are in the pool before the application is closed
  </td>
</tr>
```

| Key/Property |
| ------------ |
| visitorId    |

**`useFlagship output setConsent`**

Set if visitor has consented for protected data usage.

* **`setConsent(hasConsented: boolean): void;`**

It has one argument :

| Argument     | Type    | Description                                        |
| ------------ | ------- | -------------------------------------------------- |
| hasConsented | boolean | True if the visitor has consented false otherwise. |

\\

**`useFlagship output updateContext`**

Update the visitor context values, matching the given keys, used for targeting.\
\
A new context value associated with this key will be created if there is no previous matching value.

* **`updateContext(context: Record<string, string | number | boolean>): void`**

It has one argument :

| Argument | Type   | Description            |
| -------- | ------ | ---------------------- |
| context  | object | A Set of keys, values. |

\\

**`useFlagship output clearContext`**

Clear the actual visitor context

* **`clearContext(): void`**

\\

**`useFlagship output fetchFlags`**

In DecisionApi Mode this function calls the Flagship Decision API to run campaign assignments according to the current visitor context and retrieve applicable flags.

In bucketing Mode, it checks bucketing file, validates campaigns targeting the visitor, assigns a variation and retrieve applicable flags

* **`fetchFlags(): Promise<void>`**

\\

**`useFlagship output getFlag`**

Return a [Flag](#flag-class-api) object by its key. If no flag match the given key an empty flag will be returned. Call exists() to check if the flag has been found.

* **`getFlag<T>(key:string, defaultValue: T) : IFlag<T>`**

\\

| Argument     | Type   | Description                 |
| ------------ | ------ | --------------------------- |
| key          | String | key associated to the flag. |
| defaultValue | T      | flag default value.         |

> 🚧
>
> * Default value must be one of the following type : `string`, `number`, `boolean`, `object`, `array`.

\\

**`useFlagship output authenticate`**

Authenticate anonymous visitor

* **`authenticate(visitorId: string): void`**

| Argument  | Type   | Default  | Description                          |
| --------- | ------ | -------- | ------------------------------------ |
| visitorId | string | required | id of the new authenticated visitor. |

\\

**`useFlagship output unauthenticate`**

This function change authenticated Visitor to anonymous visitor

* **`unauthenticate(): void`**

\\

**`useFlagship output hit`**

| Key/Property | Description                                                                                                                                     |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| send         | Takes an object as parameter. The object must follow a [hit shape](#hit-tracking).                                                              |
| sendMultiple | Takes an array of object as parameter. Each object must follow a [hit shape](#hit-tracking). You can mix different hit shapes within the array. |

**`useFlagship output status`**

| Key/Property | Description                                                                                                                         |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| isLoading    | If `true`, the SDK isn't ready.                                                                                                     |
| lastRefresh  | Date cast string with ISO format. This is the date corresponding to the most recent moment where modifications were saved in cache. |

> 🚧
>
> All useFlagship hook methods will be deactivated when visitor is not initialized except getFlag

\\

#### `useFsFlag`

This hook returns a [Flag](#flag-class-api) object by its key. If no flag match the given key an empty flag will be returned.

* **`useFsFlag<T>(key: string, defaultValue: T) : IFlag<T>`**

\\

| Argument     | Type   | Description                 |
| ------------ | ------ | --------------------------- |
| key          | String | key associated to the flag. |
| defaultValue | T      | flag default value.         |

\\

#### Flag class api

**`getValue` function**

To retrieve [flag](#flag-class-api) current value, simply call value() method of the Flag object.

* **`getValue(visitorExposed:boolean):T`** function

Returns the value from the assigned campaign variation or the Flag default value if the Flag does not exist, or if types are different.

```
  <th style={{ textAlign: "left" }}>
    Type
  </th>

  <th style={{ textAlign: "left" }}>
    Default Value
  </th>

  <th style={{ textAlign: "left" }}>
    Description
  </th>
</tr>
```

```
  <td style={{ textAlign: "left" }}>
    Boolean
  </td>

  <td style={{ textAlign: "left" }}>
    true
  </td>

  <td style={{ textAlign: "left" }}>
    Tells Flagship the visitor have been exposed and have seen this flag. This will increment the visits for the current variation on your campaign reporting.\
    If needed it is possible to set this param to false and call `visitorExposed()` afterward when the visitor sees it.
  </td>
</tr>
```

| Parameter      |
| -------------- |
| visitorExposed |

> 🚧
>
> Will return default value when visitor is not yet initialized

\\

**`metadata` property**

You may need to send campaign IDs or variation IDs to a third party for reporting and/or analytics purposes. It is possible to retrieve campaigns metadata for a specific Flag.

\\

* **`metadata:IFlagMetadata`**

Return the campaign information metadata or an empty object if the Flag doesn't exist or if the default value type does not correspond to the Flag type in Flagship.

```typescript
interface IFlagMetadata{
    campaignId:string
  	campaignName: string
    variationGroupId:string
  	variationGroupName:string
    variationId: string
  	variaitonName: string
    isReference: boolean
    campaignType: string
}
```

| Key\Property       | Type    | Description                              |
| ------------------ | ------- | ---------------------------------------- |
| campaignId         | string  | Campaign name                            |
| campaignName       | string  | Campaign name                            |
| variationGroupId   | string  | Variation group ID                       |
| variationGroupName | string  | Variation group name                     |
| variationId        | string  | The variation ID assigned to the visitor |
| variationName      | string  | Variation name                           |
| isReference        | boolean | Specify if its the reference variation   |

\\

**`visitorExposed` function**

By default when the method getValue() is called, The SDK considers that the visitor have seen the effets of your Flag, unless you pass false to getValue(). In this case you will have to call visitorExposed().

There are two ways for exposing a visitor to a flag:

1. Pass an `visitorExposed=true` parameter to the **getValue()** method.
2. Use the following **visitorExposed()** method from the Flag instance.

* **`visitorExposed(): Promise<void>`**

Tells Flagship the visitor have been exposed and have seen this flag. This will increment the visits for the current variation on your campaign reporting. No visitor exposure will be sent if the Flag doesn't exist or if the default value type do not correspond to the Flag type in Flagship.

* **`userExposed(): Promise<void>`** `deprecated`

Tells Flagship the visitor have been exposed and have seen this flag. This will increment the visits for the current variation on your campaign reporting. No visitor exposure will be sent if the Flag doesn't exist or if the default value type do not correspond to the Flag type in Flagship.

> 🚧
>
> `userExposed` is deprecated, use `visitorExposed` instead

\\

**`exists` function**

This method will return true if a Flag exists in Flagship

* **`exists(): boolean`**

\
\\

### Getting flags

#### with useFsFlag hook

**Demo:**

```javascript
import React from "react";
import { useFsFlag } from "@flagship.io/react-native-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const flag = useFsFlag("backgroundColor","green")
  const flagExists = flag.exists()
  const flagMetadata = flag.metadata
  
  return (
    <Button
    	onPress={()=>{
				// Report the flag exposure 
  			flag.visitorExposed()
  		}}
      style={{
        height: "200px",
        width: "200px",
        backgroundColor: flag.getValue(),
      }}
      
      title={"I'm a square with color=" + flag.getValue()}
    >
    </Button>
  );
};
```

#### with useFlagship hook

**Demo:**

```javascript
import React from "react";
import { useFlagship } from "@flagship.io/react-native-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { getFlag } = useFlagship()
  const flag = getFlag("backgroundColor","green")
  const flagExists = flag.exists()
  const flagMetadata = flag.metadata
  
  return (
    <Button
      style={{
        height: "200px",
        width: "200px",
        backgroundColor: flag.getValue(),
      }}
      title={"I'm a square with color=" + flag.getValue()}
    >
    </Button>
  );
};
```

\\

### Report a Flag exposure

\\

```javascript
import React from "react";
import { useFsFlag } from "@flagship.io/react-native-sdkk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const flag = useFsFlag("backgroundColor","green")
  const flagExists = flag.exists()
  const flagMetadata = flag.metadata
  
  return (
    <Button
    	onPress={()=>{
				// Report the flag exposure
  			flag.visitorExposed()
  		}}
      style={{
        height: "200px",
        width: "200px",
        backgroundColor: flag.getValue(),
      }}
      title={"I'm a square with color=" + flag.getValue()}
    >
    </Button>
  );
};
```

```javascript
import React from "react";
import { useFlagship } from "@flagship.io/react-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { getFlag } = useFlagship()
  const flag = getFlag("backgroundColor","green")
  const flagExists = flag.exists()
  const flagMetadata = flag.metadata
  
  return (
    <Button
    onPress={()=>{
				// Report the flag exposure 
  			flag.visitorExposed()
  		}}
      style={{
        height: "200px",
        width: "200px",
        backgroundColor: flag.value(),
      }}
      title={"I'm a square with color=" + flag.getValue()}
    > </Button>
  );
};
```

### Fetching Flags

#### with useFlagship hook

**Demo:**

```javascript
import React from "react";
import { useFlagship } from "@flagship.io/react-native-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { fetchFlags } = useFlagship()
  
  return (
    <Button
    	onPress={()=>{
  			fetchFlags().then(()=>{
    		// Notify success...
    		})
    	title={"Trigger a fetch flag"}
  	}}>
      
    </Button>
  );
};
```

\
\\

### Managing visitor consent

With `Flagship React Native SDK`, you can manage visitor consent for data privacy usage. When False, ***campaign activation*** and ***hits*** will be disabled.

There are 2 ways to set visitor consent :

1. Set `hasConsented` key to true or false in props VisitordData of FlagshipProvider
2. Use `setConsent` method of `useFlagship` hook

\\

**Demo:**

```javascript
import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY"
      visitorData={{
        id: null, // or remove this line
        context: {
          // some context
        },
  	hasConsented: true, // set hasConsented to true or false
      }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);
```

```javascript
import React from "react";
import { useFlagship } from "@flagship.io/react-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { setConsent } = useFlagship()
  
  return (
    <Button
    	onPress={()=>{
    
  			setConsent(true)
   
  	}}
		title={"Accept consent"}
		></Button>
  );
};
```

> 📘
>
> When a visitor sets consent to false, the data collection features (visitorExposed and sendHit) will be deactivated for them and all hits related to the visitor will be flushed from the pool and the cache.

\
\\

### Update context with predefined keys of context

**Demo:**

```javascript
import React from "react";
import { FlagshipProvider, DEVICE_LOCALE } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY"
      visitorData={{
        id: null, // or remove this line
        context: {
          [DEVICE_LOCALE]: "fr",
        },
  			hasConsented: true, // set hasConsented to true or false
      }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);
```

```javascript
import React from "react";
import { useFlagship } from "@flagship.io/react-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { updateContext } = useFlagship()
  
  return (
    <Button
    	onPress={()=>{
    
  			updateContext({
         [DEVICE_LOCALE]: "fr"
        })
    
  	}}
		title={"Trigger update context"}
		></Button>
  );
};
```

[Learn more](#predefined-visitor-context-keys) about predefined keys of context

\
\\

### Experience continuity

> 🚧
>
> Make sure that the experience continuity option is enabled on the flagship platform before using those methods.

It might happen that a visitor from your app is not yet recognized and is being authenticated (and recognized) later on...

From there, we provide the ability to ensure that during such transition, your visitor will keep same experience (meaning targetting still the same campaign's variations and thus same modifications).

In order to do a successful experience continuity, we will have to distinguish when the visitor is **anonymous** or **authenticated**.

Let's assume basic scenario to understand how things work:

**1. Your visitor arrives on your app for the first time**

We need to initialize the visitor but as we don't know anything about this visitor, we'll create a random visitor id or let the SDK do it for us. You can also specify some visitor context if necessary.

```javascript
import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdkk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY"
      visitorData={{
        id: null, // or remove this line
        context: {
          // some context
        },
        isAuthenticated: false, //
      }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);
```

Whatever how it has been set, the actual visitor id will be what we call its **anonymous id**.

> 📘
>
> Be aware that when you do not specify a visitor id, as `enableClientCache` is enable by default, the SDK will try to find a previous visitor experience. If so, the new visitor will have the same visitor id as it was during the previous visitor session. From there, no id will be automatically generated.

2. Your visitor is signing in.

We need to set the value of `visitorData.isAuthenticated` to `true` or call the method `authenticate` of `useFlagship` hook.

Moreover, the visitor id set should be an existing visitor id (that has previously seen specific campaign's flags) in order to make the experience continuity effective.

```javascript
import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY"
      visitorData={{
        id: "AUTHENTICATED_ID",
        context: {
          // some context
        },
        isAuthenticated: true,
      }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);
```

```javascript
import React from "react";
import { useFlagship } from "@flagship.io/react-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { authenticate } = useFlagship()
  
  return (
    <Button
    	onPress={()=>{
    
  			// ... sign in code
    
    		authenticate("AUTHENTICATED_ID")
    
    	})
  	}}
      title={"Trigger sign in"}
      ></Button>
  );
};
```

This new visitor id is what we call its **authenticated id**.

The visitor is updated as authenticated, keeping the previous variations from campaigns that are still matched and thus gives you same modifications as before being logged in.

> 📘
>
> Keep in mind that if the visitor also has its context changed, you might still have changes on flags as your visitor might target new campaigns.

3. Your visitor decide to sign out.

We need to set the value of `visitorData.isAuthenticated` back to `false`.

If you want to keep the same visitor (anonymous) experience as before, depending on the value of prop `enableClientCache`, you'll have to:

* `enableClientCache=true`: the sdk will put back the previous anonymous id\
  automatically based on data from cache.

```javascript
import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY"
      visitorData={{
        id: null,
        context: {
          // some context
        },
        isAuthenticated: false, // <--- back to false
      }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);
```

```javascript
import React from "react";
import { useFlagship } from "@flagship.io/react-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { unauthenticate } = useFlagship()
  
  return (
    <Button
    	onPress={()=>{
    
  			// ... sign out code
    
    		unauthenticate()
    
    		
    	})
  	}}
      title={"Trigger sign out"}
      ></Button>
  );
};
```

* `enableClientCache=false`: you should specify in\
  `visitorData.id\` prop, the same value as you set in step 1.

```javascript
import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY"
      visitorData={{
        id: "YOUR_VISITOR_ID", // <--- same value as step 1
        context: {
          // some context
        },
        isAuthenticated: false, // <--- back to false
      }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);
```

If you need a completly brand new visitor experience, you should put a new visitor id in `visitorData.id` prop instead:

```javascript
import React from "react";
import { FlagshipProvider } from "@flagship.io/react-native-sdk";

const App = () => (
  <>
    <FlagshipProvider
      envId="YOUR_ENV_ID"
      apiKey="YOUR_API_KEY"
      visitorData={{
        id: "YOUR_BRAND_NEW_VISITOR_ID", // <--- new value
        context: {
          // some context
        },
        isAuthenticated: false, // <--- back to false
      }}
    >
      {/* [...] */}
    </FlagshipProvider>
  </>
);
```

### Hit Tracking

\\

This section helps you track your visitors in your application and learn how to build hits in order to feed your reports. For more information about our measurement protocol, read our [Universal Collect documentation](doc:universal-collect-documentation).

There are five different types of Hits available:

* Page
* Screen
* Transaction
* Item
* Event

**HitType**

```javascript
import React from "react";
import { useFlagship, HitType } from "@flagship.io/react-native-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { hit: fsHit } = useFlagship()
  
  return (
    <Button
    	onPress={()=>{
    
    		const pageHit = {
          type: HitType.PAGE,
          documentLocation: "https://localhost",
        }
				
  			fsHit.send(pageHit).then(()=>{
        		// Notify success
        }).catch(()=>{
        		// Notify error
        })
  		}}
			title={"Send a hit"}
    >
    </Button>
  );
};
```

| Key         | type   | Value       | Description                         |
| ----------- | ------ | ----------- | ----------------------------------- |
| PAGE        | string | PAGEVIEW    | Visitor has seen a URL.             |
| SCREEN      | string | SCREENVIEW  | Visitor has seen a screen.          |
| TRANSACTION | string | TRANSACTION | Visitor has made a transaction.     |
| ITEM        | string | ITEM        | Item bought in a transaction.       |
| EVENT       | string | EVENT       | Visitor has made a specific action. |

\\

**They must all be built and sent with the following functions from the\`useFlagship hook**

\\

```javascript
import React from "react";
import { useFlagship, HitType } from "@flagship.io/react-native-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { hit: fsHit } = useFlagship()
  
  return (
    <Button
    	onPress={()=>{
    
    fsHit.send({
      type: HitType.PAGE,
      documentLocation: "https://localhost"
    })
    
   		 // or send multiple
    		
    fsHit.sendMultiple(
      {
        type: HitType.PAGE,
        documentLocation: "https://localhost"
      },
      {
        type: HitType.SCREEN,
        documentLocation: "home"
      }
    )
  }}
		title={"Send a hit"}
    >
      Send a hit
    </Button>
  );
};
```

\\

**`useFlagship output hit.send` function**

Send Hit to Flagship servers for reporting.

* **`send (hit: IHit): Promise<void>`**

| Parameter | Type   | Default  | Description                   |
| --------- | ------ | -------- | ----------------------------- |
| hit       | object | required | Hit to send. [see Hit](#page) |

\\

**`useFlagship output hit.sendMultiple` function**

Send Hits to Flagship servers for reporting.

* **`sendMultiple(hits: IHit[]): Promise<void>`**

| Parameter | Type           | Default  | Description                            |
| --------- | -------------- | -------- | -------------------------------------- |
| hit       | Array\<object> | required | A set of Hit to send. [see Hit](#page) |

\\

#### Hit common optional parameters

\\

```javascript
import React from "react";
import { useFlagship, HitType } from "@flagship.io/react-native-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { hit: fsHit } = useFlagship()
  
  return (
    <Button
    onPress={()=>{
    
    fsHit.send({
      type: HitType.PAGE,
      documentLocation: "https://localhost",
      userIp: "127.0.0.1",
      screenResolution: "800X600",
      locale: "fr",
      sessionNumber: "1234"
    })
  }}
	title={"Send a hit"}
	></Button>
  );
};
```

\\

| Parameter        | Type   | Description                   |
| ---------------- | ------ | ----------------------------- |
| userIp           | String | (Optional) Visitor IP         |
| screenResolution | string | (Optional) Screen resolution. |
| locale           | String | (Optional) Visitor language   |
| sessionNumber    | string | (Optional) Session number     |

\\

#### Page

\\

This hit should be sent each time a visitor arrives on a new page.

```javascript
import React from "react";
import { useFlagship, HitType } from "@flagship.io/react-native-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { hit: fsHit } = useFlagship()
  
  return (
    <Button
    	onPress={()=>{
				
  			fsHit.send({
          type: HitType.PAGE, //or "PAGEVIEW",
          documentLocation: "https://www.my_domain_com/my_page"
        })
  		}}
			title={"Send a hit"}
    ></Button>
  );
};
```

\\

* A hit of type `Page` has the following structure:

| Key/Property     | Type                | Default  | Description                          |
| ---------------- | ------------------- | -------- | ------------------------------------ |
| type             | string (`PAGEVIEW`) | required | type of hit. [see HitType](#hittype) |
| documentLocation | String              | required | Valid url.                           |

\\

#### Screen

\\

This hit should be sent each time a visitor arrives on an interface on client side.

```javascript
import React from "react";
import { useFlagship, HitType } from "@flagship.io/react-native-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { hit: fsHit } = useFlagship()
  
  return (
    <Button
    	onPress={()=>{
  			fsHit.send({
          type: HitType.SCREEN, //or "SCREENVIEW",
          documentLocation: "home_screen"
        })
  		}}
			title={"Send a hit"}
    ></Button>
  );
};
```

\\

* A hit of type `Screen` has the following structure:

| Key/Property     | Type                  | Default  | Description                          |
| ---------------- | --------------------- | -------- | ------------------------------------ |
| type             | string (`SCREENVIEW`) | required | Type of hit. [see HitType](#hittype) |
| documentLocation | String                | required | Name of screen.                      |

\\

#### Transaction

\\

This hit should be sent when a visitor completes a Transaction.

```javascript
import React from "react";
import { useFlagship, HitType } from "@flagship.io/react-native-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { hit: fsHit } = useFlagship()
  
  return (
    <Button
    	onPress={()=>{
				
  			fsHit.send({
          type: HitType.TRANSACTION, //or "TRANSACTION"
          transactionId: "#12345",
          affiliation: "affiliation",
          taxes: 19.99,
          currency: "USD",
          couponCode: "code",
          itemCount: 1,
          shippingMethod: "road",
          shippingCosts: 5,
          paymentMethod: "credit_card",
          totalRevenue: "199.99"
        })
  		}}
			title={"Send a hit"}
    ></Button>
  );
};
```

\\

A hit of type `TRANSACTION` has the following structure:

| Key/Property   | Type                   | Default  | Description                                                                                                                                                  |
| -------------- | ---------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| type           | string (`TRANSACTION`) | required | Type of hit. [see HitType](#hittype)                                                                                                                         |
| transactionId  | String                 | required | Unique identifier for your transaction.                                                                                                                      |
| affiliation    | String                 | required | The name of the KPI that you will have inside your reporting. [**Learn more**](https://github.com/flagship-io/Gitbook/blob/main/docs/glossary/README.md#kpi) |
| totalRevenue   | float                  | optional | Specifies the total revenue associated with the transaction. This value should include any shipping and/or tax amounts.                                      |
| shippingCosts  | float                  | optional | The total shipping cost of your transaction.                                                                                                                 |
| shippingMethod | String                 | optional | The shipping method for your transaction.                                                                                                                    |
| taxes          | float                  | optional | Specifies the total amount of taxes in your transaction.                                                                                                     |
| currency       | String                 | optional | Specifies the currency of your transaction. NOTE: This value should be a valid ISO 4217 currency code.                                                       |
| paymentMethod  | String                 | optional | Specifies the payment method used for your transaction.                                                                                                      |
| itemCount      | int                    | optional | Specifies the number of items in your transaction.                                                                                                           |
| couponCode     | String                 | optional | Specifies the coupon code used by the customer in your transaction.                                                                                          |

\\

#### Item

\\

This hit is used to link an item with a transaction. It must be sent after the corresponding transaction hit.

```javascript
import React from "react";
import { useFlagship, HitType } from "@flagship.io/react-native-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { hit: fsHit } = useFlagship()
  
  return (
    <Button
    	onPress={()=>{
				
  			fsHit.send({
          type: HitType.ITEM, //or "ITEM"
          transactionId: "#12345",
          productName: "product",
          productSku: "sku123",
          itemPrice: 199.99,
          itemQuantity: 1,
          itemCategory: "test"
        })
    
  		}}
			title={"Send a hit"}
    ></Button>
  );
};
```

\\

A hit of type `ITEM` has the following structure:

| Key/Property  | Type            | Default  | Description                                      |
| ------------- | --------------- | -------- | ------------------------------------------------ |
| type          | string (`ITEM`) | required | Type of hit. [see HitType](#hittype)             |
| transactionId | String          | required | Unique identifier for your transaction.          |
| productName   | String          | required | Name of your item.                               |
| productSku    | String          | required | Specifies the SKU or item code.                  |
| itemCategory  | String          | optional | Specifies the category that the item belongs to. |
| itemPrice     | float           | optional | Specifies the price for a single item/unit.      |
| itemQuantity  | int             | optional | Specifies the number of items purchased.         |

#### Event

This hit can be used for any event (e.g. Add To Cart click, newsletter subscription).

\\

```javascript
import React from "react";
import { useFlagship, HitType } from "@flagship.io/react-native-sdk";
import { Button } from "react-native";

export const MyReactComponent = () => {
  const { hit: fsHit } = useFlagship()
  
  return (
    <Button
    	onPress={()=>{
				
  			fsHit.send({
          type: HitType.EVENT, //or "EVENT"
          category: EventCategory.USER_ENGAGEMENT, // or EventCategory.ACTION_TRACKING
          action: "click",
          label: "label",
          value: 100,
        })
    
  		}}
			title={"Send a hit"}
    ></Button>
  );
};
```

\\

A hit of type `EVENT` has the following structure:

| Key/Property | Type             | Default  | Description                                                                                                                                                                                 |
| ------------ | ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type         | string (`EVENT`) | required | Type of hit. [see HitType](#hittype)                                                                                                                                                        |
| category     | string           | required | <p>Specifies the category of your event. NOTE: This value must be either <strong><code>User Engagement</code></strong> or <strong><code>Action Tracking</code></strong>.<br></p>            |
| action       | string           | required | Event name that will also serve as the KPI that you will have inside your reporting. [**Learn more**](https://github.com/flagship-io/Gitbook/blob/main/docs/glossary/README.md#kpi)         |
| label        | string           | optional | Additional description of your event.                                                                                                                                                       |
| value        | integer          | optional | <p>(optional) Can be used to evaluate visitor interactions with individual site objects or content items.<br><strong>NOTE</strong>: <em>this value must be non-negative/ non-float</em></p> |

### Managing visitor cache

The aims of the cache management is the response to the following problematic:

* **Re-allocation in bucketing mode :**

In bucketing mode, the SDK will always keep visitor in variation where he was allocated first, in case of the customer or the dynamic allocation has changed the traffic allocation. Indeed in bucketing mode the assignation is made on local device so changing campaign allocation in the platform would make visitors to see different campaigns.

* **Handle offline mode on client side :**

With the cache enabled, the SDK will try to retrieve the latest visitor data (campaign assignations) from the cache, also will save all the failed hits and visitorExposed in order to resend them later.

\\

By default the Flagship ReactJS SDK provide a default cache manager implementation. It is possible to use your own cache manager by implementing the intefaces `IVisitorCacheImplementation` and `IHitCacheImplementation` through visitorCacheImplementation and hitCacheImplementation props of [FlagshipProvider](#flagshipprovider).

#### Visitor Cache

The visitor cache is used to store the visitor data in a database through the `IVisitorCacheImplementation` interface which defines the methods that an object must implement in order to handle it.

```typescript
interface IVisitorCacheImplementation {
  cacheVisitor: (visitorId: string, Data: VisitorCacheDTO) => void;
  lookupVisitor(visitorId: string): VisitorCacheDTO;
  flushVisitor(visitorId: string): void;
}
```

\\

**`cacheVisitor` function**

This method is called when the SDK needs to cache visitor information in your database.

* **`public cacheVisitor(visitorId: string, Data: object):void`**

It has 2 arguments :

| Argument  | Type   | Description                                                                               |
| --------- | ------ | ----------------------------------------------------------------------------------------- |
| visitorId | string | visitor ID                                                                                |
| Data      | object | visitor data. The object follows the shape of type [`VisitorCacheDTO`](#visitorcachedto). |

\\

**`lookupVisitor` function**

This method is called when the SDK needs to get the visitor information corresponding to visitor ID from your database.

It has to return an object of type `VisitorCacheDTO` which follows this shape [see](#visitorcachedto).

* **`public lookupVisitor(visitorId: string): object`**

It has one argument :

| Argument  | Type   | Description |
| --------- | ------ | ----------- |
| visitorId | string | visitor ID  |

**`flushVisitor` function**

This method is called when the SDK needs to erase the visitor information corresponding to visitor ID in your database.

It will be called every time [`setConsent`](#setconsent-function) get false.

* **`public flushVisitor(visitorId: string): void`**

It has one argument :

| Argument  | Type   | Description |
| --------- | ------ | ----------- |
| visitorId | string | visitor ID  |

\\

> 📘
>
> * `flushVisitor` method will be called every time [`setConsent`](#setconsent-function) get false.

\\

**VisitorCacheDTO**

```typescript
type VisitorCacheDTO = {
  version: number;
  data: {
    visitorId: string;
    anonymousId: string | null;
    consent?: boolean;
    context?: Record<string, boolean|number|string>;
    campaigns?: Array<{
      campaignId: string;
      variationGroupId: string;
      variationId: string;
      isReference?: boolean;
      type: string;
      activated?: boolean;
      flags?: Record<string, unknown>;
    }>;
  };
};
```

#### Hit Cache

The hit cache is used to store hits in your database depending on strategy used through the `IHitCacheImplementation` interface which defines the methods that an object must implement to handle it.

```typescript
interface IHitCacheImplementation {
    cacheHit(hits: Record<string, HitCacheDTO>):Promise<void>
    lookupHits():Promise<Record<string, HitCacheDTO>>
    flushHits(hitKeys: string[]): Promise<void>
    flushAllHits(): Promise<void>
}
```

\\

**`cacheHit` function**

This method will be called to cache hits depending on cache strategy used.

* **`public cacheHit(hits: Record<string, HitCacheDTO>):Promise<void>`**

It has 1 argument :

```
  <th style={{ textAlign: "left" }}>
    Type
  </th>

  <th style={{ textAlign: "left" }}>
    Description
  </th>
</tr>
```

```
  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    It's a key/value object where the :  

    * key  is a unique ID for each hit  
    * value is an object that follows the shape of type [`HitCacheDTO`](#hitCachedto).
  </td>
</tr>
```

| Argument |
| -------- |
| hits     |

\\

**`lookupHits` function**

This method will be called to load all hits from your database and trying to send them again in the background.

It has to return an object where the key is a unique ID for each hit and the value is an object of type `HitCacheDTO` which follows this shape [see](#hitCachedto).

* **`public lookupHits():Promise<Record<string, HitCacheDTO>>`**

\\

**`flushHits` function**

This method will be called to erase all hits matching the unique Hits ID from your database.

**NOTE:** It will be called every time [`setConsent`](#setconsent-function) get false to erase all hits from database for visitor who set consent to false.

* **`public flushHits(hitKeys: string[]): Promise<void>`**

It has one argument :

| Argument | Type           | Description       |
| -------- | -------------- | ----------------- |
| hitKeys  | Array\<string> | Unique ID of hits |

\\

**`flushAllHits` function**

This method will be called to erase all hits in your database without exception.

* **`public flushAllHits(): Promise<void>`**

\\

**HitCacheDTO**

```typescript
type HitCacheLookupDTO = {
  version: number;
  data: {
    visitorId: string;
    anonymousId: string | null;
    type: HitType | "ACTIVATE";
    time: number;
    content?: Record<string, unknown>;
  };
};
```

> 📘
>
> * The flushHits method will be called whenever the visitor's consent changes to false.
> * Hits older than 4H will be ignored during the resending process.

\
\\

### Appendix

#### Predefined visitor context keys

The Flagship SDK contains predefined visitor context keys.

The keys marked as **Yes** in the **Auto-set by SDK** column will be automatically set, while the ones marked as **No** need to be set by customer.

You can overwrite these keys at any time. The keys-value pairs will be sent to the server in the visitor context and can be edited in the [Persona](https://github.com/flagship-io/Gitbook/blob/main/docs/glossary/README.md#persona) section of the Flagship platform.

| SDK constant Name    | Description                                            | Context variable name   | Type       | Auto-set by SDK | Example       |
| -------------------- | ------------------------------------------------------ | ----------------------- | ---------- | --------------- | ------------- |
| DEVICE\_LOCALE       | Language of the device                                 | sdk\_deviceLanguage     | String     | No              | fra           |
| DEVICE\_TYPE         | Type of the device                                     | sdk\_deviceType         | DeviceType | No              | Mobile        |
| DEVICE\_MODEL        | Model of the device                                    | sdk\_deviceModel        | String     | No              | samsung E1200 |
| LOCATION\_CITY       | City geolocation                                       | sdk\_city               | String     | No              | toulouse      |
| LOCATION\_REGION     | Region geolocation                                     | sdk\_region             | String     | No              | occitanie     |
| LOCATION\_COUNTRY    | Country geolocation                                    | sdk\_country            | String     | No              | France        |
| LOCATION\_LAT        | Current Latitude                                       | sdk\_lat                | Double     | No              | 43.623647     |
| LOCATION\_LONG       | Current Longitude                                      | sdk\_long               | Double     | No              | 1.445397      |
| OS\_NAME             | Name of the OS                                         | sdk\_osName             | String     | YES             | android / ios |
| OS\_VERSION\_NAME    | Version name of the OS                                 | sdk\_osVersionName      | String     | No              | 9.0.0         |
| OS\_VERSION\_CODE    | Version code of the OS                                 | sdk\_osVersionCode      | String     | YES             | 24            |
| CARRIER\_NAME        | Name of the carrier or mobile virtual network operator | sdk\_carrierName        | String     | No              | free          |
| INTERNET\_CONNECTION | What is the internet connection                        | sdk\_internetConnection | String     | No              | 5g            |
| APP\_VERSION\_NAME   | Version name of the app                                | sdk\_versionName        | String     | No              | 1.1.2-beta    |
| APP\_VERSION\_CODE   | Version code of the app                                | sdk\_versionCode        | String     | No              | 40            |
| INTERFACE\_NAME      | Name of the interface                                  | sdk\_interfaceName      | String     | No              | ProductPage   |
| FLAGSHIP\_CLIENT     | Flagship SDK client (Reserved)                         | fs\_client              | String     | Yes             | TS            |
| FLAGSHIP\_VERSION    | Version of the Flagship SDK (Reserved)                 | fs\_version             | String     | Yes             | 2.0.0         |
| FLAGSHIP\_VISITOR    | Current visitor id (Reserved)                          | fs\_users               | String     | Yes             | visitor\_id   |

> 📘
>
> To overwrite the keys, use the [`updateContext`](#update-context-with-predefined-keys-of-context) method

### License

This Flagship SDK is distributed under the [Apache version 2.0](http://www.apache.org/licenses/) license.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.abtasty.com/server-side/sdks/react-native/archived-versions/archived-react-native-v3-3-x.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
