PersonaClick React Native SDK is available through GitHub.
To install it, run next command in terminal:
yarn add @personaclick/react-native-sdkor
yarn add https://github.com/PersonaClick/rn-sdk.gitAlso need added AsyncStorage plugin:
yarn add @react-native-async-storage/async-storageNote
Starting from 4.0.0 we support Expo. This means that
'react-native-device-info' no longer is required.
If your app does not use Expo, you either:
-
have to install 'react-native-device-info':
yarn add react-native-device-info
-
or provide your own unique device ID generation function See 'Initialization' below
For push notification:
yarn add @react-native-firebase/app
yarn add @react-native-firebase/messaging
yarn add @notifee/react-nativeOpen your /ios/{projectName}/AppDelegate.m file, and add the following:
At the top of the file, import the Firebase SDK:
#import <Firebase.h>Open a terminal window and navigate to the location of the Xcode project for
your app
cd ios/
pod installDisable auto-registration the device
// firebase.json
{
"react-native": {
"messaging_ios_auto_register_for_remote_messages": false
}
}On iOS, when a message is received the device silently starts your application
in a background state. To get around this problem, you can configure your
application. Use this property to conditionally render null ("nothing") if your
app is launched in the background:
// index.js
import { AppRegistry } from 'react-native'
function HeadlessCheck({ isHeadless }) {
if (isHeadless) {
// App has been launched in the background by iOS, ignore
return null
}
return <App />
}
function App() {
// Your application
}
AppRegistry.registerComponent('app', () => HeadlessCheck)To inject a isHeadless prop into your app, please update your AppDelegate.m
file as instructed below:
/ add this import statement at the top of your `AppDelegate.m` file
#import "RNFBMessagingModule.h"
// in "(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions" method
// Use `addCustomPropsToUserProps` to pass in props for initialization of your app
// Or pass in `nil` if you have none as per below example
// For `withLaunchOptions` please pass in `launchOptions` object
NSDictionary *appProperties = [RNFBMessagingModule addCustomPropsToUserProps:nil withLaunchOptions:launchOptions];
// Find the `RCTRootView` instance and update the `initialProperties` with your `appProperties` instance
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"nameOfYourApp"
initialProperties:appProperties];If the iOS Background App Refresh mode is off, your handler configured in
setBackgroundMessageHandler will not be triggered.
In your android/build.gradle
buildscript {
dependencies {
...
//Add this \/
classpath 'com.google.gms:google-services:4.3.4'
}In your android/app/build.gradle add
apply plugin: 'com.google.gms.google-services'SDK is used for several tasks:
- Initialize SDK and user's session
- Events tracking
- Track custom event
- Track push
- Product recommendations
- Product search
- Save profile settings
- Init push
- Set push token notification
- Triggers
- Price drop
- Back in Stock
- Segments
- Add user to a segment
- Remove user from a segment
- Get user segments
Initialize SDK object and use it anywhere in your application. (!) Remember to
initialize SDK only once on application launch.
import PersonaClick from '@PersonaClick/react-native-sdk'
// If you do not use Expo and have 'react-native-device-info' installed
const rnsdk = new PersonaClick('YOUR_SHOP_ID', 'Stream')
// If you use Expo:
import * as Application from 'expo-application'
import * as SecureStore from 'expo-secure-store'
import 'react-native-get-random-values'
import { v4 as uuidv4 } from 'uuid'
// Use this function to create unique ID for each app Installation
// or create your own implementation
async function getDeviceId() {
if (Application.getAndroidId) {
return Application.getAndroidId()
}
let uniqueId = await SecureStore.getItemAsync('uniqueId')
if (!uniqueId) {
uniqueId = uuidv4()
await SecureStore.setItemAsync('uniqueId', uniqueId)
}
return uniqueId
}
const rnsdk = new PersonaClick('YOUR_SHOP_ID', 'Stream', false, true, {
id: await getDeviceId(),
})rnsdk.isInit() // returns true/falseTrack user's behavior to collect data. There are several types of events:
// View product (simple way)
rnsdk.track('view', 37)
// View product (try to avoid it)
rnsdk.track('view', {
id: 37,
stock: true,
})
// View product after user clicked on recommender block
rnsdk.track('view', {
id: PRODUCT_ID,
recommended_by: 'dynamic',
recommended_code: 'UNIQUE_RECOMMENDER_CODE',
})
// View product, after user clicked on search results
rnsdk.track('view', {
id: PRODUCT_ID,
recommended_by: 'full_search',
recommended_code: QUERY_STRING,
})
// ... or instant search dropdown
rnsdk.track('view', {
id: PRODUCT_ID,
recommended_by: 'instant_search',
recommended_code: QUERY_STRING,
})
// View category
rnsdk.track('category', 100500)
// Add product to cart (simple way)
rnsdk.track('cart', id)
// Add product to cart with amount and track recommender
rnsdk.track('cart', {
id: PRODUCT_ID,
amount: PRODUCT_AMOUNT,
recommended_by: 'dynamic',
recommended_code: 'UNIQUE_RECOMMENDER_CODE',
})
//Send the full current cart
rnsdk.track('cart', [
{
id: FIRST_PRODUCT_ID,
amount: FIRST_PRODUCT_AMOUNT,
},
...{
id: LAST_PRODUCT_ID,
amount: LAST_PRODUCT_AMOUNT,
},
])
// Remove product from cart
rnsdk.track('remove_from_cart', id)
// Add product to favorities
rnsdk.track('wish', id)
// Remove product from favorities
rnsdk.track('remove_wish', id)
// Track purchase (several products)
rnsdk.track('purchase', {
products: [
{ id: 37, price: 318, amount: 3 },
{ id: 187, price: 5000, amount: 1 },
],
order: 'N318',
order_price: 29999,
})
// Track user search
rnsdk.track('search', 'This is a search example')// Simple tracking
rnsdk.trackEvent('my_event')
// Tracking with custom parameters
rnsdk.trackEvent('my_event', {
category: 'event category',
label: 'event label',
value: 100,
})const params = {
code: 'CODE',
type: 'TYPE',
}
// Track user click notification
rnsdk.notificationClicked(params)
// Track Notification received
rnsdk.notificationOpened(params)const type = 'instant_search' // full_search, ...
let search_query = 'your_search_text'
rnsdk
.search({
type: type,
search_query: search_query,
// other params
})
.then((res) => {
console.log(res)
})const recommender_code = 'recommender_code'
const params = {
item: 100500,
exclude: [3, 14, 159, 26535],
search_query: 'To be or not to be',
// other params
}
rnsdk.recommend(recommender_code, params).then((res) => {
console.log(res)
})rnsdk.cart().then((res) => {
console.log(res)
})const params = {
id: 100500,
email: '[email protected]',
phone: '4400114527199',
first_name: 'John',
last_name: 'Doe',
birthday: '1990-03-11',
age: 31,
gender: 'm',
location: 'NY',
bought_something: true,
loyalty_id: '000001234567',
loyalty_card_location: 'NY',
loyalty_status: '5% discount',
loyalty_bonuses: 1123,
loyalty_bonuses_to_next_level: 1877,
fb_id: '000000000354677',
vk_id: 'vk031845',
telegram_id: '0125762968357835',
kids: [
{ gender: 'm', birthday: '2001-04-12' },
{ gender: 'f', birthday: '2015-07-28' },
],
auto: [{ brand: 'Nissan', model: 'Qashqai', vds: 'TM7N243E4G0BJG978' }],
}
rnsdk.setProfile(params)rnsdk.getProfile().then((res) => {
console.log(res)
})//Set use Firebase messaging only. Call this method before initPush;
rnsdk.firebase_only(true);
// Simple init
rnsdk.initPush();
//onClick listener
rnsdk.initPush(onClickCallback);
// onReceivetive listener
rnsdk.initPush(false, onReceiveCallback);
// you can use different callback for notification, when app is in background.
rnsdk.initPush(false, onReceiveCallback, onBackgroundReceiveCallback);
// If onBackgroundReceiveCallback not specified, used onReceiveCallback listener.
// onClickCallback params
{
"data": {
"body": "MESSAGE_BODY",
"icon": "MESSAGE_ICON",
"id": "MESSAGE_ID",
"image": "MESSAGE_IMAGE",
"title": "MESSAGE_TITLE",
"type": "MESSAGE_TYPE"
},
"from": "MESSAGE_FROM",
"messageId": "FMC_MESSAGE_ID",
"sentTime": TIMESTAMP,
"ttl": TTL_VALUE
}
// onReceiveCallBack, onBackgroundReceiveCallback params
{
"data": {
"action_urls": "[]",
"actions": "[]",
"body": "MESSAGE_BODY",
"icon": "MESSAGE_ICON",
"id": "MESSAGE_ID",
"image": "MESSAGE_IMAGE",
"title": "MESSAGE_TITLE",
"type": "MESSAGE_TYPE"
},
"from": "MESSAGE_FROM",
"messageId": "FMC_MESSAGE_ID",
"sentTime": TIMESTAMP,
"ttl": TTL_VALUE
}rnsdk.setPushTokenNotification('NEW_TOKEN')// Subscribing
rnsdk.triggers('subscribe_for_product_price', {
email: '[email protected]',
item: '3323',
price: 160,
})
// Unsubscribing from specific products
rnsdk.triggers('unsubscribe_from_product_price', {
email: '[email protected]',
item_ids: [3323, 100500, 'ABCDEF'],
})
// Unsubscribing from all products
rnsdk.triggers('unsubscribe_from_product_price', {
email: '[email protected]',
item_ids: [],
})// Subscribing
rnsdk.triggers('subscribe_for_product_available', {
email: '[email protected]',
item: '3323',
properties: { fashion_size: 'XL' },
})
// Unsubscribing from specific products
rnsdk.triggers('unsubscribe_from_product_available', {
email: '[email protected]',
item_ids: [3323, 100500, 'ABCDEF'],
})
// Unsubscribing from all products
rnsdk.triggers('unsubscribe_from_product_available', {
email: '[email protected]',
item_ids: [],
})// Subscribe user to all kids of email campaigns and SMS
rnsdk.subscriptions('manage', {
email: '[email protected]',
phone: '+100000000000',
email_bulk: true,
email_chain: true,
email_transactional: true,
sms_bulk: true,
sms_chain: true,
sms_transactional: true,
})
// Change only specific subscriptions
rnsdk.subscriptions('manage', {
email: '[email protected]',
phone: '+100000000000',
email_chain: true,
sms_bulk: true,
sms_transactional: true,
})
// Change without phone
rnsdk.subscriptions('manage', {
email: '[email protected]',
email_chain: true,
sms_bulk: true,
sms_transactional: true,
})// Using all possible identifiers
rnsdk.segments('add', {
email: '[email protected]',
phone: '+10000000000',
segment_id: 'SEGMENT_ID',
})
// With phone only
rnsdk.segments('add', {
phone: '+10000000000',
segment_id: 'SEGMENT_ID',
})
// With email only
rnsdk.segments('add', {
email: '[email protected]',
segment_id: 'SEGMENT_ID',
})
// Without any contacts: `did` is used automatically
rnsdk.segments('add', {
segment_id: 'SEGMENT_ID',
})// Using all possible identifiers
rnsdk.segments('remove', {
email: '[email protected]',
phone: '+10000000000',
segment_id: 'SEGMENT_ID',
})
// With phone only
rnsdk.segments('remove', {
phone: '+10000000000',
segment_id: 'SEGMENT_ID',
})
// With email only
rnsdk.segments('remove', {
email: '[email protected]',
segment_id: 'SEGMENT_ID',
})
// Without any contacts: `did` is used automatically
rnsdk.segments('remove', {
segment_id: 'SEGMENT_ID',
})// Using all possible identifiers
rnsdk.segments('get').then((res) => {
// segments (type: array of objects)
// each object has the following properties:
// "id" as Segment ID
// "type" as Segment Type ("dynamic", "static")
})PersonaClick React Native SDK is available under the MIT license. See the LICENSE file for more info.