react-native-notify-sphere 1.1.0 → 1.2.1
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 +271 -902
- package/lib/module/index.js +242 -33
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/index.d.ts +45 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/index.tsx +287 -34
package/README.md
CHANGED
|
@@ -1,178 +1,92 @@
|
|
|
1
|
-
#
|
|
1
|
+
# react-native-notify-sphere
|
|
2
2
|
|
|
3
|
-
|
|
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. [
|
|
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. [
|
|
15
|
-
7. [
|
|
16
|
-
8. [
|
|
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. [
|
|
18
|
+
10. [Version History](#version-history)
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
##
|
|
22
|
+
## Features
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
- **
|
|
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
|
|
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
|
-
#
|
|
108
|
-
npm install @react-native-firebase/app
|
|
109
|
-
npm install @react-native-firebase/messaging
|
|
110
|
-
|
|
111
|
-
|
|
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:
|
|
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
|
-
###
|
|
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
|
-
|
|
71
|
+
Download from the Firebase Console and place it at `android/app/google-services.json`.
|
|
146
72
|
|
|
147
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
193
|
-
|
|
194
|
-
**File**: `android/app/src/main/AndroidManifest.xml`
|
|
102
|
+
### 4. Update `AndroidManifest.xml`
|
|
195
103
|
|
|
196
104
|
```xml
|
|
197
|
-
<
|
|
198
|
-
|
|
199
|
-
|
|
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
|
-
|
|
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
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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
|
-
|
|
124
|
+
### 5. Add notification icon
|
|
257
125
|
|
|
258
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
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
|
-
###
|
|
139
|
+
### 2. Enable capabilities in Xcode
|
|
318
140
|
|
|
319
|
-
**
|
|
141
|
+
Go to **Target → Signing & Capabilities → + Capability** and add:
|
|
142
|
+
- `Push Notifications`
|
|
143
|
+
- `Background Modes` → check **Remote notifications**
|
|
320
144
|
|
|
321
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
##
|
|
174
|
+
## Usage
|
|
374
175
|
|
|
375
|
-
|
|
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
|
-
|
|
180
|
+
### `index.js` — register the background handler
|
|
378
181
|
|
|
379
|
-
|
|
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
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
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
|
-
|
|
192
|
+
const STORAGE_KEY = '@notifysphere_subscription_id';
|
|
578
193
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
604
|
-
|
|
605
|
-
|
|
208
|
+
```tsx
|
|
209
|
+
import { useEffect } from 'react';
|
|
210
|
+
import { Platform } from 'react-native';
|
|
211
|
+
import NotifySphere from 'react-native-notify-sphere';
|
|
606
212
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
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
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
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
|
-
|
|
251
|
+
init();
|
|
622
252
|
|
|
623
|
-
|
|
253
|
+
// Listen for all notification events
|
|
254
|
+
NotifySphere.onNotification((notification, type) => {
|
|
255
|
+
console.log('Notification event:', type, notification);
|
|
624
256
|
|
|
625
|
-
|
|
257
|
+
if (type === 'press' || type === 'opened' || type === 'initial') {
|
|
258
|
+
// User tapped the notification — navigate, show modal, etc.
|
|
259
|
+
}
|
|
626
260
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
261
|
+
if (type === 'received') {
|
|
262
|
+
// Notification arrived while the app was in the foreground
|
|
263
|
+
}
|
|
264
|
+
});
|
|
631
265
|
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
692
|
-
|
|
693
|
-
###
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
**
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
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
|
-
|
|
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
|
-
|
|
764
|
-
```bash
|
|
765
|
-
# Android
|
|
766
|
-
adb logcat | grep -i "error\|exception"
|
|
305
|
+
### `NotifySphere.setBackgroundHandler(config?)`
|
|
767
306
|
|
|
768
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
317
|
+
---
|
|
784
318
|
|
|
785
|
-
|
|
786
|
-
- Push notifications **DO NOT work** on iOS Simulator
|
|
787
|
-
- Must test on real device
|
|
319
|
+
### `NotifySphere.onNotification(callback)`
|
|
788
320
|
|
|
789
|
-
|
|
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
|
-
|
|
795
|
-
|
|
796
|
-
//
|
|
797
|
-
|
|
798
|
-
|
|
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
|
-
|
|
803
|
-
|
|
804
|
-
|
|
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
|
-
|
|
807
|
-
|
|
808
|
-
**Symptoms:**
|
|
809
|
-
- Notification displays
|
|
810
|
-
- Callback triggered
|
|
811
|
-
- But `data` object is empty
|
|
337
|
+
---
|
|
812
338
|
|
|
813
|
-
|
|
339
|
+
### `NotifySphere.updateTags(params)`
|
|
814
340
|
|
|
815
|
-
|
|
341
|
+
Updates user tags without re-registering the device. `appId` is optional — falls back to the value passed in `initialize()`.
|
|
816
342
|
|
|
817
|
-
```
|
|
818
|
-
{
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
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
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
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
|
-
|
|
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
|
-
|
|
362
|
+
Unsubscribes all active listeners and resets internal state. Call this on logout or when you no longer need notifications.
|
|
892
363
|
|
|
893
|
-
|
|
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
|
-
|
|
910
|
-
|
|
911
|
-
**Android:**
|
|
368
|
+
---
|
|
912
369
|
|
|
913
|
-
|
|
914
|
-
2. Send notification with sound:
|
|
370
|
+
### `NotifySphere.checkApplicationPermission()`
|
|
915
371
|
|
|
916
|
-
|
|
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
|
-
|
|
374
|
+
---
|
|
925
375
|
|
|
926
|
-
|
|
927
|
-
2. Ensure file is added to target
|
|
928
|
-
3. Send notification with sound in payload
|
|
376
|
+
## FCM Payload Format
|
|
929
377
|
|
|
930
|
-
|
|
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
|
-
"
|
|
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
|
-
|
|
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
|
-
###
|
|
397
|
+
### Supported `data` fields
|
|
945
398
|
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
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
|
-
##
|
|
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
|
-
###
|
|
413
|
+
### API calls returning 401 Unauthorized
|
|
1026
414
|
|
|
1027
|
-
|
|
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
|
-
###
|
|
417
|
+
### Notifications not displaying on Android
|
|
1040
418
|
|
|
1041
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
425
|
+
### `async-storage` build error
|
|
1056
426
|
|
|
1057
|
-
-
|
|
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
|
-
###
|
|
429
|
+
### iOS notifications not working
|
|
1062
430
|
|
|
1063
|
-
|
|
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
|
-
|
|
1069
|
-
cd ios && pod deintegrate && pod install && cd ..
|
|
433
|
+
### Debug logging
|
|
1070
434
|
|
|
1071
|
-
|
|
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
|
-
|
|
1076
|
-
|
|
1077
|
-
npx react-native log-ios
|
|
437
|
+
```ts
|
|
438
|
+
await NotifySphere.initialize({ ..., debug: __DEV__ });
|
|
1078
439
|
```
|
|
1079
440
|
|
|
1080
441
|
---
|
|
1081
442
|
|
|
1082
|
-
##
|
|
443
|
+
## Version History
|
|
1083
444
|
|
|
1084
|
-
|
|
445
|
+
### v1.2.0 (March 2026)
|
|
1085
446
|
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
467
|
+
- Initial release
|
|
1097
468
|
|
|
1098
469
|
---
|
|
1099
470
|
|
|
1100
|
-
**Created:** January 7, 2026
|
|
1101
|
-
**Status:** ✅ Production Ready
|
|
1102
471
|
**Platform Support:** Android ✅ | iOS ✅
|