react-native-notify-sphere 1.1.0 → 1.2.0

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.
package/README.md CHANGED
@@ -1,178 +1,92 @@
1
- # NotifySphere Push Notifications Implementation Guide
1
+ # react-native-notify-sphere
2
2
 
3
- Complete implementation guide for integrating **react-native-notify-sphere** push notifications in React Native Android/iOS applications.
3
+ A React Native push notification SDK built on Firebase Cloud Messaging (FCM) and Notifee. Handles delivery tracking, press tracking, user segmentation via tags, and rich notifications with full Android and iOS support.
4
4
 
5
5
  ---
6
6
 
7
7
  ## Table of Contents
8
8
 
9
- 1. [Overview](#overview)
9
+ 1. [Features](#features)
10
10
  2. [Prerequisites](#prerequisites)
11
11
  3. [Installation](#installation)
12
12
  4. [Android Setup](#android-setup)
13
13
  5. [iOS Setup](#ios-setup)
14
- 6. [Implementation](#implementation)
15
- 7. [NotifySphere Admin Panel](#notifysphere-admin-panel)
16
- 8. [Testing](#testing)
14
+ 6. [Usage](#usage)
15
+ 7. [API Reference](#api-reference)
16
+ 8. [FCM Payload Format](#fcm-payload-format)
17
17
  9. [Troubleshooting](#troubleshooting)
18
- 10. [Advanced Features](#advanced-features)
18
+ 10. [Version History](#version-history)
19
19
 
20
20
  ---
21
21
 
22
- ## Overview
22
+ ## Features
23
23
 
24
- ### What is NotifySphere?
25
-
26
- NotifySphere is a custom push notification solution built on top of Firebase Cloud Messaging (FCM) and Notifee, providing:
27
-
28
- - **Centralized Management**: Admin panel for sending notifications
29
- - **User Segmentation**: Target users with custom tags
30
- - **Analytics**: Track delivery, opens, and engagement
31
- - **Rich Notifications**: Support for images, sounds, and custom actions
32
- - **Cross-Platform**: Works on both Android and iOS
33
-
34
- ### Architecture
35
-
36
- ```
37
- ┌─────────────────────────────────────────────┐
38
- │ NotifySphere Admin Panel │
39
- │ • Send Notifications │
40
- │ • Manage User Segments │
41
- │ • View Analytics & Reports │
42
- └──────────────┬──────────────────────────────┘
43
-
44
-
45
- ┌─────────────────────────────────────────────┐
46
- │ NotifySphere Backend API │
47
- │ (notifysphere.dothejob.in:3008) │
48
- │ • User Registration & Token Management │
49
- │ • Tag-based Segmentation │
50
- │ • Notification Delivery via Firebase │
51
- └──────────────┬──────────────────────────────┘
52
-
53
-
54
- ┌─────────────────────────────────────────────┐
55
- │ Firebase Cloud Messaging (FCM) │
56
- │ • Push Notification Delivery │
57
- │ • Device Token Management │
58
- └──────────────┬──────────────────────────────┘
59
-
60
-
61
- ┌─────────────────────────────────────────────┐
62
- │ Your React Native App │
63
- │ • react-native-notify-sphere │
64
- │ • @react-native-firebase/messaging │
65
- │ • @notifee/react-native │
66
- └─────────────────────────────────────────────┘
67
- ```
24
+ - Foreground, background, and terminated-state notification handling
25
+ - ✅ Delivery confirmation API — fires in all three app states
26
+ - Press / click tracking API
27
+ - ✅ Smart re-registration — only calls the API when FCM token or user details change
28
+ - Automatic FCM token refresh handling
29
+ - User segmentation via custom tags
30
+ - Rich notifications — images, custom sounds, action buttons
31
+ - Bearer token authentication on all API calls
32
+ - Full TypeScript support
33
+ - ✅ Android & iOS
68
34
 
69
35
  ---
70
36
 
71
37
  ## Prerequisites
72
38
 
73
- ### Required Tools
74
-
75
- - **Node.js**: v16 or higher
76
- - **React Native**: v0.70+
77
- - **Android Studio**: Latest version (for Android development)
78
- - **Xcode**: Latest version (for iOS development)
79
- - **CocoaPods**: Latest version (for iOS dependencies)
80
-
81
- ### Firebase Project
82
-
83
- 1. Create/Select project at [Firebase Console](https://console.firebase.google.com)
84
- 2. Enable **Cloud Messaging**
85
- 3. Download configuration files:
86
- - **Android**: `google-services.json`
87
- - **iOS**: `GoogleService-Info.plist`
88
- 4. Get **Firebase Server Key**:
89
- - Firebase Console → Project Settings → Cloud Messaging → Server Key
90
-
91
- ### NotifySphere Account
92
-
93
- 1. Access NotifySphere Admin Panel (contact provider for credentials)
94
- 2. Create new application
95
- 3. Obtain **App ID** (UUID format, e.g., `123b13cc-7dcb-2dcc-8dde-565433ec8d40`)
39
+ - React Native `0.70+`
40
+ - A Firebase project with Cloud Messaging enabled
41
+ - A **NotifySphere account** with an App ID and API Token
96
42
 
97
43
  ---
98
44
 
99
45
  ## Installation
100
46
 
101
- ### Step 1: Install Packages
47
+ ### Step 1 Install the package and peer dependencies
102
48
 
103
49
  ```bash
104
- # Core NotifySphere package
105
50
  npm install react-native-notify-sphere
106
51
 
107
- # Required Firebase packages
108
- npm install @react-native-firebase/app@22.4.0
109
- npm install @react-native-firebase/messaging@22.4.0
110
-
111
- # Notifee for local notifications
112
- npm install @notifee/react-native@9.1.8
113
-
114
- # Additional dependencies
115
- npm install react-native-localize
116
- npm install react-native-device-info
117
- npm install axios
52
+ # Peer dependencies (native — must be installed in your app)
53
+ npm install @react-native-firebase/app
54
+ npm install @react-native-firebase/messaging
55
+ npm install @notifee/react-native
56
+ npm install @react-native-async-storage/async-storage
118
57
  ```
119
58
 
120
- ### Step 2: Link Native Dependencies
59
+ ### Step 2 — iOS: install pods
121
60
 
122
61
  ```bash
123
- # iOS only - Install pods
124
62
  cd ios && pod install && cd ..
125
63
  ```
126
64
 
127
- ### Step 3: Verify Installation
128
-
129
- ```bash
130
- # Check if packages are installed
131
- npm list react-native-notify-sphere @react-native-firebase/messaging @notifee/react-native
132
- ```
133
-
134
65
  ---
135
66
 
136
67
  ## Android Setup
137
68
 
138
- ### Step 1: Add Firebase Configuration
139
-
140
- **File Location**: `android/app/google-services.json`
141
-
142
- 1. Download `google-services.json` from Firebase Console
143
- 2. Place file in `android/app/` directory
69
+ ### 1. Add `google-services.json`
144
70
 
145
- ### Step 2: Configure Gradle Files
71
+ Download from the Firebase Console and place it at `android/app/google-services.json`.
146
72
 
147
- #### Root build.gradle
148
-
149
- **File**: `android/build.gradle`
73
+ ### 2. Configure `android/build.gradle`
150
74
 
151
75
  ```gradle
152
76
  buildscript {
153
77
  dependencies {
154
- // ... other dependencies
155
-
156
- // Add Google Services plugin
157
78
  classpath 'com.google.gms:google-services:4.4.0'
158
79
  }
159
80
  }
160
81
  ```
161
82
 
162
- #### App build.gradle
163
-
164
- **File**: `android/app/build.gradle`
83
+ ### 3. Configure `android/app/build.gradle`
165
84
 
166
85
  ```gradle
167
86
  apply plugin: "com.android.application"
168
87
  apply plugin: "com.facebook.react"
169
88
 
170
- // ... other configurations
171
-
172
89
  android {
173
- // ... android config
174
-
175
- // Add packaging options to avoid conflicts
176
90
  packagingOptions {
177
91
  pickFirst 'lib/x86/libc++_shared.so'
178
92
  pickFirst 'lib/x86_64/libc++_shared.so'
@@ -181,922 +95,377 @@ android {
181
95
  }
182
96
  }
183
97
 
184
- dependencies {
185
- // ... dependencies
186
- }
187
-
188
- // IMPORTANT: Apply Google Services plugin at the very bottom (last line)
98
+ // Must be the last line in the file
189
99
  apply plugin: 'com.google.gms.google-services'
190
100
  ```
191
101
 
192
- ### Step 3: Update AndroidManifest.xml
193
-
194
- **File**: `android/app/src/main/AndroidManifest.xml`
102
+ ### 4. Update `AndroidManifest.xml`
195
103
 
196
104
  ```xml
197
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
198
- xmlns:tools="http://schemas.android.com/tools"
199
- package="com.yourapp.package">
200
-
201
- <!-- Notification Permissions -->
202
- <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
203
- <uses-permission android:name="android.permission.INTERNET" />
204
- <uses-permission android:name="android.permission.VIBRATE" />
205
-
206
- <application
207
- android:name=".MainApplication"
208
- android:allowBackup="false"
209
- android:theme="@style/AppTheme">
210
-
211
- <!-- Firebase Notification Icon -->
212
- <meta-data
213
- android:name="com.google.firebase.messaging.default_notification_icon"
214
- android:resource="@drawable/ic_stat_notification"
215
- tools:replace="android:resource" />
216
-
217
- <!-- Notification Color -->
218
- <meta-data
219
- android:name="com.google.firebase.messaging.default_notification_color"
220
- android:resource="@color/notification_color"
221
- tools:replace="android:resource" />
222
-
223
- <!-- Default Notification Channel -->
224
- <meta-data
225
- android:name="com.google.firebase.messaging.default_notification_channel_id"
226
- android:value="default_notification_channel"
227
- tools:replace="android:value" />
228
-
229
- <!-- Your Activities -->
230
- <activity
231
- android:name=".MainActivity"
232
- android:exported="true">
233
- <!-- ... intent filters ... -->
234
- </activity>
235
-
236
- </application>
237
- </manifest>
238
- ```
105
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
106
+ <uses-permission android:name="android.permission.INTERNET" />
107
+ <uses-permission android:name="android.permission.VIBRATE" />
239
108
 
240
- ### Step 4: Create Resource Files
109
+ <application ...>
110
+ <!-- Default notification icon -->
111
+ <meta-data
112
+ android:name="com.google.firebase.messaging.default_notification_icon"
113
+ android:resource="@drawable/ic_stat_onesignal_default"
114
+ tools:replace="android:resource" />
241
115
 
242
- #### Colors
243
-
244
- **File**: `android/app/src/main/res/values/colors.xml`
245
-
246
- ```xml
247
- <?xml version="1.0" encoding="utf-8"?>
248
- <resources>
249
- <color name="notification_color">#FF6B6B</color>
250
- <color name="ic_launcher_background">#FFFFFF</color>
251
- <color name="white">#FFFFFF</color>
252
- <color name="black">#000000</color>
253
- </resources>
116
+ <!-- Default notification channel -->
117
+ <meta-data
118
+ android:name="com.google.firebase.messaging.default_notification_channel_id"
119
+ android:value="channel_default"
120
+ tools:replace="android:value" />
121
+ </application>
254
122
  ```
255
123
 
256
- #### Strings
124
+ ### 5. Add notification icon
257
125
 
258
- **File**: `android/app/src/main/res/values/strings.xml`
259
-
260
- ```xml
261
- <?xml version="1.0" encoding="utf-8"?>
262
- <resources>
263
- <string name="app_name">Your App Name</string>
264
- </resources>
126
+ Place your notification icon at:
265
127
  ```
266
-
267
- #### Styles
268
-
269
- **File**: `android/app/src/main/res/values/styles.xml`
270
-
271
- ```xml
272
- <?xml version="1.0" encoding="utf-8"?>
273
- <resources>
274
- <style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
275
- <item name="android:textColor">#000000</item>
276
- </style>
277
- </resources>
128
+ android/app/src/main/res/drawable/ic_stat_onesignal_default.png
278
129
  ```
279
130
 
280
- ### Step 5: Add Notification Icon
281
-
282
- Create a notification icon and place it in:
283
- - `android/app/src/main/res/drawable/ic_stat_notification.png`
284
-
285
- Or use an existing icon in your project.
286
-
287
131
  ---
288
132
 
289
133
  ## iOS Setup
290
134
 
291
- ### Step 1: Add Firebase Configuration
292
-
293
- 1. Download `GoogleService-Info.plist` from Firebase Console
294
- 2. Open Xcode: `open ios/YourApp.xcworkspace`
295
- 3. Drag and drop `GoogleService-Info.plist` into Xcode project
296
- 4. Ensure "Copy items if needed" is checked
297
- 5. Add to all targets
298
-
299
- ### Step 2: Install CocoaPods
300
-
301
- ```bash
302
- cd ios
303
- pod install
304
- cd ..
305
- ```
306
-
307
- ### Step 3: Enable Capabilities in Xcode
135
+ ### 1. Add `GoogleService-Info.plist`
308
136
 
309
- 1. Open `ios/YourApp.xcworkspace` in Xcode
310
- 2. Select Project → Target → **Signing & Capabilities**
311
- 3. Click **+ Capability**
312
- 4. Add **"Push Notifications"**
313
- 5. Click **+ Capability** again
314
- 6. Add **"Background Modes"**
315
- - Check: ☑️ **Remote notifications**
137
+ Download from the Firebase Console, open Xcode, and drag the file into your project root. Make sure "Copy items if needed" is checked and it is added to all targets.
316
138
 
317
- ### Step 4: Update AppDelegate
139
+ ### 2. Enable capabilities in Xcode
318
140
 
319
- **File**: `ios/YourApp/AppDelegate.mm` (or `AppDelegate.m`)
141
+ Go to **Target Signing & Capabilities → + Capability** and add:
142
+ - `Push Notifications`
143
+ - `Background Modes` → check **Remote notifications**
320
144
 
321
- #### Add Imports
145
+ ### 3. Update `AppDelegate.mm`
322
146
 
323
147
  ```objc
324
148
  #import <Firebase.h>
325
149
  #import <UserNotifications/UserNotifications.h>
326
- ```
327
-
328
- #### Update didFinishLaunchingWithOptions
329
150
 
330
- ```objc
331
- - (BOOL)application:(UIApplication *)application
151
+ - (BOOL)application:(UIApplication *)application
332
152
  didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
333
153
  {
334
- // Initialize Firebase
335
154
  if ([FIRApp defaultApp] == nil) {
336
155
  [FIRApp configure];
337
156
  }
338
-
339
- // Set up notification center
340
157
  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
341
158
  center.delegate = self;
342
-
343
- // ... rest of your existing code
344
-
345
159
  return YES;
346
160
  }
347
- ```
348
161
 
349
- #### Add Notification Handler Methods
350
-
351
- ```objc
352
- // Handle foreground notifications
353
162
  - (void)userNotificationCenter:(UNUserNotificationCenter *)center
354
163
  willPresentNotification:(UNNotification *)notification
355
- withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
356
- {
357
- completionHandler(UNNotificationPresentationOptionSound |
358
- UNNotificationPresentationOptionAlert |
359
- UNNotificationPresentationOptionBadge);
360
- }
361
-
362
- // Handle notification tap
363
- - (void)userNotificationCenter:(UNUserNotificationCenter *)center
364
- didReceiveNotificationResponse:(UNNotificationResponse *)response
365
- withCompletionHandler:(void(^)(void))completionHandler
164
+ withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
366
165
  {
367
- completionHandler();
166
+ completionHandler(UNNotificationPresentationOptionSound |
167
+ UNNotificationPresentationOptionAlert |
168
+ UNNotificationPresentationOptionBadge);
368
169
  }
369
170
  ```
370
171
 
371
172
  ---
372
173
 
373
- ## Implementation
174
+ ## Usage
374
175
 
375
- ### Step 1: Create NotificationHelper Component
176
+ You need two things from your NotifySphere dashboard before you start:
177
+ - **App ID** — identifies your application
178
+ - **API Token** — authenticates all requests to the NotifySphere API
376
179
 
377
- **File**: `src/utils/NotificationHelper.tsx`
180
+ ### `index.js` — register the background handler
378
181
 
379
- ```typescript
380
- import { useEffect, useCallback } from 'react';
381
- import { Platform } from 'react-native';
382
- import NotifySphere from 'react-native-notify-sphere';
383
- import { useNavigation } from '@react-navigation/native';
384
-
385
- interface Props {
386
- navigationRef?: any;
387
- }
182
+ This **must** be called before `AppRegistry.registerComponent()` so the handler is in place when the app is woken from a terminated state to handle a background notification.
388
183
 
389
- export let deviceInfo: any = {};
390
-
391
- const NotificationHelper: React.FC<Props> = (props) => {
392
- const navigation = useNavigation();
393
-
394
- // Handle notification click
395
- const onClickNotification = useCallback(
396
- (notificationData: any, type?: string) => {
397
- console.log('📬 Notification Clicked');
398
- console.log('Type:', type);
399
- console.log('Data:', notificationData);
400
-
401
- const data = notificationData?.data || {};
402
- const action = data?.redirect_action;
403
-
404
- // Navigate based on action
405
- switch (action) {
406
- case 'home':
407
- navigation.navigate('Home');
408
- break;
409
-
410
- case 'profile':
411
- navigation.navigate('Profile');
412
- break;
413
-
414
- case 'details':
415
- if (data?.itemId) {
416
- navigation.navigate('Details', { id: data.itemId });
417
- }
418
- break;
419
-
420
- default:
421
- // Default navigation
422
- console.log('No specific action, staying on current screen');
423
- break;
424
- }
425
- },
426
- [navigation]
427
- );
428
-
429
- useEffect(() => {
430
- const initializeNotifications = async () => {
431
- try {
432
- console.log('🔥 Initializing NotifySphere...');
433
-
434
- // Get user information (replace with your actual user data)
435
- const userId = 12345; // Your user ID
436
- const userName = 'John Doe';
437
- const userEmail = 'john@example.com';
438
- const userPhone = 9876543210;
439
-
440
- // Initialize NotifySphere
441
- const subscriptionId = await NotifySphere.initialize({
442
- applicationUserId: userId,
443
- type: Platform.OS === 'android' ? 'AndroidPush' : 'IOSPush',
444
- name: userName,
445
- email: userEmail,
446
- appId: 'YOUR_NOTIFYSPHERE_APP_ID', // Replace with your App ID
447
- phone: userPhone,
448
- lat: '26.9124', // Optional: User latitude
449
- long: '75.7873', // Optional: User longitude
450
- city: 'Jaipur', // Optional: User city
451
- state: 'Rajasthan', // Optional: User state
452
- tags: {
453
- userType: 'customer',
454
- premium: 'true',
455
- // Add your custom tags
456
- },
457
- });
458
-
459
- console.log('✅ NotifySphere Initialized!');
460
- console.log('Subscription ID:', subscriptionId);
461
-
462
- // Store subscription ID
463
- deviceInfo.userId = subscriptionId;
464
-
465
- // Update tags (optional - for better targeting)
466
- NotifySphere.updateTags({
467
- appId: 'YOUR_NOTIFYSPHERE_APP_ID',
468
- applicationUserId: userId,
469
- type: Platform.OS === 'android' ? 'AndroidPush' : 'IOSPush',
470
- tags: {
471
- lastLogin: new Date().toISOString(),
472
- appVersion: '1.0.0',
473
- // Add more tags as needed
474
- },
475
- });
476
-
477
- // Set notification callback
478
- NotifySphere.onNotification((notification, type) => {
479
- console.log('🔔 Notification Callback Triggered');
480
- console.log('Type:', type); // 'opened', 'initial', 'press'
481
-
482
- // Handle notification
483
- onClickNotification(notification, type);
484
- });
485
-
486
- console.log('✅ Notification handlers registered!');
487
-
488
- } catch (error) {
489
- console.error('❌ NotifySphere Error:', error);
490
- }
491
- };
492
-
493
- initializeNotifications();
494
- }, [onClickNotification]);
495
-
496
- return null;
497
- };
498
-
499
- export default NotificationHelper;
500
- ```
501
-
502
- ### Step 2: Add to Your App
503
-
504
- **File**: `App.tsx`
505
-
506
- ```typescript
507
- import React from 'react';
508
- import { NavigationContainer } from '@react-navigation/native';
509
- import { Provider } from 'react-redux';
510
- import NotificationHelper from './src/utils/NotificationHelper';
511
- import store from './src/redux/store';
512
-
513
- const App = () => {
514
- return (
515
- <Provider store={store}>
516
- <NavigationContainer>
517
- {/* Your navigation stack */}
518
- <YourNavigationStack />
519
-
520
- {/* Add NotificationHelper */}
521
- <NotificationHelper />
522
- </NavigationContainer>
523
- </Provider>
524
- );
525
- };
526
-
527
- export default App;
528
- ```
529
-
530
- ### Step 3: Replace App ID
531
-
532
- In `NotificationHelper.tsx`, replace:
533
- ```typescript
534
- appId: 'YOUR_NOTIFYSPHERE_APP_ID'
535
- ```
536
-
537
- With your actual NotifySphere App ID from the admin panel.
538
-
539
- ---
540
-
541
- ## NotifySphere Admin Panel
542
-
543
- ### Step 1: Create Application
544
-
545
- 1. **Login** to NotifySphere Admin Panel
546
- 2. Click **"Create New App"**
547
- 3. Fill in details:
548
- - **App Name**: Your application name
549
- - **Platform**: Select Android and/or iOS
550
- - **Package Name**: Your app's package name
551
- 4. Click **Save**
552
- 5. **Copy the App ID** (UUID format)
553
-
554
- ### Step 2: Configure Firebase
555
-
556
- 1. Go to your app's settings in NotifySphere Admin
557
- 2. Click **"Firebase Configuration"**
558
- 3. Add **Firebase Server Key**:
559
- - Get from: Firebase Console → Project Settings → Cloud Messaging → Server Key
560
- 4. Save configuration
561
-
562
- ### Step 3: Test Setup
563
-
564
- 1. Go to **"Send Notification"** in admin panel
565
- 2. Select your app
566
- 3. Fill in basic details:
567
- - **Title**: Test Notification
568
- - **Body**: This is a test message
569
- 4. Click **Send**
570
-
571
- ---
572
-
573
- ## Testing
574
-
575
- ### Method 1: Via NotifySphere Admin Panel
184
+ ```js
185
+ import { AppRegistry } from 'react-native';
186
+ import AsyncStorage from '@react-native-async-storage/async-storage';
187
+ import App from './src/App';
188
+ import { name as appName } from './app.json';
189
+ import NotifySphere from 'react-native-notify-sphere';
190
+ import { API_TOKEN } from './src/App';
576
191
 
577
- **Recommended for production testing**
192
+ const STORAGE_KEY = '@notifysphere_subscription_id';
578
193
 
579
- 1. Login to NotifySphere Admin Panel
580
- 2. Navigate to **"Send Notification"**
581
- 3. Select your application
582
- 4. Configure notification:
194
+ // Load the persisted subscription_id so delivery receipts include it
195
+ // even when the app starts from a terminated state.
196
+ AsyncStorage.getItem(STORAGE_KEY).then((subscriptionId) => {
197
+ NotifySphere.setBackgroundHandler({
198
+ apiKey: API_TOKEN,
199
+ subscriptionId: subscriptionId ?? undefined,
200
+ });
201
+ });
583
202
 
584
- ```json
585
- {
586
- "title": "New Message",
587
- "body": "You have received a new message!",
588
- "data": {
589
- "redirect_action": "details",
590
- "itemId": "123",
591
- "type": "message"
592
- }
593
- }
203
+ AppRegistry.registerComponent(appName, () => App);
594
204
  ```
595
205
 
596
- 5. Target:
597
- - **All Users**: Send to everyone
598
- - **By Tags**: Target specific user segments
599
- - **Specific Users**: Enter user IDs
600
-
601
- 6. Click **Send**
206
+ ### `App.tsx` — initialize and listen
602
207
 
603
- ### Method 2: Via Firebase Console
604
-
605
- **Good for quick testing**
208
+ ```tsx
209
+ import { useEffect } from 'react';
210
+ import { Platform } from 'react-native';
211
+ import NotifySphere from 'react-native-notify-sphere';
606
212
 
607
- 1. Go to [Firebase Console](https://console.firebase.google.com)
608
- 2. Select your project
609
- 3. Navigate to **Cloud Messaging** **Send your first message**
610
- 4. Click **"Send test message"**
611
- 5. Get FCM token from app logs:
213
+ const APP_ID = 'your-notifysphere-app-id';
214
+ export const API_TOKEN = 'your-api-token'; // Get this from your NotifySphere dashboard
215
+ const PUSH_TYPE = Platform.OS === 'android' ? 'AndroidPush' : 'IOSPush';
612
216
 
613
- ```bash
614
- # Android
615
- npx react-native log-android | grep "fcmToken"
616
-
617
- # iOS
618
- npx react-native log-ios | grep "fcmToken"
619
- ```
217
+ export default function App() {
218
+ useEffect(() => {
219
+ const init = async () => {
220
+ // Safe to call on every app open — only hits the registration API
221
+ // when the FCM token or user details have changed.
222
+ const subscriptionId = await NotifySphere.initialize({
223
+ applicationUserId: 123, // your internal user ID
224
+ type: PUSH_TYPE,
225
+ appId: APP_ID,
226
+ apiKey: API_TOKEN,
227
+ name: 'John Doe',
228
+ email: 'john@example.com',
229
+ phone: '9876543210', // string — preserves leading zeros
230
+ lat: '26.9124',
231
+ long: '75.7873',
232
+ city: 'Jaipur',
233
+ state: 'Rajasthan',
234
+ tags: {
235
+ userType: 'customer',
236
+ premium: 'true',
237
+ },
238
+ debug: __DEV__, // enable verbose logs in development
239
+ });
240
+
241
+ console.log('NotifySphere subscriptionId:', subscriptionId);
242
+
243
+ // Optionally update tags without re-registering the device
244
+ await NotifySphere.updateTags({
245
+ applicationUserId: 123,
246
+ type: PUSH_TYPE,
247
+ tags: { lastLogin: new Date().toISOString() },
248
+ });
249
+ };
620
250
 
621
- 6. Paste token and click **Test**
251
+ init();
622
252
 
623
- ### Method 3: Via Postman/API
253
+ // Listen for all notification events
254
+ NotifySphere.onNotification((notification, type) => {
255
+ console.log('Notification event:', type, notification);
624
256
 
625
- **For automated testing**
257
+ if (type === 'press' || type === 'opened' || type === 'initial') {
258
+ // User tapped the notification — navigate, show modal, etc.
259
+ }
626
260
 
627
- ```http
628
- POST https://fcm.googleapis.com/fcm/send
629
- Content-Type: application/json
630
- Authorization: key=YOUR_FIREBASE_SERVER_KEY
261
+ if (type === 'received') {
262
+ // Notification arrived while the app was in the foreground
263
+ }
264
+ });
631
265
 
632
- {
633
- "to": "DEVICE_FCM_TOKEN",
634
- "notification": {
635
- "title": "Test Notification",
636
- "body": "Testing push notifications"
637
- },
638
- "data": {
639
- "redirect_action": "home",
640
- "customKey": "customValue"
641
- },
642
- "android": {
643
- "priority": "high"
644
- },
645
- "apns": {
646
- "headers": {
647
- "apns-priority": "10"
648
- }
649
- }
266
+ // Clean up listeners on unmount / logout
267
+ return () => NotifySphere.destroy();
268
+ }, []);
650
269
  }
651
270
  ```
652
271
 
653
- ### Test Scenarios
654
-
655
- #### ✅ Foreground Testing (App Open)
656
-
657
- **Expected Behavior:**
658
- - Notification displays as banner/head-up notification
659
- - Sound plays (if configured)
660
- - Vibration occurs (if configured)
661
- - Tapping navigates to specified screen
662
-
663
- **Verification:**
664
- ```bash
665
- npx react-native log-android | grep "displayLocalNotification"
666
- # Should see: "✅ NOTIFICATION DISPLAYED SUCCESSFULLY!"
667
- ```
668
-
669
- #### ✅ Background Testing (App Minimized)
670
-
671
- **Expected Behavior:**
672
- - Notification appears in notification tray
673
- - Tapping opens app
674
- - Navigation occurs after app opens
675
-
676
- #### ✅ Killed State Testing (App Closed)
677
-
678
- **Expected Behavior:**
679
- - Notification appears in notification tray
680
- - Tapping launches app
681
- - Navigation occurs after app launches
682
-
683
- **Verification:**
684
- ```bash
685
- npx react-native log-android | grep "Notification Callback"
686
- # Should see: Type: 'initial' or 'opened'
687
- ```
272
+ > **Security note:** Never commit your `API_TOKEN` to source control. In production, read it from a secure config file or environment variable (e.g. via `react-native-config`).
688
273
 
689
274
  ---
690
275
 
691
- ## Troubleshooting
692
-
693
- ### Common Issues
694
-
695
- #### Issue: "No FCM Token Received"
696
-
697
- **Symptoms:**
698
- - No token in logs
699
- - Notifications not received
700
-
701
- **Solutions:**
702
-
703
- 1. **Check Firebase Configuration:**
704
- ```bash
705
- # Android
706
- ls -la android/app/google-services.json
707
-
708
- # iOS
709
- ls -la ios/GoogleService-Info.plist
710
- ```
276
+ ## API Reference
277
+
278
+ ### `NotifySphere.initialize(config)`
279
+
280
+ Initialises the SDK, registers the device with the NotifySphere server, and sets up notification listeners. Safe to call on every app open — the registration API is only called when the FCM token or user details have changed since the last run.
281
+
282
+ **Returns:** `Promise<string | undefined>` — the `subscription_id` assigned by the server.
283
+
284
+ | Field | Type | Required | Description |
285
+ |---|---|---|---|
286
+ | `applicationUserId` | `number` | ✅ | Your internal user ID for this device |
287
+ | `type` | `string` | ✅ | `'AndroidPush'` or `'IOSPush'` |
288
+ | `appId` | `string` | ✅ | Your NotifySphere App ID |
289
+ | `apiKey` | `string` | ✅ | Bearer token from your NotifySphere dashboard |
290
+ | `name` | `string` | | User display name |
291
+ | `email` | `string` | | User email address |
292
+ | `phone` | `string` | | User phone number (string to preserve leading zeros) |
293
+ | `lat` | `string` | | User latitude |
294
+ | `long` | `string` | | User longitude |
295
+ | `city` | `string` | | User city |
296
+ | `state` | `string` | | User state / region |
297
+ | `tags` | `Record<string, string>` | | Custom key-value segmentation tags |
298
+ | `baseUrl` | `string` | | Override the API base URL (defaults to hosted service) |
299
+ | `trackingUrl` | `string` | | Override the press-tracking endpoint |
300
+ | `deliveryUrl` | `string` | | Override the delivery-confirmation endpoint |
301
+ | `debug` | `boolean` | | Enable verbose `[NotifySphere]` console logs (default: `false`) |
711
302
 
712
- 2. **Verify Google Services Plugin:**
713
- ```bash
714
- cat android/app/build.gradle | grep "google-services"
715
- # Should be at the very bottom of the file
716
- ```
717
-
718
- 3. **Check Permissions:**
719
- ```bash
720
- # Android - Check if permission granted
721
- adb shell dumpsys package com.yourapp.package | grep "POST_NOTIFICATIONS"
722
- ```
723
-
724
- #### Issue: "Foreground Notifications Not Displaying"
725
-
726
- **Error in logs:**
727
- ```
728
- ❌ ERROR in displayLocalNotification
729
- Error: largeIcon expected a valid string URL
730
- ```
731
-
732
- **Solution:**
733
-
734
- The package has a known issue with empty `largeIcon` field. Fix by editing package:
735
-
736
- ```bash
737
- code node_modules/react-native-notify-sphere/src/index.tsx
738
- ```
739
-
740
- Find `displayLocalNotification` function and update:
741
-
742
- ```typescript
743
- // Validate largeIcon before using
744
- const largeIconRaw = remoteMessage.data?.largeIcon;
745
- const validLargeIcon = largeIconRaw && largeIconRaw.trim() !== ''
746
- ? largeIconRaw
747
- : undefined;
748
-
749
- // Only add if valid
750
- if (validLargeIcon) {
751
- notificationConfig.android.largeIcon = validLargeIcon;
752
- }
753
- ```
754
-
755
- #### Issue: "App Crashes on Notification"
756
-
757
- **Symptoms:**
758
- - App crashes when notification received
759
- - No error in React Native logs
760
-
761
- **Solutions:**
303
+ ---
762
304
 
763
- 1. **Check Native Logs:**
764
- ```bash
765
- # Android
766
- adb logcat | grep -i "error\|exception"
305
+ ### `NotifySphere.setBackgroundHandler(config?)`
767
306
 
768
- # iOS
769
- # View in Xcode console
770
- ```
771
-
772
- 2. **Verify Channel Creation:**
773
- ```bash
774
- npx react-native log-android | grep "Channel created"
775
- ```
307
+ Registers Firebase and Notifee background/terminated-state handlers. **Must be called in `index.js`** before `AppRegistry.registerComponent()`.
776
308
 
777
- 3. **Check Sound Files:**
778
- - Ensure custom sound files exist in `android/app/src/main/res/raw/`
779
- - Use `default` sound if custom sound missing
309
+ When the app is **terminated**, `initialize()` never runs, so any config you passed there is not available. Pass `apiKey` and `subscriptionId` here directly so delivery receipts still work.
780
310
 
781
- #### Issue: "iOS Notifications Not Working"
311
+ | Field | Type | Description |
312
+ |---|---|---|
313
+ | `apiKey` | `string` | Bearer token — required for authenticated delivery receipts in terminated state |
314
+ | `subscriptionId` | `string` | Persisted subscription ID — include it so receipts are linked to the correct device |
315
+ | `deliveryUrl` | `string` | Override the delivery URL for terminated state (optional) |
782
316
 
783
- **Common Causes:**
317
+ ---
784
318
 
785
- 1. **Testing on Simulator:**
786
- - Push notifications **DO NOT work** on iOS Simulator
787
- - Must test on real device
319
+ ### `NotifySphere.onNotification(callback)`
788
320
 
789
- 2. **Missing Capabilities:**
790
- - Xcode → Target → Signing & Capabilities
791
- - Verify "Push Notifications" is enabled
792
- - Verify "Background Modes" → "Remote notifications" is checked
321
+ Register a callback to receive all notification events.
793
322
 
794
- 3. **Firebase Not Initialized:**
795
- ```objc
796
- // Check AppDelegate.mm
797
- if ([FIRApp defaultApp] == nil) {
798
- [FIRApp configure]; // Must be present
799
- }
323
+ ```ts
324
+ NotifySphere.onNotification((notification, type) => {
325
+ // notification: { title, body, data, image, sound }
326
+ // type: 'received' | 'press' | 'opened' | 'initial'
327
+ });
800
328
  ```
801
329
 
802
- 4. **Provisioning Profile:**
803
- - Ensure push notifications are enabled in Apple Developer Portal
804
- - Regenerate provisioning profile if needed
330
+ | Event type | When it fires |
331
+ |---|---|
332
+ | `received` | Notification arrived while the app was in the foreground |
333
+ | `press` | A Notifee background notification was tapped |
334
+ | `opened` | App brought from background via notification tap |
335
+ | `initial` | App launched from a quit state via notification tap |
805
336
 
806
- #### Issue: "Notification Data Not Received in Callback"
807
-
808
- **Symptoms:**
809
- - Notification displays
810
- - Callback triggered
811
- - But `data` object is empty
337
+ ---
812
338
 
813
- **Solution:**
339
+ ### `NotifySphere.updateTags(params)`
814
340
 
815
- Check notification payload structure:
341
+ Updates user tags without re-registering the device. `appId` is optional — falls back to the value passed in `initialize()`.
816
342
 
817
- ```json
818
- {
819
- "notification": {
820
- "title": "Title",
821
- "body": "Body"
822
- },
823
- "data": {
824
- "redirect_action": "home",
825
- "itemId": "123"
826
- }
827
- }
343
+ ```ts
344
+ await NotifySphere.updateTags({
345
+ applicationUserId: 123,
346
+ type: 'AndroidPush',
347
+ tags: { premium: 'true', age: '33' },
348
+ });
828
349
  ```
829
350
 
830
- Ensure `data` is separate from `notification` object.
831
-
832
- ### Debug Commands
833
-
834
- ```bash
835
- # Android - View all logs
836
- npx react-native log-android
837
-
838
- # Android - Filter notification logs
839
- npx react-native log-android | grep -E "NotifySphere|fcm|notification"
840
-
841
- # iOS - View all logs
842
- npx react-native log-ios
843
-
844
- # iOS - Filter notification logs
845
- npx react-native log-ios | grep -E "NotifySphere|Firebase|notification"
846
-
847
- # Check app processes
848
- adb shell ps | grep com.yourapp.package
849
-
850
- # Kill app (Android)
851
- adb shell am force-stop com.yourapp.package
852
-
853
- # Clear app data (Android)
854
- adb shell pm clear com.yourapp.package
855
- ```
351
+ | Field | Type | Required | Description |
352
+ |---|---|---|---|
353
+ | `applicationUserId` | `number` | ✅ | Your internal user ID |
354
+ | `type` | `string` | ✅ | `'AndroidPush'` or `'IOSPush'` |
355
+ | `tags` | `Record<string, string>` | ✅ | Tags to update |
356
+ | `appId` | `string` | | Defaults to the `appId` passed in `initialize()` |
856
357
 
857
358
  ---
858
359
 
859
- ## Advanced Features
860
-
861
- ### Custom Tags for User Segmentation
862
-
863
- ```typescript
864
- NotifySphere.updateTags({
865
- appId: 'YOUR_APP_ID',
866
- applicationUserId: userId,
867
- type: Platform.OS === 'android' ? 'AndroidPush' : 'IOSPush',
868
- tags: {
869
- // Demographic
870
- age: '25-34',
871
- gender: 'male',
872
- location: 'New York',
873
-
874
- // Behavioral
875
- purchaseFrequency: 'high',
876
- lastPurchase: '2024-01-01',
877
- totalSpent: '5000',
878
-
879
- // Engagement
880
- appVersion: '2.1.0',
881
- lastLogin: new Date().toISOString(),
882
- notificationsEnabled: 'true',
883
-
884
- // Custom
885
- interests: 'sports,technology',
886
- membershipLevel: 'premium',
887
- },
888
- });
889
- ```
360
+ ### `NotifySphere.destroy()`
890
361
 
891
- ### Rich Notifications with Images
362
+ Unsubscribes all active listeners and resets internal state. Call this on logout or when you no longer need notifications.
892
363
 
893
- Send from admin panel or API:
894
-
895
- ```json
896
- {
897
- "notification": {
898
- "title": "New Product Launch",
899
- "body": "Check out our latest collection!",
900
- "image": "https://example.com/image.jpg"
901
- },
902
- "data": {
903
- "redirect_action": "product_details",
904
- "productId": "P123"
905
- }
906
- }
364
+ ```ts
365
+ NotifySphere.destroy();
907
366
  ```
908
367
 
909
- ### Custom Sounds
910
-
911
- **Android:**
368
+ ---
912
369
 
913
- 1. Add sound file: `android/app/src/main/res/raw/custom_sound.mp3`
914
- 2. Send notification with sound:
370
+ ### `NotifySphere.checkApplicationPermission()`
915
371
 
916
- ```json
917
- {
918
- "data": {
919
- "sound": "custom_sound"
920
- }
921
- }
922
- ```
372
+ Requests notification permission from the OS and returns `true` if granted. Called automatically by `initialize()` — you only need to call this directly if you want to check permission status before initialising.
923
373
 
924
- **iOS:**
374
+ ---
925
375
 
926
- 1. Add sound file to Xcode project
927
- 2. Ensure file is added to target
928
- 3. Send notification with sound in payload
376
+ ## FCM Payload Format
929
377
 
930
- ### Action Buttons
378
+ NotifySphere expects **data-only** FCM messages (no `notification` field). This is required for delivery confirmation to work in the terminated state.
931
379
 
932
380
  ```json
933
381
  {
382
+ "to": "<device-fcm-token>",
934
383
  "data": {
935
- "actionButtons": "[{\"title\":\"View\",\"pressAction\":{\"id\":\"view\"}},{\"title\":\"Dismiss\",\"pressAction\":{\"id\":\"dismiss\"}}]"
384
+ "title": "Hello!",
385
+ "body": "You have a new message.",
386
+ "notification_id": "uuid-here",
387
+ "sound": "default",
388
+ "imageUrl": "https://example.com/image.jpg",
389
+ "smallIcon": "ic_stat_onesignal_default",
390
+ "redirect_action": "home"
936
391
  }
937
392
  }
938
393
  ```
939
394
 
940
- ### Notification Scheduling
941
-
942
- Currently, NotifySphere handles immediate delivery. For scheduled notifications, use the admin panel's scheduling feature or implement server-side scheduling.
395
+ > **Why data-only?** If a `notification` field is present in the FCM payload, the OS handles display silently — your JavaScript never runs and delivery receipts cannot fire in the terminated state.
943
396
 
944
- ### Analytics Tracking
397
+ ### Supported `data` fields
945
398
 
946
- NotifySphere automatically tracks:
947
- - Notification delivery
948
- - Open rates
949
- - Click rates
950
- - Device information
951
-
952
- View in admin panel: **Analytics Notification Reports**
399
+ | Field | Description |
400
+ |---|---|
401
+ | `title` | Notification title |
402
+ | `body` | Notification body text |
403
+ | `notification_id` | ID used for delivery and press tracking |
404
+ | `sound` | Sound file name without extension, or `'default'` |
405
+ | `imageUrl` | URL for a big-picture style notification image |
406
+ | `smallIcon` | Android small icon resource name (falls back to `ic_stat_onesignal_default`) |
407
+ | `actionButtons` | JSON string of Notifee action button definitions |
953
408
 
954
409
  ---
955
410
 
956
- ## Best Practices
957
-
958
- ### 1. User Privacy
959
-
960
- ```typescript
961
- // Request permission gracefully
962
- const hasPermission = await NotifySphere.checkApplicationPermission();
963
-
964
- if (!hasPermission) {
965
- // Show explanation UI
966
- showPermissionExplanation();
967
- // Then request
968
- await requestPermission();
969
- }
970
- ```
971
-
972
- ### 2. Tag Management
973
-
974
- ```typescript
975
- // Update tags when relevant data changes
976
- useEffect(() => {
977
- if (user.profileUpdated) {
978
- NotifySphere.updateTags({
979
- appId: APP_ID,
980
- applicationUserId: user.id,
981
- type: Platform.OS === 'android' ? 'AndroidPush' : 'IOSPush',
982
- tags: {
983
- profileComplete: 'true',
984
- lastUpdated: new Date().toISOString(),
985
- },
986
- });
987
- }
988
- }, [user.profileUpdated]);
989
- ```
990
-
991
- ### 3. Error Handling
992
-
993
- ```typescript
994
- try {
995
- const subscriptionId = await NotifySphere.initialize({...});
996
-
997
- if (!subscriptionId) {
998
- // Handle initialization failure
999
- logError('NotifySphere initialization failed');
1000
- // Retry or fallback
1001
- }
1002
- } catch (error) {
1003
- // Handle error gracefully
1004
- logError('NotifySphere error:', error);
1005
- // Show user-friendly message if needed
1006
- }
1007
- ```
1008
-
1009
- ### 4. Testing Checklist
1010
-
1011
- - [ ] Test on real devices (iOS especially)
1012
- - [ ] Test all notification states (foreground, background, killed)
1013
- - [ ] Test navigation for each `redirect_action`
1014
- - [ ] Test with different payload structures
1015
- - [ ] Test with images
1016
- - [ ] Test with custom sounds
1017
- - [ ] Test user segmentation with tags
1018
- - [ ] Verify analytics tracking
1019
- - [ ] Test opt-out functionality
1020
-
1021
- ---
1022
-
1023
- ## Package Information
411
+ ## Troubleshooting
1024
412
 
1025
- ### Dependencies
413
+ ### API calls returning 401 Unauthorized
1026
414
 
1027
- ```json
1028
- {
1029
- "react-native-notify-sphere": "^1.0.0",
1030
- "@react-native-firebase/app": "22.4.0",
1031
- "@react-native-firebase/messaging": "22.4.0",
1032
- "@notifee/react-native": "9.1.8",
1033
- "react-native-device-info": "latest",
1034
- "react-native-localize": "latest",
1035
- "axios": "latest"
1036
- }
1037
- ```
415
+ Make sure you are passing `apiKey` in both `initialize()` and `setBackgroundHandler()`. The API Token can be found in your NotifySphere dashboard under your app settings.
1038
416
 
1039
- ### Package Features
417
+ ### Notifications not displaying on Android
1040
418
 
1041
- - Automatic foreground notification display
1042
- - ✅ Background notification handling
1043
- - ✅ Notification tap handling
1044
- - ✅ Custom tags for segmentation
1045
- - ✅ Image support in notifications
1046
- - ✅ Custom sound support
1047
- - ✅ Analytics tracking
1048
- - ✅ Action buttons support
1049
- - ✅ Cross-platform (Android & iOS)
419
+ Check that `ic_stat_onesignal_default.png` exists at `android/app/src/main/res/drawable/`. Android silently drops notifications with a missing or invalid small icon.
1050
420
 
1051
- ---
421
+ ### Delivery receipt not firing in terminated state
1052
422
 
1053
- ## Resources
423
+ Make sure you are sending a **data-only** FCM message (no `notification` field in the payload). Also confirm that `setBackgroundHandler()` is called in `index.js` before `AppRegistry.registerComponent()`, and that you are passing both `apiKey` and `subscriptionId` to it.
1054
424
 
1055
- ### Documentation
425
+ ### `async-storage` build error
1056
426
 
1057
- - [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging)
1058
- - [Notifee Documentation](https://notifee.app/react-native/docs/overview)
1059
- - [React Native Firebase](https://rnfirebase.io/)
427
+ Use `@react-native-async-storage/async-storage@^1.23.1`. Version 2+ requires a custom Maven repository that is not configured by default in most React Native projects.
1060
428
 
1061
- ### Useful Commands
429
+ ### iOS notifications not working
1062
430
 
1063
- ```bash
1064
- # Clean build
1065
- cd android && ./gradlew clean && cd ..
1066
- rm -rf node_modules && npm install
431
+ Push notifications do not work on the iOS Simulator. Test on a physical device with a push-enabled provisioning profile.
1067
432
 
1068
- # iOS clean
1069
- cd ios && pod deintegrate && pod install && cd ..
433
+ ### Debug logging
1070
434
 
1071
- # Run app
1072
- npm run android
1073
- npm run ios
435
+ Pass `debug: true` (or `debug: __DEV__`) to `initialize()` to see verbose `[NotifySphere]` logs in the Metro console:
1074
436
 
1075
- # View logs
1076
- npx react-native log-android
1077
- npx react-native log-ios
437
+ ```ts
438
+ await NotifySphere.initialize({ ..., debug: __DEV__ });
1078
439
  ```
1079
440
 
1080
441
  ---
1081
442
 
1082
- ## Support
443
+ ## Version History
1083
444
 
1084
- For issues or questions:
445
+ ### v1.2.0 (March 2026)
1085
446
 
1086
- 1. Check logs for error messages
1087
- 2. Verify all configuration steps
1088
- 3. Test on real devices (especially iOS)
1089
- 4. Check Firebase and NotifySphere admin panels
1090
- 5. Contact NotifySphere support if needed
447
+ - **Bearer token authentication** all API endpoints now require an `apiKey` (Bearer token); added to `initialize()`, `registerDevice`, and `setBackgroundHandler()`
448
+ - **Updated API URL structure** — endpoints now follow `client/{appId}/...` path pattern
449
+ - **Fixed `registerDevice` URL** corrected a template literal bug that was constructing an invalid URL
450
+ - **Fixed `updateTags` URL** removed incorrect `/apps/` path segment
451
+ - **Dynamic tracking / delivery URLs** — `trackingUrl` and `deliveryUrl` are now built with `appId` at runtime rather than using static defaults
1091
452
 
1092
- ---
453
+ ### v1.1.0 (January 2026)
1093
454
 
1094
- ## Version History
455
+ - **Delivery confirmation API** — fires in foreground, background, and terminated state
456
+ - **Smart re-registration** — registration API only called when FCM token or user details change
457
+ - **Automatic token refresh** — `onTokenRefresh` watcher re-registers without requiring another `initialize()` call
458
+ - **`destroy()` method** — clean listener unsubscription on logout
459
+ - **Configurable endpoints** — `baseUrl`, `trackingUrl`, `deliveryUrl` in `initialize()`
460
+ - **`phone` changed to `string`** — prevents corruption of numbers with leading zeros
461
+ - **`appId` stored internally** — `updateTags` no longer requires passing `appId` again
462
+ - **`debug` flag** — all `console.log` calls gated behind `debug: true`
463
+ - **Removed unused dependencies** — `react-native-device-info`, `react-native-localize`
464
+
465
+ ### v1.0.1 (October 2025)
1095
466
 
1096
- - **v1.0.0** (January 2026) - Initial implementation guide
467
+ - Initial release
1097
468
 
1098
469
  ---
1099
470
 
1100
- **Created:** January 7, 2026
1101
- **Status:** ✅ Production Ready
1102
471
  **Platform Support:** Android ✅ | iOS ✅