zixflow-reactnative 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +1857 -325
  2. package/android/gradle.properties +1 -1
  3. package/android/src/main/java/com/zixflow/reactnative/sdk/NativeZixflowModule.kt +29 -19
  4. package/android/src/main/java/com/zixflow/reactnative/sdk/constant/Keys.kt +1 -4
  5. package/android/src/main/java/com/zixflow/reactnative/sdk/logging/NativeZixflowLoggingModule.kt +2 -2
  6. package/android/src/main/java/com/zixflow/reactnative/sdk/messaginginapp/NativeMessagingInAppModule.kt +2 -13
  7. package/ios/wrappers/utils/ZixflowConfigUtils.swift +5 -9
  8. package/lib/commonjs/types/data-pipelines.js +3 -15
  9. package/lib/commonjs/types/data-pipelines.js.map +1 -1
  10. package/lib/commonjs/utils/param-validation.js +1 -1
  11. package/lib/commonjs/utils/param-validation.js.map +1 -1
  12. package/lib/commonjs/zixflow-cdp.js +2 -10
  13. package/lib/commonjs/zixflow-cdp.js.map +1 -1
  14. package/lib/commonjs/zixflow.js.map +1 -1
  15. package/lib/module/types/data-pipelines.js +2 -15
  16. package/lib/module/types/data-pipelines.js.map +1 -1
  17. package/lib/module/utils/param-validation.js +1 -1
  18. package/lib/module/utils/param-validation.js.map +1 -1
  19. package/lib/module/zixflow-cdp.js +2 -10
  20. package/lib/module/zixflow-cdp.js.map +1 -1
  21. package/lib/module/zixflow.js +0 -6
  22. package/lib/module/zixflow.js.map +1 -1
  23. package/lib/typescript/commonjs/types/data-pipelines.d.ts +4 -20
  24. package/lib/typescript/commonjs/types/data-pipelines.d.ts.map +1 -1
  25. package/lib/typescript/commonjs/zixflow-cdp.d.ts.map +1 -1
  26. package/lib/typescript/commonjs/zixflow.d.ts +0 -5
  27. package/lib/typescript/commonjs/zixflow.d.ts.map +1 -1
  28. package/lib/typescript/module/types/data-pipelines.d.ts +4 -20
  29. package/lib/typescript/module/types/data-pipelines.d.ts.map +1 -1
  30. package/lib/typescript/module/zixflow-cdp.d.ts.map +1 -1
  31. package/lib/typescript/module/zixflow.d.ts +0 -5
  32. package/lib/typescript/module/zixflow.d.ts.map +1 -1
  33. package/package.json +4 -4
  34. package/src/types/data-pipelines.ts +4 -21
  35. package/src/utils/param-validation.ts +1 -1
  36. package/src/zixflow-cdp.ts +2 -12
  37. package/src/zixflow.ts +0 -6
  38. package/zixflow-reactnative-richpush.podspec +2 -2
  39. package/zixflow-reactnative.podspec +2 -2
package/README.md CHANGED
@@ -1,517 +1,2049 @@
1
- <p align="center">
2
- <a href="https://zixflow.com">
3
- <img src="https://zixflow.com/logo.svg" height="60">
4
- </a>
5
- </p>
1
+ # Zixflow React Native SDK - Integration Guide
6
2
 
7
- [![npm version](https://img.shields.io/npm/v/zixflow-reactnative.svg)](https://www.npmjs.com/package/zixflow-reactnative)
8
- [![npm downloads](https://img.shields.io/npm/dm/zixflow-reactnative)](https://www.npmjs.com/package/zixflow-reactnative)
9
- ![min Android SDK version is 21](https://img.shields.io/badge/min%20Android%20SDK-21-green)
10
- ![min iOS version is 13](https://img.shields.io/badge/min%20iOS%20version-13-blue)
11
- ![min Swift version is 5.3](https://img.shields.io/badge/min%20Swift%20version-5.3-orange)
12
- [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.0-4baaaa.svg)](CODE_OF_CONDUCT.md)
3
+ Welcome to the **Zixflow React Native SDK** integration guide. This comprehensive document will help you install, configure, and use the Zixflow SDK in your React Native application to track user behavior, send push notifications, display in-app messages, and more.
13
4
 
14
- # Zixflow React Native SDK
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Introduction](#introduction)
10
+ 2. [Requirements](#requirements)
11
+ 3. [Installation](#installation)
12
+ - [npm Installation](#npm-installation)
13
+ - [Yarn Installation](#yarn-installation)
14
+ 4. [iOS Setup](#ios-setup)
15
+ - [CocoaPods Integration](#cocoapods-integration)
16
+ - [Swift Package Manager Integration](#swift-package-manager-integration)
17
+ - [Push Notification Setup (APNs)](#push-notification-setup-apns)
18
+ - [Notification Service Extension](#notification-service-extension)
19
+ 5. [Android Setup](#android-setup)
20
+ - [Gradle Configuration](#gradle-configuration)
21
+ - [Firebase Cloud Messaging Setup](#firebase-cloud-messaging-setup)
22
+ 6. [Quick Start](#quick-start)
23
+ - [Basic Configuration](#basic-configuration)
24
+ - [SDK Initialization](#sdk-initialization)
25
+ 7. [Core Features](#core-features)
26
+ - [User Identification](#user-identification)
27
+ - [Event Tracking](#event-tracking)
28
+ - [Screen Tracking](#screen-tracking)
29
+ - [User Profile Attributes](#user-profile-attributes)
30
+ - [Device Attributes](#device-attributes)
31
+ - [Clearing User Identity](#clearing-user-identity)
32
+ 8. [Push Notifications](#push-notifications)
33
+ - [Requesting Permission](#requesting-permission)
34
+ - [Handling Push Notifications](#handling-push-notifications)
35
+ - [Device Token Registration](#device-token-registration)
36
+ 9. [In-App Messaging](#in-app-messaging)
37
+ - [Event Listeners](#event-listeners)
38
+ - [Message Events](#message-events)
39
+ - [Dismissing Messages](#dismissing-messages)
40
+ 10. [Location Tracking](#location-tracking)
41
+ 11. [Advanced Configuration](#advanced-configuration)
42
+ - [Region Settings](#region-settings)
43
+ - [Log Levels](#log-levels)
44
+ - [Auto-Tracking Options](#auto-tracking-options)
45
+ - [Custom API Hosts](#custom-api-hosts)
46
+ 12. [Troubleshooting](#troubleshooting)
47
+ - [Installation Issues](#installation-issues)
48
+ - [iOS Build Errors](#ios-build-errors)
49
+ - [Android Build Errors](#android-build-errors)
50
+ - [Push Notification Issues](#push-notification-issues)
51
+ - [In-App Message Issues](#in-app-message-issues)
52
+ 13. [Example Applications](#example-applications)
53
+ 14. [API Reference](#api-reference)
54
+ 15. [Support & Resources](#support--resources)
55
+
56
+ ---
15
57
 
16
- The official Zixflow SDK for React Native enables you to integrate customer engagement features—like in-app messaging and push notifications—into your app. Track customer behavior, send targeted messages, and create personalized experiences.
58
+ ## Introduction
17
59
 
18
- > 📖 Full documentation: [zixflow.com/docs/sdk/react-native](https://zixflow.com/docs/sdk/react-native/)
19
- > 🧪 Example apps: [see the `/example` directory](/example)
60
+ The **Zixflow React Native SDK** enables you to:
61
+
62
+ - **Identify users** and track their behavior across your app
63
+ - **Send targeted push notifications** via Apple Push Notification service (APNs) or Firebase Cloud Messaging (FCM)
64
+ - **Display in-app messages** to engage users at the right time
65
+ - **Track user location** to enable location-based messaging
66
+ - **Manage user profiles** with custom attributes
67
+ - **Track events and screen views** automatically or manually
68
+
69
+ The SDK is built on top of the native Zixflow iOS and Android SDKs, providing a unified TypeScript API for React Native applications.
20
70
 
21
71
  ---
22
72
 
23
- ## About Zixflow
73
+ ## Requirements
74
+
75
+ ### React Native
24
76
 
25
- Zixflow is a customer engagement platform built on proven Zixflow technology. This SDK is a customized fork of the Zixflow React Native SDK, optimized for use with the Zixflow platform.
77
+ - **React Native**: 0.60.0 or higher
78
+ - **React**: 16.8.0 or higher (for hooks support)
26
79
 
27
- ### Key Features
80
+ ### iOS
28
81
 
29
- - 📊 Customer identification and event tracking
30
- - 📲 Push notifications (iOS APN and Android FCM)
31
- - 💬 In-app messaging
32
- - 📍 Location tracking (optional)
33
- - 🎯 Personalized customer experiences
34
- - 📈 Analytics and customer data pipelines
35
- - 🔧 TypeScript support
36
- - ⚡ React Native New Architecture (TurboModules) support
82
+ - **iOS**: 13.0 or higher
83
+ - **Xcode**: 14.0 or higher
84
+ - **Swift**: 5.3 or higher
85
+ - **CocoaPods**: 1.10.0 or higher (if using CocoaPods)
86
+
87
+ ### Android
88
+
89
+ - **Android**: API level 24 (Android 7.0) or higher
90
+ - **Kotlin**: 1.6.0 or higher
91
+ - **Gradle**: 7.0 or higher
92
+
93
+ ### TypeScript (Recommended)
94
+
95
+ - **TypeScript**: 4.0 or higher
37
96
 
38
97
  ---
39
98
 
40
99
  ## Installation
41
100
 
101
+ ### npm Installation
102
+
103
+ Install the SDK using npm:
104
+
42
105
  ```bash
43
106
  npm install zixflow-reactnative
44
107
  ```
45
108
 
46
- or
109
+ ### Yarn Installation
110
+
111
+ Or install using Yarn:
47
112
 
48
113
  ```bash
49
114
  yarn add zixflow-reactnative
50
115
  ```
51
116
 
117
+ After installation, proceed with platform-specific setup for iOS and Android.
118
+
52
119
  ---
53
120
 
54
- ## Quick Start
121
+ ## iOS Setup
55
122
 
56
- ### SDK Initialization
123
+ ### CocoaPods Integration
57
124
 
58
- Here's a simplified example showing how to initialize the SDK to enable mobile features:
125
+ The Zixflow React Native SDK automatically integrates with the native iOS SDK via CocoaPods or Swift Package Manager. If you're using **React Native 0.60 or higher**, dependencies are auto-linked.
59
126
 
60
- ```ts
61
- import {
62
- Zixflow,
63
- ZixflowConfig,
64
- ZixflowLogLevel,
65
- } from 'zixflow-reactnative';
127
+ 1. **Navigate to the iOS directory**:
66
128
 
67
- useEffect(() => {
68
- const config: ZixflowConfig = {
69
- cdpApiKey: 'your-api-key', // Required
70
- migrationSiteId: 'your-site-id', // Optional, for migrating from older SDKs
71
- logLevel: ZixflowLogLevel.Debug,
72
- trackApplicationLifecycleEvents: true,
73
- inApp: {
74
- siteId: 'your-site-id', // Required for in-app messaging
75
- },
76
- push: {
77
- android: {
78
- pushClickBehavior: 'ActivityPreventRestart', // Optional
79
- },
80
- },
81
- };
129
+ ```bash
130
+ cd ios
131
+ ```
82
132
 
83
- Zixflow.initialize(config);
84
- }, []);
133
+ 2. **Install CocoaPods dependencies**:
134
+
135
+ ```bash
136
+ pod install
85
137
  ```
86
138
 
87
- > 🔑 For help finding your credentials, check out the [Quick Start Guide](https://zixflow.com/docs/sdk/react-native/quick-start-guide/).
139
+ 3. **Open the workspace in Xcode**:
88
140
 
89
- ---
141
+ ```bash
142
+ open YourApp.xcworkspace
143
+ ```
90
144
 
91
- ## Core Features
145
+ The SDK will automatically include the necessary Zixflow iOS modules:
146
+ - `ZixflowCommon`
147
+ - `ZixflowDataPipelines`
148
+ - `ZixflowMessagingPush`
149
+ - `ZixflowMessagingPushAPN` (for APNs)
150
+ - `ZixflowMessagingInApp`
92
151
 
93
- ### 👤 Identify Users
152
+ ### Swift Package Manager Integration
94
153
 
95
- Associate events and devices with customer profiles:
154
+ If you prefer **Swift Package Manager (SPM)**, you can configure your project to use the Zixflow iOS SDK directly:
96
155
 
97
- ```ts
98
- Zixflow.identify({
99
- userId: 'user123',
100
- traits: {
101
- email: 'user@example.com',
102
- firstName: 'John',
103
- lastName: 'Doe',
104
- plan: 'premium',
105
- },
106
- });
107
- ```
156
+ 1. **Open your project in Xcode**
157
+ 2. **Go to File > Add Package Dependencies**
158
+ 3. **Enter the repository URL**:
159
+ ```
160
+ https://github.com/zixflow/zixflow-ios.git
161
+ ```
162
+ 4. **Select the version**: Use `1.0.0` or higher
163
+ 5. **Add the following modules** to your app target:
164
+ - `Zixflow` (umbrella module)
165
+ - `ZixflowDataPipelines`
166
+ - `ZixflowMessagingPushAPN`
167
+ - `ZixflowMessagingInApp`
108
168
 
109
- ### 📊 Track Events
169
+ > **Note**: The example app uses SPM for the native iOS SDK integration. See `example/ios/Podfile` for reference.
110
170
 
111
- Track custom events to trigger messaging based on user behavior:
171
+ ### Push Notification Setup (APNs)
112
172
 
113
- ```ts
114
- Zixflow.track('Product Viewed', {
115
- productId: '12345',
116
- productName: 'Awesome Product',
117
- price: 49.99,
118
- category: 'Electronics',
119
- });
120
- ```
173
+ To enable **Apple Push Notifications (APNs)**:
121
174
 
122
- ### 📺 Screen Tracking
175
+ 1. **Enable Push Notifications capability** in Xcode:
176
+ - Select your app target
177
+ - Go to **Signing & Capabilities**
178
+ - Click **+ Capability** and add **Push Notifications**
123
179
 
124
- Track screen views in your app:
180
+ 2. **Enable Background Modes**:
181
+ - Add **Background Modes** capability
182
+ - Enable **Remote notifications**
125
183
 
126
- ```ts
127
- Zixflow.screen('Product Details', {
128
- productId: '12345',
129
- category: 'Electronics',
130
- });
184
+ 3. **Configure APNs certificates** in your Apple Developer account and upload them to Zixflow dashboard.
185
+
186
+ ### Notification Service Extension
187
+
188
+ To support **rich push notifications** (images, videos, action buttons), you need to add a **Notification Service Extension**:
189
+
190
+ 1. **Create a Notification Service Extension** in Xcode:
191
+ - File > New > Target > Notification Service Extension
192
+ - Name it `NotificationServiceExtension`
193
+
194
+ 2. **Add Zixflow modules to the extension** in your `Podfile`:
195
+
196
+ ```ruby
197
+ target 'NotificationServiceExtension' do
198
+ pod "ZixflowMessagingPushAPN", "~> 1.0"
199
+ pod "ZixflowMessagingPush", "~> 1.0"
200
+ pod "ZixflowDataPipelines", "~> 1.0"
201
+ pod "ZixflowCommon", "~> 1.0"
202
+ pod "ZixflowTrackingMigration", "~> 1.0"
203
+ pod "AnalyticsSwiftZixflow", "1.7.3+zixflow.1"
204
+ end
131
205
  ```
132
206
 
133
- ### 🏷️ Set Profile Attributes
207
+ 3. **Update `NotificationService.swift`**:
134
208
 
135
- Update customer profile attributes:
209
+ ```swift
210
+ import UserNotifications
211
+ import ZixflowMessagingPushAPN
136
212
 
137
- ```ts
138
- Zixflow.setProfileAttributes({
139
- plan: 'enterprise',
140
- lastSeenAt: Date.now(),
141
- preferences: {
142
- notifications: true,
143
- newsletter: true,
144
- },
145
- });
213
+ class NotificationService: UNNotificationServiceExtension {
214
+ var contentHandler: ((UNNotificationContent) -> Void)?
215
+ var bestAttemptContent: UNMutableNotificationContent?
216
+
217
+ override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
218
+ self.contentHandler = contentHandler
219
+ bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
220
+
221
+ // Use Zixflow to handle rich push
222
+ MessagingPushAPN.didReceive(request, withContentHandler: contentHandler)
223
+ }
224
+
225
+ override func serviceExtensionTimeWillExpire() {
226
+ if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
227
+ contentHandler(bestAttemptContent)
228
+ }
229
+ }
230
+ }
146
231
  ```
147
232
 
233
+ 4. **Run `pod install`** again to install extension dependencies.
234
+
148
235
  ---
149
236
 
150
- ## 📲 Push Notifications
237
+ ## Android Setup
238
+
239
+ ### Gradle Configuration
240
+
241
+ The React Native auto-linking will handle most of the Android setup. However, you need to ensure the following:
242
+
243
+ 1. **Set minimum SDK version** in `android/build.gradle`:
151
244
 
152
- This SDK supports rich push notifications using Firebase (for Android) and either Firebase or APNs (for iOS).
245
+ ```gradle
246
+ buildscript {
247
+ ext {
248
+ minSdkVersion = 24
249
+ compileSdkVersion = 34
250
+ targetSdkVersion = 34
251
+ }
252
+ }
253
+ ```
153
254
 
154
- ### Request Permission (iOS)
255
+ 2. **Add Maven repositories** in `android/build.gradle`:
155
256
 
156
- ```ts
157
- const status = await Zixflow.pushMessaging.showPromptForPushNotifications();
158
- console.log('Push permission status:', status);
257
+ ```gradle
258
+ allprojects {
259
+ repositories {
260
+ google()
261
+ mavenCentral()
262
+ maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' }
263
+ }
264
+ }
159
265
  ```
160
266
 
161
- ### Handle Push Notifications
267
+ The Zixflow Android SDK will be automatically included via the React Native module.
162
268
 
163
- ```ts
164
- // Track when user receives a notification
165
- Zixflow.pushMessaging.onMessageReceived((message) => {
166
- console.log('Notification received:', message);
167
- });
269
+ ### Firebase Cloud Messaging Setup
168
270
 
169
- // Track when user clicks on a notification
170
- Zixflow.pushMessaging.onBackgroundMessageReceived((message) => {
171
- console.log('Notification clicked:', message);
172
- });
271
+ To enable **Firebase Cloud Messaging (FCM)** for push notifications on Android:
272
+
273
+ 1. **Add Firebase to your project**:
274
+ - Go to [Firebase Console](https://console.firebase.google.com/)
275
+ - Add your Android app
276
+ - Download `google-services.json` and place it in `android/app/`
277
+
278
+ 2. **Add Google Services plugin** in `android/build.gradle`:
279
+
280
+ ```gradle
281
+ buildscript {
282
+ dependencies {
283
+ classpath 'com.google.gms:google-services:4.4.2'
284
+ }
285
+ }
286
+ ```
287
+
288
+ 3. **Apply the plugin** in `android/app/build.gradle`:
289
+
290
+ ```gradle
291
+ apply plugin: 'com.google.gms.google-services'
173
292
  ```
174
293
 
175
- Follow our [push setup guide](https://zixflow.com/docs/sdk/react-native/push/) to configure your project for push.
294
+ 4. **Configure FCM in the SDK** (shown in the initialization section below).
176
295
 
177
296
  ---
178
297
 
179
- ## 💬 In-App Messaging
298
+ ## Quick Start
299
+
300
+ ### Basic Configuration
180
301
 
181
- Display in-app messages to your users:
302
+ The SDK is configured using a `ZixflowConfig` object with several options:
182
303
 
183
- ```ts
184
- import { InAppMessageEvent, InAppMessageEventType } from 'zixflow-reactnative';
304
+ ```typescript
305
+ import { Zixflow, ZixflowConfig, ZixflowLogLevel } from 'zixflow-reactnative';
185
306
 
186
- // Register event listener
187
- Zixflow.inAppMessaging.registerEventsListener((event: InAppMessageEvent) => {
188
- switch (event.eventType) {
189
- case InAppMessageEventType.MessageShown:
190
- console.log('In-app message shown:', event.message);
191
- break;
192
- case InAppMessageEventType.MessageClicked:
193
- console.log('In-app message clicked:', event.message);
194
- break;
195
- case InAppMessageEventType.MessageDismissed:
196
- console.log('In-app message dismissed:', event.message);
197
- break;
198
- }
199
- });
307
+ const config: ZixflowConfig = {
308
+ apiKey: 'YOUR_API_KEY',
309
+ logLevel: ZixflowLogLevel.debug,
310
+ inApp: {
311
+ },
312
+ autoTrackDeviceAttributes: true,
313
+ trackApplicationLifecycleEvents: true,
314
+ };
315
+ ```
200
316
 
201
- // Dismiss message programmatically
202
- Zixflow.inAppMessaging.dismissMessage();
317
+ **Configuration Options**:
318
+
319
+ | Option | Type | Required | Description |
320
+ |--------|------|----------|-------------|
321
+ | `apiKey` | string | Yes | Your Zixflow API key |
322
+ | `logLevel` | `ZixflowLogLevel` | No | Logging level (debug, info, error, none) |
323
+ | `inApp` | object | No | Enable in-app messaging (use empty object: {}) |
324
+ | `autoTrackDeviceAttributes` | boolean | No | Automatically track device info |
325
+ | `trackApplicationLifecycleEvents` | boolean | No | Automatically track app lifecycle |
326
+
327
+ ### SDK Initialization
328
+
329
+ Initialize the SDK in your `App.tsx` or main component using `useEffect`:
330
+
331
+ ```typescript
332
+ import React, { useEffect } from 'react';
333
+ import { Zixflow, ZixflowConfig, ZixflowLogLevel } from 'zixflow-reactnative';
334
+
335
+ export default function App() {
336
+ useEffect(() => {
337
+ // Configure the SDK
338
+ const config: ZixflowConfig = {
339
+ apiKey: 'YOUR_API_KEY',
340
+ logLevel: ZixflowLogLevel.debug,
341
+ inApp: {
342
+ },
343
+ autoTrackDeviceAttributes: true,
344
+ trackApplicationLifecycleEvents: true,
345
+ };
346
+
347
+ // Initialize the SDK
348
+ Zixflow.initialize(config);
349
+
350
+ console.log('Zixflow SDK initialized');
351
+ }, []);
352
+
353
+ return (
354
+ // Your app UI
355
+ );
356
+ }
203
357
  ```
204
358
 
205
- ### Inbox Messages
359
+ > **Important**: Initialize the SDK as early as possible in your app's lifecycle, ideally in the root component's `useEffect`.
360
+
361
+ ---
206
362
 
207
- Manage inbox messages:
363
+ ## Core Features
208
364
 
209
- ```ts
210
- const inbox = Zixflow.inAppMessaging.inbox();
365
+ ### User Identification
211
366
 
212
- // Get all messages
213
- const messages = await inbox.getMessages();
367
+ Identify users to track their behavior across sessions and devices:
214
368
 
215
- // Mark message as read
216
- await inbox.markMessageOpened(messageId);
369
+ ```typescript
370
+ import { Zixflow } from 'zixflow-reactnative';
217
371
 
218
- // Delete message
219
- await inbox.markMessageDeleted(messageId);
372
+ // Identify user with ID only
373
+ Zixflow.identify({
374
+ userId: 'user-123'
375
+ });
220
376
 
221
- // Subscribe to inbox updates
222
- inbox.subscribeToMessages((messages) => {
223
- console.log('Inbox updated:', messages);
377
+ // Identify user with traits
378
+ Zixflow.identify({
379
+ userId: 'user-123',
380
+ traits: {
381
+ email: 'user@example.com',
382
+ firstName: 'John',
383
+ lastName: 'Doe',
384
+ plan: 'premium'
385
+ }
224
386
  });
225
387
  ```
226
388
 
227
- ---
389
+ **When to identify users**:
390
+ - After successful login
391
+ - When user information becomes available
392
+ - After account creation
393
+
394
+ ### Event Tracking
395
+
396
+ Track custom events to understand user behavior:
397
+
398
+ ```typescript
399
+ import { Zixflow } from 'zixflow-reactnative';
228
400
 
229
- ## 📍 Location Tracking
401
+ // Track event without properties
402
+ Zixflow.track('button_clicked');
230
403
 
231
- Track user location (optional feature):
404
+ // Track event with properties
405
+ Zixflow.track('product_viewed', {
406
+ product_id: '12345',
407
+ product_name: 'Premium Plan',
408
+ category: 'subscription',
409
+ price: 29.99
410
+ });
232
411
 
233
- ```ts
234
- Zixflow.location.setLastKnownLocation(latitude, longitude);
412
+ // Track with Map (alternative syntax)
413
+ const properties = new Map<string, any>();
414
+ properties.set('item_count', 3);
415
+ properties.set('total_amount', 89.97);
416
+ Zixflow.track('checkout_completed', properties);
235
417
  ```
236
418
 
237
- ### iOS Location Setup
419
+ **Common events to track**:
420
+ - User actions (button clicks, form submissions)
421
+ - E-commerce events (product views, purchases)
422
+ - Content interactions (article reads, video plays)
423
+ - Feature usage
238
424
 
239
- **Important:** iOS requires location permission descriptions in `Info.plist`. Add these keys or location tracking will silently fail:
425
+ ### Screen Tracking
240
426
 
241
- ```xml
242
- <key>NSLocationWhenInUseUsageDescription</key>
243
- <string>We need your location to provide personalized experiences</string>
244
- <key>NSLocationAlwaysUsageDescription</key>
245
- <string>We need your location to provide personalized experiences</string>
427
+ Track screen views to understand user navigation:
428
+
429
+ ```typescript
430
+ import { Zixflow } from 'zixflow-reactnative';
431
+
432
+ // Track screen view
433
+ Zixflow.screen('HomeScreen');
434
+
435
+ // Track screen with properties
436
+ Zixflow.screen('ProductDetailScreen', {
437
+ product_id: '12345',
438
+ category: 'electronics'
439
+ });
246
440
  ```
247
441
 
248
- Add the location pod to your `ios/Podfile`:
249
- ```ruby
250
- pod 'zixflow-reactnative/location', :path => '../node_modules/zixflow-reactnative'
442
+ **Automatic screen tracking** with React Navigation:
443
+
444
+ ```typescript
445
+ import { NavigationContainer, NavigationContainerRef } from '@react-navigation/native';
446
+ import { Zixflow } from 'zixflow-reactnative';
447
+ import React, { useRef } from 'react';
448
+
449
+ export default function App() {
450
+ const navigationRef = useRef<NavigationContainerRef>(null);
451
+ const routeNameRef = useRef<string>();
452
+
453
+ return (
454
+ <NavigationContainer
455
+ ref={navigationRef}
456
+ onReady={() => {
457
+ routeNameRef.current = navigationRef.current?.getCurrentRoute()?.name;
458
+ }}
459
+ onStateChange={async () => {
460
+ const previousRouteName = routeNameRef.current;
461
+ const currentRouteName = navigationRef.current?.getCurrentRoute()?.name;
462
+
463
+ if (previousRouteName !== currentRouteName && currentRouteName) {
464
+ // Track screen change
465
+ Zixflow.screen(currentRouteName);
466
+ }
467
+
468
+ // Save current route name
469
+ routeNameRef.current = currentRouteName;
470
+ }}
471
+ >
472
+ {/* Your navigation setup */}
473
+ </NavigationContainer>
474
+ );
475
+ }
251
476
  ```
252
477
 
253
- ### Android Location Setup
478
+ ### User Profile Attributes
254
479
 
255
- Enable location tracking in `android/gradle.properties`:
256
- ```properties
257
- zixflow_location_enabled=true
258
- ```
480
+ Set custom attributes on user profiles:
259
481
 
260
- ---
482
+ ```typescript
483
+ import { Zixflow } from 'zixflow-reactnative';
261
484
 
262
- ## Advanced Features
485
+ // Set profile attributes
486
+ Zixflow.setProfileAttributes({
487
+ plan: 'premium',
488
+ subscription_status: 'active',
489
+ last_login: new Date().toISOString(),
490
+ preferences: {
491
+ newsletter: true,
492
+ notifications: true
493
+ }
494
+ });
495
+ ```
263
496
 
264
497
  ### Device Attributes
265
498
 
266
- Set custom device attributes:
499
+ Set custom attributes on the current device:
500
+
501
+ ```typescript
502
+ import { Zixflow } from 'zixflow-reactnative';
267
503
 
268
- ```ts
504
+ // Set device attributes
269
505
  Zixflow.setDeviceAttributes({
270
- deviceModel: 'iPhone 14 Pro',
271
- appVersion: '2.1.0',
272
- customAttribute: 'value',
506
+ app_version: '2.1.0',
507
+ build_number: '421',
508
+ theme: 'dark',
509
+ language_preference: 'en-US'
273
510
  });
274
511
  ```
275
512
 
276
- ### Register Device Token
513
+ ### Clearing User Identity
514
+
515
+ Clear user identity when users log out:
516
+
517
+ ```typescript
518
+ import { Zixflow } from 'zixflow-reactnative';
277
519
 
278
- Register a device token for push notifications:
520
+ // Clear identify on logout
521
+ const handleLogout = async () => {
522
+ // Clear Zixflow identity
523
+ Zixflow.clearIdentify();
279
524
 
280
- ```ts
281
- Zixflow.registerDeviceToken('your-device-token');
525
+ // Perform other logout actions
526
+ // ...
527
+ };
282
528
  ```
283
529
 
284
- ### Clear Identification
530
+ ---
285
531
 
286
- Clear the current user identification:
532
+ ## Push Notifications
287
533
 
288
- ```ts
289
- Zixflow.clearIdentify();
290
- ```
534
+ Complete guide to implementing push notifications in React Native with Zixflow using Apple Push Notifications (APNs) or Firebase Cloud Messaging (FCM).
535
+
536
+ ### Prerequisites
537
+
538
+ Before implementing push notifications:
539
+
540
+ 1. **Configure push credentials in Zixflow dashboard** - Add APNs certificates or FCM Server Key
541
+ 2. **Complete iOS/Android native setup** - Ensure native dependencies are installed
542
+ 3. **Device tokens must be associated with users** - Call `identify()` before sending notifications
543
+
544
+ **Important Limitation**: The Zixflow React Native SDK currently supports deep links and images in push notifications. Custom action buttons require additional native code.
291
545
 
292
546
  ---
293
547
 
294
- ## Platform-Specific Setup
548
+ ### Platform-Specific Requirements
549
+
550
+ #### iOS Requirements
551
+
552
+ - **APNs or FCM**: Choose either Apple Push Notification service or Firebase Cloud Messaging
553
+ - **Xcode Capabilities**: Push Notifications and Background Modes
554
+ - **Notification Service Extension**: Required for rich push (images, videos)
555
+ - **Physical Device**: iOS Simulator cannot receive push notifications
556
+
557
+ #### Android Requirements
558
+
559
+ - **Firebase Project**: Required for FCM integration
560
+ - **google-services.json**: Must be in `android/app/` directory
561
+ - **Minimum API Level 24**: Android 7.0 or higher
562
+ - **POST_NOTIFICATIONS Permission**: Required for Android 13+ (API 33+)
563
+
564
+ ---
295
565
 
296
566
  ### iOS Setup
297
567
 
298
- 1. Add pods to your `ios/Podfile`:
568
+ You can use either **APNs (Apple Push Notification service)** or **FCM (Firebase Cloud Messaging)** on iOS.
569
+
570
+ #### Step 1: Enable Push Capabilities in Xcode
571
+
572
+ 1. Open your project's `.xcworkspace` file in Xcode
573
+ 2. Select your app target
574
+ 3. Go to **Signing & Capabilities** tab
575
+ 4. Click **+ Capability** → Add **Push Notifications**
576
+ 5. Click **+ Capability** → Add **Background Modes**
577
+ 6. Enable **Remote notifications** under Background Modes
578
+
579
+ #### Step 2: Choose APNs or FCM
580
+
581
+ **Option A: APNs (Recommended for iOS-only apps)**
582
+
583
+ Update your `ios/Podfile`:
299
584
 
300
585
  ```ruby
301
- pod 'zixflow-reactnative', :path => '../node_modules/zixflow-reactnative'
586
+ require_relative '../node_modules/react-native/scripts/react_native_pods'
587
+ require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
588
+
589
+ platform :ios, '13.0'
590
+
591
+ target 'YourApp' do
592
+ config = use_native_modules!
302
593
 
303
- # For FCM push:
304
- pod 'zixflow-reactnative/fcm', :path => '../node_modules/zixflow-reactnative'
594
+ use_react_native!(:path => config[:reactNativePath])
305
595
 
306
- # For APN push:
307
- pod 'zixflow-reactnative/apn', :path => '../node_modules/zixflow-reactnative'
596
+ # Add Zixflow with APNs support
597
+ pod 'zixflow-reactnative/apn', :path => '../node_modules/zixflow-reactnative'
308
598
 
309
- # For location tracking:
310
- pod 'zixflow-reactnative/location', :path => '../node_modules/zixflow-reactnative'
599
+ # Your other dependencies...
600
+ end
311
601
  ```
312
602
 
313
- 2. Run `pod install` in the `ios` directory
603
+ **Option B: FCM (For cross-platform Firebase apps)**
314
604
 
315
- 3. Follow the [iOS push setup guide](https://zixflow.com/docs/sdk/react-native/push/ios)
605
+ Update your `ios/Podfile` with static linkage:
316
606
 
317
- ### Android Setup
607
+ ```ruby
608
+ require_relative '../node_modules/react-native/scripts/react_native_pods'
609
+ require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
318
610
 
319
- #### Requirements
611
+ platform :ios, '13.0'
320
612
 
321
- - **compileSdkVersion**: 36 or higher
322
- - **Android Gradle Plugin**: 8.9.1 or higher
323
- - **Gradle**: 8.11.1 or higher
324
- - **minSdkVersion**: 21 or higher
325
- - **Kotlin**: 1.9.25 or higher
613
+ # Required for FCM
614
+ use_frameworks! :linkage => :static
326
615
 
327
- #### Configuration
616
+ target 'YourApp' do
617
+ config = use_native_modules!
328
618
 
329
- 1. Update your `android/build.gradle`:
619
+ use_react_native!(:path => config[:reactNativePath])
330
620
 
331
- ```gradle
332
- buildscript {
333
- ext {
334
- compileSdkVersion = 36
335
- buildToolsVersion = "36.0.0"
336
- minSdkVersion = 21
337
- targetSdkVersion = 36
338
- }
339
- dependencies {
340
- classpath("com.android.tools.build:gradle:8.9.1")
341
- }
342
- }
621
+ # Add Zixflow with FCM support
622
+ pod 'zixflow-reactnative/fcm', :path => '../node_modules/zixflow-reactnative'
623
+
624
+ # Your other dependencies...
625
+ end
343
626
  ```
344
627
 
345
- 2. Update `android/gradle/wrapper/gradle-wrapper.properties`:
628
+ **Install dependencies:**
346
629
 
347
- ```properties
348
- distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
630
+ ```bash
631
+ cd ios
632
+ pod install
633
+ cd ..
349
634
  ```
350
635
 
351
- 3. Add Kotlin compiler flag in `android/app/build.gradle`:
636
+ #### Step 3: Configure AppDelegate (Swift - Recommended)
352
637
 
353
- ```gradle
354
- android {
355
- // ... other config
638
+ For modern Swift-based React Native apps with APNs:
639
+
640
+ **AppDelegate.swift:**
641
+
642
+ ```swift
643
+ import UIKit
644
+ import ZixflowMessagingPushAPN
645
+
646
+ @main
647
+ class AppDelegateWithZixflowIntegration: ZixflowAppDelegateWrapper<AppDelegate> {}
648
+
649
+ class AppDelegate: NSObject, UIApplicationDelegate {
650
+
651
+ func application(
652
+ _ application: UIApplication,
653
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
654
+ ) -> Bool {
655
+ // Set notification delegate
656
+ UNUserNotificationCenter.current().delegate = self
657
+
658
+ // Initialize Zixflow push messaging (APNs)
659
+ MessagingPushAPN.initialize(
660
+ withConfig: MessagingPushConfigBuilder()
661
+ .build()
662
+ )
663
+
664
+ return true
665
+ }
356
666
  }
357
667
 
358
- tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
359
- kotlinOptions {
360
- freeCompilerArgs += ['-Xskip-metadata-version-check']
361
- }
668
+ extension AppDelegate: UNUserNotificationCenterDelegate {
669
+ // Show notifications when app is in foreground
670
+ func userNotificationCenter(
671
+ _ center: UNUserNotificationCenter,
672
+ willPresent notification: UNNotification,
673
+ withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
674
+ ) {
675
+ completionHandler([.banner, .list, .badge, .sound])
676
+ }
362
677
  }
363
678
  ```
364
679
 
365
- 4. The SDK is automatically linked via autolinking
680
+ **For FCM**, import `ZixflowMessagingPushFCM` instead:
366
681
 
367
- 5. (Optional) Enable location tracking in `android/gradle.properties`:
682
+ ```swift
683
+ import ZixflowMessagingPushFCM
368
684
 
369
- ```properties
370
- zixflow_location_enabled=true
685
+ // Initialize with FCM
686
+ MessagingPushFCM.initialize(
687
+ withConfig: MessagingPushConfigBuilder()
688
+ .build()
689
+ )
371
690
  ```
372
691
 
373
- 6. Follow the [Android push setup guide](https://zixflow.com/docs/sdk/react-native/push/android)
692
+ #### Step 4: Configure AppDelegate (Objective-C)
374
693
 
375
- ---
694
+ If your React Native app uses Objective-C, create a Swift bridge:
376
695
 
377
- ## Configuration Options
696
+ **Create `MyAppPushNotificationsHandler.swift`:**
378
697
 
379
- | Option | Type | Required | Description |
380
- |--------|------|----------|-------------|
381
- | `cdpApiKey` | `string` | ✅ | Your Zixflow API key |
382
- | `migrationSiteId` | `string` | ❌ | Site ID for migration from older SDKs |
383
- | `logLevel` | `ZixflowLogLevel` | ❌ | Logging verbosity (default: error) |
384
- | `trackApplicationLifecycleEvents` | `boolean` | ❌ | Auto-track app lifecycle events |
385
- | `inApp` | `object` | ❌ | In-app messaging configuration |
386
- | `push` | `object` | ❌ | Push notification configuration |
698
+ ```swift
699
+ import Foundation
700
+ import ZixflowMessagingPushAPN
387
701
 
388
- ---
702
+ @objc
703
+ public class MyAppPushNotificationsHandler: NSObject {
389
704
 
390
- ## TypeScript Support
705
+ @objc(setupZixflowClickHandling)
706
+ public func setupZixflowClickHandling() {
707
+ MessagingPushAPN.initialize(
708
+ withConfig: MessagingPushConfigBuilder().build()
709
+ )
710
+ }
391
711
 
392
- This SDK is written in TypeScript and includes full type definitions:
712
+ @objc(application:deviceToken:)
713
+ public func application(
714
+ _ application: UIApplication,
715
+ didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
716
+ ) {
717
+ MessagingPush.shared.application(
718
+ application,
719
+ didRegisterForRemoteNotificationsWithDeviceToken: deviceToken
720
+ )
721
+ }
393
722
 
394
- ```ts
395
- import type {
396
- Zixflow,
397
- ZixflowConfig,
398
- ZixflowInAppMessaging,
399
- ZixflowPushMessaging,
400
- ZixflowLocation,
401
- CustomAttributes,
402
- IdentifyParams,
403
- InAppMessage,
404
- InboxMessage,
405
- } from 'zixflow-reactnative';
723
+ @objc(application:error:)
724
+ public func application(
725
+ _ application: UIApplication,
726
+ didFailToRegisterForRemoteNotificationsWithError error: Error
727
+ ) {
728
+ MessagingPush.shared.application(
729
+ application,
730
+ didFailToRegisterForRemoteNotificationsWithError: error
731
+ )
732
+ }
733
+ }
406
734
  ```
407
735
 
408
- ---
736
+ **Update `AppDelegate.mm`:**
737
+
738
+ ```objc
739
+ #import "YourApp-Swift.h"
740
+
741
+ @implementation AppDelegate
409
742
 
410
- ## Module APIs
743
+ MyAppPushNotificationsHandler* pnHandlerObj;
411
744
 
412
- Access specific SDK modules:
745
+ - (BOOL)application:(UIApplication *)application
746
+ didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
747
+ // ... existing initialization code ...
413
748
 
414
- ```ts
415
- // In-app messaging
416
- Zixflow.inAppMessaging.registerEventsListener(listener);
749
+ // Register for remote notifications
750
+ [application registerForRemoteNotifications];
417
751
 
418
- // Push messaging
419
- Zixflow.pushMessaging.showPromptForPushNotifications();
752
+ // Initialize push handling
753
+ pnHandlerObj = [[MyAppPushNotificationsHandler alloc] init];
754
+ [pnHandlerObj setupZixflowClickHandling];
420
755
 
421
- // Location tracking
422
- Zixflow.location.setLastKnownLocation(lat, lng);
756
+ return YES;
757
+ }
758
+
759
+ - (void)application:(UIApplication *)application
760
+ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
761
+ [pnHandlerObj application:application deviceToken:deviceToken];
762
+ }
763
+
764
+ - (void)application:(UIApplication *)application
765
+ didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
766
+ [pnHandlerObj application:application error:error];
767
+ }
768
+
769
+ @end
423
770
  ```
424
771
 
425
- Note: Due to JavaScript limitations, module properties return the internal implementation instances, but all functionality works as expected.
772
+ #### Step 5: Rich Push with Notification Service Extension
426
773
 
427
- ---
774
+ To support rich push notifications (images, videos, GIFs), add a Notification Service Extension:
428
775
 
429
- ## Example App
776
+ **1. Create Notification Service Extension:**
430
777
 
431
- Check out our comprehensive [example app](/example) that demonstrates:
778
+ 1. In Xcode: **File** → **New** → **Target**
779
+ 2. Select **Notification Service Extension**
780
+ 3. Name it `NotificationServiceExtension`
781
+ 4. Click **Finish** (activate scheme when prompted)
432
782
 
433
- - SDK initialization
434
- - User identification
435
- - Event tracking
436
- - Push notifications
437
- - In-app messaging
438
- - Location tracking
439
- - Inbox management
783
+ **2. Add Zixflow to Extension:**
784
+
785
+ Update your `ios/Podfile` to include the extension:
786
+
787
+ ```ruby
788
+ # Main app target
789
+ target 'YourApp' do
790
+ # ... existing configuration ...
791
+ pod 'zixflow-reactnative/apn', :path => '../node_modules/zixflow-reactnative'
792
+ end
793
+
794
+ # Notification Service Extension target
795
+ target 'NotificationServiceExtension' do
796
+ pod 'zixflow-reactnative-richpush/apn', :path => '../node_modules/zixflow-reactnative'
797
+ end
798
+ ```
799
+
800
+ For FCM:
801
+
802
+ ```ruby
803
+ target 'NotificationServiceExtension' do
804
+ pod 'zixflow-reactnative-richpush/fcm', :path => '../node_modules/zixflow-reactnative'
805
+ end
806
+ ```
440
807
 
441
- To run the example app:
808
+ **3. Install dependencies:**
442
809
 
443
810
  ```bash
444
- cd example
445
- npm install
811
+ cd ios
812
+ pod install
813
+ cd ..
814
+ ```
446
815
 
447
- # iOS
448
- cd ios && pod install && cd ..
449
- npx react-native run-ios
816
+ **4. Update `NotificationService.swift`:**
450
817
 
451
- # Android
452
- npx react-native run-android
818
+ ```swift
819
+ import UserNotifications
820
+ import ZixflowMessagingPushAPN
821
+
822
+ class NotificationService: UNNotificationServiceExtension {
823
+ var contentHandler: ((UNNotificationContent) -> Void)?
824
+ var bestAttemptContent: UNMutableNotificationContent?
825
+
826
+ override func didReceive(
827
+ _ request: UNNotificationRequest,
828
+ withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
829
+ ) {
830
+ self.contentHandler = contentHandler
831
+ bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
832
+
833
+ // Initialize SDK for extension
834
+ MessagingPushAPN.initializeForExtension(
835
+ withConfig: MessagingPushConfigBuilder(apiKey: "YOUR_API_KEY")
836
+ .build()
837
+ )
838
+
839
+ if let bestAttemptContent = bestAttemptContent {
840
+ // Let Zixflow handle rich push and track delivery
841
+ MessagingPush.shared.didReceive(request, withContentHandler: contentHandler)
842
+ }
843
+ }
844
+
845
+ override func serviceExtensionTimeWillExpire() {
846
+ // Called when extension is about to be terminated
847
+ MessagingPush.shared.serviceExtensionTimeWillExpire()
848
+
849
+ if let contentHandler = contentHandler,
850
+ let bestAttemptContent = bestAttemptContent {
851
+ contentHandler(bestAttemptContent)
852
+ }
853
+ }
854
+ }
453
855
  ```
454
856
 
857
+ **Important:** Replace `"YOUR_API_KEY"` with your actual API key.
858
+
455
859
  ---
456
860
 
457
- ## Troubleshooting
861
+ ### Android Setup
458
862
 
459
- ### Common Issues
863
+ Android push notifications use Firebase Cloud Messaging (FCM).
460
864
 
461
- **Issue: Build fails with "Zixflow pod not found"**
462
- - Run `pod install` in your iOS directory
463
- - Make sure you're using the correct pod name: `zixflow-reactnative`
865
+ #### Step 1: Add Firebase to Your Project
464
866
 
465
- **Issue: Push notifications not working**
466
- - Verify your Firebase configuration (Android) or APNs certificates (iOS)
467
- - Check that you've requested push permissions
468
- - Ensure you've registered the device token
867
+ 1. Go to [Firebase Console](https://console.firebase.google.com/)
868
+ 2. Add your Android app to Firebase project
869
+ 3. Download `google-services.json`
870
+ 4. Place `google-services.json` in `android/app/` directory
469
871
 
470
- **Issue: In-app messages not showing**
471
- - Verify you've configured `inApp.siteId` in the config
472
- - Check that you've registered an events listener
473
- - Ensure messages are targeted correctly in your Zixflow dashboard
872
+ #### Step 2: Configure Gradle
474
873
 
475
- For more help, see our [troubleshooting guide](https://zixflow.com/docs/sdk/react-native/troubleshooting/) or [open an issue](https://github.com/zixflow/zixflow-reactnative/issues).
874
+ **Project-level `android/build.gradle`:**
476
875
 
477
- ---
876
+ ```gradle
877
+ buildscript {
878
+ ext {
879
+ minSdkVersion = 24
880
+ compileSdkVersion = 34
881
+ targetSdkVersion = 34
882
+ }
478
883
 
479
- ## Requirements
884
+ dependencies {
885
+ classpath 'com.google.gms:google-services:4.4.2'
886
+ }
887
+ }
888
+
889
+ allprojects {
890
+ repositories {
891
+ google()
892
+ mavenCentral()
893
+ }
894
+ }
895
+ ```
480
896
 
481
- - React Native 0.70+
482
- - iOS 13+
483
- - Android API 21+ (Android 5.0 Lollipop)
484
- - Swift 5.3+
485
- - Kotlin 1.8+
897
+ **App-level `android/app/build.gradle`:**
486
898
 
487
- ---
899
+ ```gradle
900
+ apply plugin: 'com.android.application'
901
+ apply plugin: 'com.google.gms.google-services' // Add this line
488
902
 
489
- ## Contributing
903
+ android {
904
+ // ... existing configuration ...
905
+ }
490
906
 
491
- We welcome contributions! To get started:
907
+ dependencies {
908
+ // React Native auto-linking handles Zixflow dependencies
909
+ // ... your other dependencies ...
910
+ }
911
+ ```
492
912
 
493
- 1. Review our [example app](/example) to help with local development
494
- 2. Follow our [Code of Conduct](CODE_OF_CONDUCT.md)
495
- 3. Check out [DEVELOPMENT.md](DEVELOPMENT.md) for development guidelines
496
- 4. Open issues or pull requests on [GitHub](https://github.com/zixflow/zixflow-reactnative)
913
+ #### Step 3: Add Permissions
497
914
 
498
- ---
915
+ Add to `android/app/src/main/AndroidManifest.xml`:
499
916
 
500
- ## Support
917
+ ```xml
918
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
501
919
 
502
- - 📚 [Documentation](https://zixflow.com/docs/sdk/react-native/)
503
- - 💬 [Community Forum](https://community.zixflow.com)
504
- - 🐛 [Issue Tracker](https://github.com/zixflow/zixflow-reactnative/issues)
505
- - 📧 Email: apps@zixflow.com
920
+ <!-- Required for push notifications -->
921
+ <uses-permission android:name="android.permission.INTERNET" />
506
922
 
507
- ---
923
+ <!-- Required for Android 13+ (API 33+) -->
924
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
508
925
 
509
- ## License
926
+ <application>
927
+ <!-- Your app configuration -->
928
+ </application>
929
+ </manifest>
930
+ ```
510
931
 
511
- [MIT](LICENSE)
932
+ #### Step 4: Configure Notification Icon and Color (Optional)
512
933
 
513
- ---
934
+ Add to `android/app/src/main/AndroidManifest.xml` inside `<application>` tag:
514
935
 
515
- ## Acknowledgments
936
+ ```xml
937
+ <application>
938
+ <!-- Default notification icon (white, transparent background) -->
939
+ <meta-data
940
+ android:name="com.google.firebase.messaging.default_notification_icon"
941
+ android:resource="@drawable/ic_notification" />
942
+
943
+ <!-- Default notification color (accent color) -->
944
+ <meta-data
945
+ android:name="com.google.firebase.messaging.default_notification_color"
946
+ android:resource="@color/notification_color" />
947
+ </application>
948
+ ```
949
+
950
+ ---
951
+
952
+ ### React Native Integration
953
+
954
+ #### Step 1: Initialize SDK
955
+
956
+ Initialize the Zixflow SDK in your `App.tsx`:
957
+
958
+ ```typescript
959
+ import React, { useEffect } from 'react';
960
+ import { Zixflow, ZixflowConfig, ZixflowLogLevel } from 'zixflow-reactnative';
961
+
962
+ export default function App() {
963
+ useEffect(() => {
964
+ // Configure the SDK
965
+ const config: ZixflowConfig = {
966
+ apiKey: 'YOUR_API_KEY',
967
+ logLevel: ZixflowLogLevel.debug,
968
+ inApp: {
969
+ },
970
+ autoTrackDeviceAttributes: true,
971
+ trackApplicationLifecycleEvents: true,
972
+ };
973
+
974
+ // Initialize the SDK
975
+ Zixflow.initialize(config);
976
+
977
+ console.log('Zixflow SDK initialized');
978
+ }, []);
979
+
980
+ return (
981
+ // Your app UI
982
+ );
983
+ }
984
+ ```
985
+
986
+ #### Step 2: Request Push Permission
987
+
988
+ Request permission to send push notifications:
989
+
990
+ ```typescript
991
+ import React, { useState } from 'react';
992
+ import { Button, Alert } from 'react-native';
993
+ import { Zixflow, ZixflowPushPermissionStatus } from 'zixflow-reactnative';
994
+
995
+ export default function PushPermissionButton() {
996
+ const [permissionStatus, setPermissionStatus] = useState<ZixflowPushPermissionStatus | null>(null);
997
+
998
+ const requestPushPermission = async () => {
999
+ try {
1000
+ const permission = await Zixflow.pushMessaging.showPromptForPushNotifications({
1001
+ ios: {
1002
+ sound: true,
1003
+ badge: true,
1004
+ alert: true,
1005
+ },
1006
+ });
1007
+
1008
+ setPermissionStatus(permission);
1009
+
1010
+ switch (permission) {
1011
+ case ZixflowPushPermissionStatus.Granted:
1012
+ Alert.alert('Success', 'Push notifications enabled!');
1013
+ console.log('Push notifications enabled');
1014
+ break;
1015
+
1016
+ case ZixflowPushPermissionStatus.Denied:
1017
+ Alert.alert('Denied', 'Push notification permission was denied');
1018
+ console.log('Push notifications denied');
1019
+ break;
1020
+
1021
+ case ZixflowPushPermissionStatus.NotDetermined:
1022
+ // iOS only: permission not yet asked
1023
+ console.log('Push notification permission not determined');
1024
+ break;
1025
+ }
1026
+ } catch (error) {
1027
+ console.error('Failed to request push permission:', error);
1028
+ }
1029
+ };
1030
+
1031
+ return (
1032
+ <Button
1033
+ title="Enable Push Notifications"
1034
+ onPress={requestPushPermission}
1035
+ />
1036
+ );
1037
+ }
1038
+ ```
1039
+
1040
+ **Permission Options (iOS)**:
1041
+
1042
+ | Option | Type | Description |
1043
+ |--------|------|-------------|
1044
+ | `sound` | boolean | Enable notification sounds |
1045
+ | `badge` | boolean | Enable app badge updates |
1046
+ | `alert` | boolean | Show notification alerts |
1047
+
1048
+ #### Step 3: Check Permission Status
1049
+
1050
+ Check current push permission status:
1051
+
1052
+ ```typescript
1053
+ import { Zixflow, ZixflowPushPermissionStatus } from 'zixflow-reactnative';
1054
+
1055
+ const checkPushPermission = async () => {
1056
+ try {
1057
+ const status = await Zixflow.pushMessaging.getPushPermissionStatus();
1058
+
1059
+ console.log('Push permission status:', status);
1060
+
1061
+ if (status === ZixflowPushPermissionStatus.Granted) {
1062
+ console.log('Push notifications are enabled');
1063
+ } else if (status === ZixflowPushPermissionStatus.Denied) {
1064
+ console.log('Push notifications are disabled');
1065
+ } else {
1066
+ console.log('Push permission not determined');
1067
+ }
1068
+ } catch (error) {
1069
+ console.error('Failed to get push permission status:', error);
1070
+ }
1071
+ };
1072
+ ```
1073
+
1074
+ #### Step 4: Identify Users
1075
+
1076
+ **Critical**: Device tokens must be associated with a user before push notifications can be delivered.
1077
+
1078
+ ```typescript
1079
+ import { Zixflow } from 'zixflow-reactnative';
1080
+
1081
+ // Identify user when they log in
1082
+ const handleLogin = async (userId: string, userEmail: string) => {
1083
+ try {
1084
+ // Identify user with Zixflow
1085
+ Zixflow.identify({
1086
+ userId: userId,
1087
+ traits: {
1088
+ email: userEmail,
1089
+ firstName: 'John',
1090
+ lastName: 'Doe',
1091
+ plan: 'premium',
1092
+ },
1093
+ });
1094
+
1095
+ console.log('User identified:', userId);
1096
+ } catch (error) {
1097
+ console.error('Failed to identify user:', error);
1098
+ }
1099
+ };
1100
+ ```
1101
+
1102
+ **Important Notes:**
1103
+ - When users start the app, they automatically generate a device token
1104
+ - This token links to their Zixflow profile when you call `identify()`
1105
+ - Device tokens are automatically removed from previous profiles when identifying new users
1106
+ - This prevents duplicate notifications when users switch accounts
1107
+
1108
+ #### Step 5: Get Device Token
1109
+
1110
+ Retrieve the registered device token:
1111
+
1112
+ ```typescript
1113
+ import { Zixflow } from 'zixflow-reactnative';
1114
+
1115
+ const getDeviceToken = async () => {
1116
+ try {
1117
+ const token = await Zixflow.pushMessaging.getRegisteredDeviceToken();
1118
+ console.log('Device token:', token);
1119
+ return token;
1120
+ } catch (error) {
1121
+ console.error('Failed to get device token:', error);
1122
+ return null;
1123
+ }
1124
+ };
1125
+ ```
1126
+
1127
+ ---
1128
+
1129
+ ### Deep Links and Navigation
1130
+
1131
+ Handle deep links from push notifications:
1132
+
1133
+ #### Setup Deep Linking
1134
+
1135
+ **1. Configure Deep Links (iOS):**
1136
+
1137
+ Add to `ios/YourApp/Info.plist`:
1138
+
1139
+ ```xml
1140
+ <key>CFBundleURLTypes</key>
1141
+ <array>
1142
+ <dict>
1143
+ <key>CFBundleURLSchemes</key>
1144
+ <array>
1145
+ <string>yourapp</string>
1146
+ </array>
1147
+ </dict>
1148
+ </array>
1149
+ ```
1150
+
1151
+ **2. Configure Deep Links (Android):**
1152
+
1153
+ Add to `android/app/src/main/AndroidManifest.xml`:
1154
+
1155
+ ```xml
1156
+ <activity android:name=".MainActivity">
1157
+ <!-- Existing intent filter -->
1158
+
1159
+ <!-- Deep link intent filter -->
1160
+ <intent-filter>
1161
+ <action android:name="android.intent.action.VIEW" />
1162
+ <category android:name="android.intent.category.DEFAULT" />
1163
+ <category android:name="android.intent.category.BROWSABLE" />
1164
+
1165
+ <data
1166
+ android:scheme="yourapp"
1167
+ android:host="*" />
1168
+ </intent-filter>
1169
+
1170
+ <!-- Universal Links (optional) -->
1171
+ <intent-filter android:autoVerify="true">
1172
+ <action android:name="android.intent.action.VIEW" />
1173
+ <category android:name="android.intent.category.DEFAULT" />
1174
+ <category android:name="android.intent.category.BROWSABLE" />
1175
+
1176
+ <data
1177
+ android:scheme="https"
1178
+ android:host="yourapp.com" />
1179
+ </intent-filter>
1180
+ </activity>
1181
+ ```
1182
+
1183
+ #### Handle Deep Links in React Native
1184
+
1185
+ Use React Navigation's linking configuration:
1186
+
1187
+ ```typescript
1188
+ import React from 'react';
1189
+ import { NavigationContainer } from '@react-navigation/native';
1190
+ import { createNativeStackNavigator } from '@react-navigation/native-stack';
1191
+ import { Linking } from 'react-native';
1192
+
1193
+ const Stack = createNativeStackNavigator();
1194
+
1195
+ const linking = {
1196
+ prefixes: ['yourapp://', 'https://yourapp.com'],
1197
+ config: {
1198
+ screens: {
1199
+ Home: 'home',
1200
+ Product: 'product/:id',
1201
+ Profile: 'profile',
1202
+ },
1203
+ },
1204
+ };
1205
+
1206
+ export default function App() {
1207
+ return (
1208
+ <NavigationContainer linking={linking}>
1209
+ <Stack.Navigator>
1210
+ <Stack.Screen name="Home" component={HomeScreen} />
1211
+ <Stack.Screen name="Product" component={ProductScreen} />
1212
+ <Stack.Screen name="Profile" component={ProfileScreen} />
1213
+ </Stack.Navigator>
1214
+ </NavigationContainer>
1215
+ );
1216
+ }
1217
+ ```
1218
+
1219
+ ---
1220
+
1221
+ ### Rich Push Notification Payloads
1222
+
1223
+ The Zixflow SDK automatically handles rich push notifications. Here's how to structure payloads:
1224
+
1225
+ #### iOS APNs Payload
1226
+
1227
+ ```json
1228
+ {
1229
+ "aps": {
1230
+ "mutable-content": 1,
1231
+ "alert": {
1232
+ "title": "New Product Available",
1233
+ "body": "Check out our latest premium features"
1234
+ },
1235
+ "badge": 1,
1236
+ "sound": "default"
1237
+ },
1238
+ "Zixflow": {
1239
+ "push": {
1240
+ "link": "yourapp://product/123",
1241
+ "image": "https://example.com/product-image.jpg"
1242
+ }
1243
+ }
1244
+ }
1245
+ ```
1246
+
1247
+ #### iOS FCM Payload
1248
+
1249
+ ```json
1250
+ {
1251
+ "message": {
1252
+ "apns": {
1253
+ "payload": {
1254
+ "aps": {
1255
+ "mutable-content": 1,
1256
+ "alert": {
1257
+ "title": "Special Offer",
1258
+ "body": "Limited time discount!"
1259
+ }
1260
+ },
1261
+ "Zixflow": {
1262
+ "push": {
1263
+ "link": "https://yourapp.com/offers",
1264
+ "image": "https://example.com/offer.png"
1265
+ }
1266
+ }
1267
+ },
1268
+ "headers": {
1269
+ "apns-priority": 10
1270
+ }
1271
+ }
1272
+ }
1273
+ }
1274
+ ```
1275
+
1276
+ #### Android FCM Payload
1277
+
1278
+ ```json
1279
+ {
1280
+ "message": {
1281
+ "data": {
1282
+ "title": "Order Shipped",
1283
+ "body": "Your order is on the way!",
1284
+ "image": "https://example.com/shipping.jpg",
1285
+ "link": "yourapp://orders/456"
1286
+ }
1287
+ }
1288
+ }
1289
+ ```
1290
+
1291
+ ---
1292
+
1293
+ ### Testing Push Notifications
1294
+
1295
+ #### 1. Verify Device Token Registration
1296
+
1297
+ Check if device token is registered:
1298
+
1299
+ ```typescript
1300
+ const verifyPushSetup = async () => {
1301
+ try {
1302
+ const token = await Zixflow.pushMessaging.getRegisteredDeviceToken();
1303
+ const status = await Zixflow.pushMessaging.getPushPermissionStatus();
1304
+
1305
+ console.log('Device token:', token);
1306
+ console.log('Permission status:', status);
1307
+
1308
+ if (token && status === ZixflowPushPermissionStatus.Granted) {
1309
+ console.log('✓ Push notifications ready');
1310
+ } else {
1311
+ console.log('✗ Push setup incomplete');
1312
+ }
1313
+ } catch (error) {
1314
+ console.error('Push verification failed:', error);
1315
+ }
1316
+ };
1317
+ ```
1318
+
1319
+ #### 2. Enable Debug Logging
1320
+
1321
+ Set log level to debug during development:
1322
+
1323
+ ```typescript
1324
+ const config: ZixflowConfig = {
1325
+ apiKey: 'YOUR_API_KEY',
1326
+ logLevel: ZixflowLogLevel.debug, // Verbose logging
1327
+ };
1328
+
1329
+ Zixflow.initialize(config);
1330
+ ```
1331
+
1332
+ #### 3. Test on Physical Devices
1333
+
1334
+ **iOS:**
1335
+ - Push notifications **do not work** on iOS Simulator
1336
+ - Must use physical iOS device
1337
+ - Ensure APNs certificate is configured in Zixflow dashboard
1338
+
1339
+ **Android:**
1340
+ - Emulator works if Google Play Services installed
1341
+ - Physical device always recommended
1342
+ - Ensure FCM Server Key is configured in Zixflow dashboard
1343
+
1344
+ #### 4. Send Test Push from Zixflow
1345
+
1346
+ 1. Log into Zixflow dashboard
1347
+ 2. Navigate to **Messaging** → **Push Notifications**
1348
+ 3. Create test push notification
1349
+ 4. Send to specific user (using `userId` from `identify()`)
1350
+
1351
+ ---
1352
+
1353
+ ### Troubleshooting
1354
+
1355
+ #### iOS Push Not Received
1356
+
1357
+ **Symptoms:** Push sent but not delivered on iOS
1358
+
1359
+ **Solutions:**
1360
+ 1. Verify Push Notifications capability enabled in Xcode
1361
+ 2. Check APNs certificate uploaded to Zixflow dashboard
1362
+ 3. Ensure testing on physical device (not simulator)
1363
+ 4. Verify user identified: `Zixflow.identify({ userId: ... })`
1364
+ 5. Check permission granted: `getPushPermissionStatus()`
1365
+ 6. Review logs for errors
1366
+
1367
+ #### Android Push Not Received
1368
+
1369
+ **Symptoms:** Push sent but not delivered on Android
1370
+
1371
+ **Solutions:**
1372
+ 1. Verify `google-services.json` in `android/app/` directory
1373
+ 2. Check FCM Server Key in Zixflow dashboard
1374
+ 3. Ensure POST_NOTIFICATIONS permission granted (Android 13+)
1375
+ 4. Verify Google Services plugin applied
1376
+ 5. Check device token registered
1377
+ 6. Review logs for errors
1378
+
1379
+ #### Rich Push Not Working (Images)
1380
+
1381
+ **Symptoms:** Images not loading in notifications
1382
+
1383
+ **iOS Solutions:**
1384
+ 1. Ensure Notification Service Extension properly configured
1385
+ 2. Verify extension has correct dependencies in Podfile
1386
+ 3. Check App Groups configuration (if using)
1387
+ 4. Verify image URL is accessible
1388
+ 5. Check extension logs for errors
1389
+
1390
+ **Android Solutions:**
1391
+ 1. Verify image URL is accessible from device
1392
+ 2. Check internet connectivity
1393
+ 3. Ensure image format is supported (JPEG, PNG, GIF)
1394
+
1395
+ #### Permission Denied
1396
+
1397
+ **Symptoms:** User denied push permission
1398
+
1399
+ **Solutions:**
1400
+ 1. Explain value before requesting permission
1401
+ 2. Guide users to Settings to enable manually
1402
+ 3. Show in-app message explaining benefits
1403
+ 4. Request permission at appropriate time (after user engagement)
1404
+
1405
+ #### Device Token Not Registered
1406
+
1407
+ **Symptoms:** `getRegisteredDeviceToken()` returns empty or fails
1408
+
1409
+ **Solutions:**
1410
+ 1. Verify SDK initialized before calling
1411
+ 2. Check permission granted
1412
+ 3. Ensure identify() called to associate token
1413
+ 4. Review native logs for errors
1414
+ 5. Rebuild app and retry
1415
+
1416
+ ---
1417
+
1418
+ ### Best Practices
1419
+
1420
+ 1. **Request permission thoughtfully** - Explain value before asking
1421
+ 2. **Identify users immediately** after authentication
1422
+ 3. **Test on physical devices** - Simulators have limitations
1423
+ 4. **Use rich push** - Images increase engagement
1424
+ 5. **Handle deep links** - Provide seamless navigation
1425
+ 6. **Monitor metrics** - Track delivery and open rates
1426
+ 7. **Enable debug logging** - During development only
1427
+ 8. **Test both platforms** - iOS and Android behave differently
1428
+ 9. **Clear identity on logout** - Call `clearIdentify()`
1429
+ 10. **Keep credentials secure** - Never commit API keys to git
1430
+
1431
+ ---
1432
+
1433
+ ### Next Steps
1434
+
1435
+ - Learn about [In-App Messaging](#in-app-messaging)
1436
+ - Explore [Deep Link Handling](#deep-links-and-navigation)
1437
+ - See [Example Applications](#example-applications) for complete implementations
1438
+
1439
+ ---
1440
+
1441
+ ## In-App Messaging
1442
+
1443
+ ### Event Listeners
1444
+
1445
+ Register event listeners to respond to in-app message events:
1446
+
1447
+ ```typescript
1448
+ import { Zixflow, InAppMessageEvent, InAppMessageEventType } from 'zixflow-reactnative';
1449
+ import { useEffect } from 'react';
1450
+
1451
+ export default function App() {
1452
+ useEffect(() => {
1453
+ const inAppMessaging = Zixflow.inAppMessaging;
1454
+
1455
+ const eventListener = inAppMessaging.registerEventsListener((event: InAppMessageEvent) => {
1456
+ switch (event.eventType) {
1457
+ case InAppMessageEventType.messageShown:
1458
+ console.log('In-app message shown', event);
1459
+ break;
1460
+
1461
+ case InAppMessageEventType.messageDismissed:
1462
+ console.log('In-app message dismissed', event);
1463
+ break;
1464
+
1465
+ case InAppMessageEventType.messageActionTaken:
1466
+ console.log('Action taken on in-app message', event);
1467
+ handleMessageAction(event);
1468
+ break;
1469
+
1470
+ case InAppMessageEventType.errorWithMessage:
1471
+ console.error('Error with in-app message', event);
1472
+ break;
1473
+ }
1474
+ });
1475
+
1476
+ // Cleanup listener on unmount
1477
+ return () => {
1478
+ eventListener.remove();
1479
+ };
1480
+ }, []);
1481
+
1482
+ return (
1483
+ // Your app UI
1484
+ );
1485
+ }
1486
+ ```
1487
+
1488
+ ### Message Events
1489
+
1490
+ The SDK provides the following in-app message event types:
1491
+
1492
+ | Event Type | Description |
1493
+ |------------|-------------|
1494
+ | `messageShown` | Message was displayed to the user |
1495
+ | `messageDismissed` | Message was dismissed by the user |
1496
+ | `messageActionTaken` | User took an action on the message (clicked button, link, etc.) |
1497
+ | `errorWithMessage` | Error occurred while displaying the message |
1498
+
1499
+ **Event properties**:
1500
+ - `eventType`: The type of event
1501
+ - `deliveryId`: Unique delivery identifier
1502
+ - `messageId`: Message template identifier
1503
+ - `actionName`: Name of the action taken (for `messageActionTaken`)
1504
+ - `actionValue`: Value of the action (for `messageActionTaken`)
1505
+
1506
+ ### Dismissing Messages
1507
+
1508
+ Programmatically dismiss the current in-app message:
1509
+
1510
+ ```typescript
1511
+ import { Zixflow } from 'zixflow-reactnative';
1512
+
1513
+ const handleMessageAction = (event: InAppMessageEvent) => {
1514
+ if (event.actionValue === 'dismiss' || event.actionValue === 'close') {
1515
+ // Dismiss the message
1516
+ Zixflow.inAppMessaging.dismissMessage();
1517
+ }
1518
+ };
1519
+ ```
1520
+
1521
+ ---
1522
+
1523
+ ## Location Tracking
1524
+
1525
+ Enable location tracking to send location-based messages:
1526
+
1527
+ ```typescript
1528
+ import { Zixflow } from 'zixflow-reactnative';
1529
+
1530
+ // Location tracking is configured via the native SDK
1531
+ // Make sure to request location permissions in your app
1532
+
1533
+ // iOS: Add location permission keys to Info.plist
1534
+ // - NSLocationWhenInUseUsageDescription
1535
+ // - NSLocationAlwaysAndWhenInUseUsageDescription
1536
+
1537
+ // Android: Add location permissions to AndroidManifest.xml
1538
+ // - ACCESS_FINE_LOCATION
1539
+ // - ACCESS_COARSE_LOCATION
1540
+ ```
1541
+
1542
+ Request location permissions using a library like `react-native-permissions`:
1543
+
1544
+ ```typescript
1545
+ import { request, PERMISSIONS, RESULTS } from 'react-native-permissions';
1546
+ import { Platform } from 'react-native';
1547
+
1548
+ const requestLocationPermission = async () => {
1549
+ const permission = Platform.select({
1550
+ ios: PERMISSIONS.IOS.LOCATION_WHEN_IN_USE,
1551
+ android: PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
1552
+ });
1553
+
1554
+ if (!permission) return;
1555
+
1556
+ const result = await request(permission);
1557
+
1558
+ if (result === RESULTS.GRANTED) {
1559
+ console.log('Location permission granted');
1560
+ }
1561
+ };
1562
+ ```
1563
+
1564
+ ---
1565
+
1566
+ ## Advanced Configuration
1567
+
1568
+ ### Region Settings
1569
+
1570
+ Configure the data center region for data residency:
1571
+
1572
+ ```typescript
1573
+ import { Zixflow } from 'zixflow-reactnative';
1574
+
1575
+ const config = {
1576
+ apiKey: 'YOUR_API_KEY',
1577
+ // or
1578
+ };
1579
+
1580
+ Zixflow.initialize(config);
1581
+ ```
1582
+
1583
+ **Available regions**:
1584
+ - `` - United States data center
1585
+ - `` - European Union data center
1586
+
1587
+ ### Log Levels
1588
+
1589
+ Control SDK logging for debugging:
1590
+
1591
+ ```typescript
1592
+ import { Zixflow, ZixflowLogLevel } from 'zixflow-reactnative';
1593
+
1594
+ const config = {
1595
+ apiKey: 'YOUR_API_KEY',
1596
+ logLevel: ZixflowLogLevel.debug, // debug, info, error, none
1597
+ };
1598
+
1599
+ Zixflow.initialize(config);
1600
+ ```
1601
+
1602
+ **Log levels**:
1603
+ - `ZixflowLogLevel.debug` - Verbose logging (development)
1604
+ - `ZixflowLogLevel.info` - Informational messages
1605
+ - `ZixflowLogLevel.error` - Errors only
1606
+ - `ZixflowLogLevel.none` - No logging (production)
1607
+
1608
+ ### Auto-Tracking Options
1609
+
1610
+ Configure automatic tracking features:
1611
+
1612
+ ```typescript
1613
+ import { Zixflow } from 'zixflow-reactnative';
1614
+
1615
+ const config = {
1616
+ apiKey: 'YOUR_API_KEY',
1617
+
1618
+ // Automatically track device attributes (OS, model, app version)
1619
+ autoTrackDeviceAttributes: true,
1620
+
1621
+ // Automatically track app lifecycle events (open, close, background)
1622
+ trackApplicationLifecycleEvents: true,
1623
+
1624
+ // Automatically track screens (requires integration)
1625
+ autoTrackScreenViews: true,
1626
+ };
1627
+
1628
+ Zixflow.initialize(config);
1629
+ ```
1630
+
1631
+ ### Custom API Hosts
1632
+
1633
+ Override API endpoints for testing or custom infrastructure:
1634
+
1635
+ ```typescript
1636
+ import { Zixflow } from 'zixflow-reactnative';
1637
+
1638
+ const config = {
1639
+ apiKey: 'YOUR_API_KEY',
1640
+
1641
+ // Custom tracking API host
1642
+ trackingApiUrl: 'https://custom-track.zixflow.com',
1643
+
1644
+ // Custom in-app messaging API host
1645
+ inApp: {
1646
+ // Override in-app messaging API endpoint if needed
1647
+ },
1648
+ };
1649
+
1650
+ Zixflow.initialize(config);
1651
+ ```
1652
+
1653
+ ---
1654
+
1655
+ ## Troubleshooting
1656
+
1657
+ ### Installation Issues
1658
+
1659
+ **Issue**: `npm install` fails with dependency conflicts
1660
+
1661
+ **Solution**: Use `--legacy-peer-deps` flag:
1662
+ ```bash
1663
+ npm install zixflow-reactnative --legacy-peer-deps
1664
+ ```
1665
+
1666
+ Or with Yarn:
1667
+ ```bash
1668
+ yarn add zixflow-reactnative --legacy-peer-deps
1669
+ ```
1670
+
1671
+ ---
1672
+
1673
+ **Issue**: Auto-linking fails after installation
1674
+
1675
+ **Solution**: Try manual linking:
1676
+
1677
+ 1. Clean the build:
1678
+ ```bash
1679
+ cd android && ./gradlew clean && cd ..
1680
+ cd ios && rm -rf Pods && pod install && cd ..
1681
+ ```
1682
+
1683
+ 2. Rebuild the app:
1684
+ ```bash
1685
+ npx react-native run-ios
1686
+ npx react-native run-android
1687
+ ```
1688
+
1689
+ ### iOS Build Errors
1690
+
1691
+ **Issue**: `Module 'Zixflow' not found`
1692
+
1693
+ **Solution**:
1694
+ 1. Ensure you've run `pod install` in the `ios` directory
1695
+ 2. Clean build folder in Xcode: Product > Clean Build Folder
1696
+ 3. Rebuild the project
1697
+
1698
+ ---
1699
+
1700
+ **Issue**: Swift compiler errors in native modules
1701
+
1702
+ **Solution**:
1703
+ 1. Check Xcode version (14.0+ required)
1704
+ 2. Update CocoaPods: `sudo gem install cocoapods`
1705
+ 3. Update pod dependencies: `cd ios && pod update && cd ..`
1706
+
1707
+ ---
1708
+
1709
+ **Issue**: Notification Service Extension not working
1710
+
1711
+ **Solution**:
1712
+ 1. Ensure the extension target has the correct dependencies in Podfile
1713
+ 2. Run `pod install` after adding the extension
1714
+ 3. Check that the extension's deployment target is iOS 13.0+
1715
+ 4. Verify the extension is added to your app's target dependencies
1716
+
1717
+ ### Android Build Errors
1718
+
1719
+ **Issue**: `Cannot find symbol class Zixflow`
1720
+
1721
+ **Solution**:
1722
+ 1. Clean Gradle cache:
1723
+ ```bash
1724
+ cd android && ./gradlew clean && cd ..
1725
+ ```
1726
+
1727
+ 2. Rebuild the app:
1728
+ ```bash
1729
+ npx react-native run-android
1730
+ ```
1731
+
1732
+ ---
1733
+
1734
+ **Issue**: Duplicate class errors with Firebase
1735
+
1736
+ **Solution**:
1737
+ 1. Check that you're not including Firebase dependencies manually if using FCM
1738
+ 2. Ensure all Firebase dependencies use the same version
1739
+ 3. Add to `android/gradle.properties`:
1740
+ ```properties
1741
+ android.enableJetifier=true
1742
+ ```
1743
+
1744
+ ---
1745
+
1746
+ **Issue**: Minimum SDK version error
1747
+
1748
+ **Solution**: Update `android/build.gradle`:
1749
+ ```gradle
1750
+ ext {
1751
+ minSdkVersion = 24
1752
+ }
1753
+ ```
1754
+
1755
+ ### Push Notification Issues
1756
+
1757
+ **Issue**: Push notifications not received on iOS
1758
+
1759
+ **Checklist**:
1760
+ - [ ] Push Notifications capability enabled in Xcode
1761
+ - [ ] APNs certificate uploaded to Zixflow dashboard
1762
+ - [ ] Device token registered (check logs)
1763
+ - [ ] Permission granted by user
1764
+ - [ ] App not in foreground (notifications shown in background/killed state)
1765
+
1766
+ ---
1767
+
1768
+ **Issue**: Push notifications not received on Android
1769
+
1770
+ **Checklist**:
1771
+ - [ ] `google-services.json` file added to `android/app/`
1772
+ - [ ] Google Services plugin applied in `android/app/build.gradle`
1773
+ - [ ] FCM server key uploaded to Zixflow dashboard
1774
+ - [ ] Device registered for push (check logs)
1775
+ - [ ] Notification permissions granted (Android 13+)
1776
+
1777
+ ---
1778
+
1779
+ **Issue**: Rich push notifications (images) not working
1780
+
1781
+ **Solution**: Ensure Notification Service Extension is properly configured on iOS (see [Notification Service Extension](#notification-service-extension))
1782
+
1783
+ ### In-App Message Issues
1784
+
1785
+ **Issue**: In-app messages not displaying
1786
+
1787
+ **Checklist**:
1788
+ - [ ] In-app messaging module initialized
1789
+ - [ ] Event listener registered
1790
+ - [ ] User identified before triggering message
1791
+ - [ ] Message created and published in Zixflow dashboard
1792
+ - [ ] Check logs for error events
1793
+
1794
+ ---
1795
+
1796
+ **Issue**: In-app message events not firing
1797
+
1798
+ **Solution**: Ensure event listener is registered before messages are triggered:
1799
+ ```typescript
1800
+ useEffect(() => {
1801
+ const listener = Zixflow.inAppMessaging.registerEventsListener((event) => {
1802
+ console.log('In-app event:', event);
1803
+ });
1804
+
1805
+ return () => listener.remove();
1806
+ }, []);
1807
+ ```
1808
+
1809
+ ---
1810
+
1811
+ ## Example Applications
1812
+
1813
+ The Zixflow React Native SDK includes example applications demonstrating best practices:
1814
+
1815
+ ### Sample App (APNs)
1816
+
1817
+ Location: `example/`
1818
+
1819
+ **Features**:
1820
+ - User identification and logout
1821
+ - Event tracking
1822
+ - Screen tracking with React Navigation
1823
+ - Push notifications with APNs
1824
+ - In-app messaging with event listeners
1825
+ - Profile and device attributes
1826
+
1827
+ **Running the example**:
1828
+
1829
+ ```bash
1830
+ # Install dependencies
1831
+ cd example
1832
+ npm install
1833
+
1834
+ # iOS
1835
+ cd ios && pod install && cd ..
1836
+ npx react-native run-ios
1837
+
1838
+ # Android
1839
+ npx react-native run-android
1840
+ ```
1841
+
1842
+ ---
1843
+
1844
+ ## API Reference
1845
+
1846
+ ### Core SDK
1847
+
1848
+ #### `Zixflow.initialize(config: ZixflowConfig): void`
1849
+
1850
+ Initialize the SDK with configuration.
1851
+
1852
+ ```typescript
1853
+ Zixflow.initialize({
1854
+ apiKey: 'YOUR_API_KEY',
1855
+ });
1856
+ ```
1857
+
1858
+ #### `Zixflow.identify(params: { userId: string; traits?: object }): void`
1859
+
1860
+ Identify a user with optional traits.
1861
+
1862
+ ```typescript
1863
+ Zixflow.identify({
1864
+ userId: 'user-123',
1865
+ traits: { email: 'user@example.com' }
1866
+ });
1867
+ ```
1868
+
1869
+ #### `Zixflow.clearIdentify(): void`
1870
+
1871
+ Clear the current user's identity.
1872
+
1873
+ ```typescript
1874
+ Zixflow.clearIdentify();
1875
+ ```
1876
+
1877
+ #### `Zixflow.track(name: string, properties?: object | Map<string, any>): void`
1878
+
1879
+ Track a custom event.
1880
+
1881
+ ```typescript
1882
+ Zixflow.track('button_clicked', { button_name: 'signup' });
1883
+ ```
1884
+
1885
+ #### `Zixflow.screen(name: string, properties?: object): void`
1886
+
1887
+ Track a screen view.
1888
+
1889
+ ```typescript
1890
+ Zixflow.screen('HomeScreen');
1891
+ ```
1892
+
1893
+ #### `Zixflow.setProfileAttributes(attributes: object): void`
1894
+
1895
+ Set attributes on the user profile.
1896
+
1897
+ ```typescript
1898
+ Zixflow.setProfileAttributes({ plan: 'premium' });
1899
+ ```
1900
+
1901
+ #### `Zixflow.setDeviceAttributes(attributes: object): void`
1902
+
1903
+ Set attributes on the current device.
1904
+
1905
+ ```typescript
1906
+ Zixflow.setDeviceAttributes({ app_version: '2.0.0' });
1907
+ ```
1908
+
1909
+ ### Push Messaging
1910
+
1911
+ #### `Zixflow.pushMessaging.showPromptForPushNotifications(options): Promise<ZixflowPushPermissionStatus>`
1912
+
1913
+ Request push notification permission.
1914
+
1915
+ ```typescript
1916
+ const status = await Zixflow.pushMessaging.showPromptForPushNotifications({
1917
+ ios: { sound: true, badge: true }
1918
+ });
1919
+ ```
1920
+
1921
+ ### In-App Messaging
1922
+
1923
+ #### `Zixflow.inAppMessaging.registerEventsListener(callback): EventSubscription`
1924
+
1925
+ Register a listener for in-app message events.
1926
+
1927
+ ```typescript
1928
+ const listener = Zixflow.inAppMessaging.registerEventsListener((event) => {
1929
+ console.log('In-app event:', event);
1930
+ });
1931
+
1932
+ // Remove listener
1933
+ listener.remove();
1934
+ ```
1935
+
1936
+ #### `Zixflow.inAppMessaging.dismissMessage(): void`
1937
+
1938
+ Dismiss the currently displayed in-app message.
1939
+
1940
+ ```typescript
1941
+ Zixflow.inAppMessaging.dismissMessage();
1942
+ ```
1943
+
1944
+ ### Types
1945
+
1946
+ #### `ZixflowConfig`
1947
+
1948
+ Configuration object for SDK initialization.
1949
+
1950
+ ```typescript
1951
+ interface ZixflowConfig {
1952
+ apiKey: string;
1953
+ region?: Region;
1954
+ logLevel?: ZixflowLogLevel;
1955
+ inApp?: {
1956
+ };
1957
+ autoTrackDeviceAttributes?: boolean;
1958
+ trackApplicationLifecycleEvents?: boolean;
1959
+ autoTrackScreenViews?: boolean;
1960
+ trackingApiUrl?: string;
1961
+ }
1962
+ ```
1963
+
1964
+ #### `Region`
1965
+
1966
+ Data center region enum.
1967
+
1968
+ ```typescript
1969
+ enum Region {
1970
+ US = 'US',
1971
+ EU = 'EU'
1972
+ }
1973
+ ```
1974
+
1975
+ #### `ZixflowLogLevel`
1976
+
1977
+ Log level enum.
1978
+
1979
+ ```typescript
1980
+ enum ZixflowLogLevel {
1981
+ none = 'none',
1982
+ error = 'error',
1983
+ info = 'info',
1984
+ debug = 'debug'
1985
+ }
1986
+ ```
1987
+
1988
+ #### `ZixflowPushPermissionStatus`
1989
+
1990
+ Push notification permission status.
1991
+
1992
+ ```typescript
1993
+ enum ZixflowPushPermissionStatus {
1994
+ Granted = 'granted',
1995
+ Denied = 'denied',
1996
+ NotDetermined = 'notDetermined'
1997
+ }
1998
+ ```
1999
+
2000
+ #### `InAppMessageEventType`
2001
+
2002
+ In-app message event types.
2003
+
2004
+ ```typescript
2005
+ enum InAppMessageEventType {
2006
+ messageShown = 'messageShown',
2007
+ messageDismissed = 'messageDismissed',
2008
+ messageActionTaken = 'messageActionTaken',
2009
+ errorWithMessage = 'errorWithMessage'
2010
+ }
2011
+ ```
2012
+
2013
+ #### `InAppMessageEvent`
2014
+
2015
+ In-app message event object.
2016
+
2017
+ ```typescript
2018
+ interface InAppMessageEvent {
2019
+ eventType: InAppMessageEventType;
2020
+ deliveryId?: string;
2021
+ messageId?: string;
2022
+ actionName?: string;
2023
+ actionValue?: string;
2024
+ }
2025
+ ```
2026
+
2027
+ ---
2028
+
2029
+ ## Support & Resources
2030
+
2031
+ ### Documentation
2032
+
2033
+ - **GitHub Repository**: https://github.com/zixflow/zixflow-reactnative
2034
+ - **iOS SDK Documentation**: https://github.com/zixflow/zixflow-ios
2035
+ - **Android SDK Documentation**: https://github.com/zixflow/zixflow-android
2036
+ - **API Reference**: See [API Reference](#api-reference) section above
2037
+
2038
+ ### Getting Help
2039
+
2040
+ - **GitHub Issues**: https://github.com/zixflow/zixflow-reactnative/issues
2041
+ - **Support Email**: support@zixflow.com
2042
+
2043
+ ### Changelog
2044
+
2045
+ See [CHANGELOG.md](../CHANGELOG.md) for version history and release notes.
2046
+
2047
+ ---
516
2048
 
517
- This SDK is based on the Zixflow React Native SDK and maintains compatibility with the Zixflow platform while providing Zixflow-specific optimizations and branding.
2049
+ **Need help?** Contact our support team at support@zixflow.com or open an issue on GitHub.