@teardown/react-native 2.0.29 → 2.0.30
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 +22 -19
- package/docs/adapters/device/basic.mdx +7 -7
- package/docs/adapters/device/device-info.mdx +8 -8
- package/docs/adapters/device/expo.mdx +10 -10
- package/docs/adapters/device/index.mdx +51 -20
- package/docs/adapters/notifications/expo.mdx +64 -30
- package/docs/adapters/notifications/firebase.mdx +61 -27
- package/docs/adapters/notifications/index.mdx +120 -39
- package/docs/adapters/notifications/wix.mdx +61 -27
- package/docs/advanced.mdx +99 -3
- package/docs/api-reference.mdx +177 -12
- package/docs/core-concepts.mdx +31 -13
- package/docs/force-updates.mdx +18 -8
- package/docs/hooks-reference.mdx +9 -6
- package/docs/identity.mdx +46 -6
- package/docs/logging.mdx +5 -4
- package/package.json +5 -5
- package/src/clients/api/api.client.ts +4 -0
- package/src/clients/device/device.client.ts +9 -0
- package/src/clients/events/events.client.ts +102 -0
- package/src/clients/events/index.ts +1 -0
- package/src/clients/force-update/force-update.client.ts +26 -9
- package/src/clients/identity/identity.client.test.ts +1 -0
- package/src/clients/identity/identity.client.ts +265 -41
- package/src/exports/index.ts +1 -0
- package/src/hooks/use-force-update.ts +14 -0
- package/src/teardown.core.ts +42 -3
|
@@ -4,7 +4,7 @@ description: Push notification adapters for token registration and management.
|
|
|
4
4
|
icon: Bell
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
Notification adapters handle push notification token registration and
|
|
7
|
+
Notification adapters handle push notification token registration, permission requests, and notification event handling with your push notification provider.
|
|
8
8
|
|
|
9
9
|
## Available Adapters
|
|
10
10
|
|
|
@@ -16,40 +16,94 @@ Notification adapters handle push notification token registration and management
|
|
|
16
16
|
|
|
17
17
|
## Usage
|
|
18
18
|
|
|
19
|
-
Notification adapters are
|
|
19
|
+
Notification adapters are passed to `TeardownCore` to enable push notification support:
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
|
-
import {
|
|
22
|
+
import { TeardownCore } from '@teardown/react-native';
|
|
23
|
+
import { ExpoNotificationsAdapter } from '@teardown/react-native/expo';
|
|
24
|
+
import { ExpoDeviceAdapter } from '@teardown/react-native/adapters/expo';
|
|
25
|
+
import { MMKVStorageAdapter } from '@teardown/react-native/adapters/mmkv';
|
|
26
|
+
|
|
27
|
+
const teardown = new TeardownCore({
|
|
28
|
+
org_id: 'your-org-id',
|
|
29
|
+
project_id: 'your-project-id',
|
|
30
|
+
api_key: 'your-api-key',
|
|
31
|
+
storageAdapter: new MMKVStorageAdapter(),
|
|
32
|
+
deviceAdapter: new ExpoDeviceAdapter(),
|
|
33
|
+
notificationAdapter: new ExpoNotificationsAdapter(), // Optional
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Access notifications via core
|
|
37
|
+
if (teardown.notifications) {
|
|
38
|
+
const token = await teardown.notifications.getToken();
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Adapter Interface
|
|
43
|
+
|
|
44
|
+
All notification adapters extend the abstract `NotificationAdapter` class:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
abstract class NotificationAdapter {
|
|
48
|
+
/** The notification platform this adapter supports (APNS, FCM, EXPO) */
|
|
49
|
+
abstract get platform(): NotificationPlatformEnum;
|
|
23
50
|
|
|
24
|
-
|
|
51
|
+
/** Get the current push notification token */
|
|
52
|
+
abstract getToken(): Promise<string | null>;
|
|
25
53
|
|
|
26
|
-
|
|
27
|
-
|
|
54
|
+
/** Request push notification permissions from the user */
|
|
55
|
+
abstract requestPermissions(): Promise<PermissionStatus>;
|
|
28
56
|
|
|
29
|
-
|
|
30
|
-
|
|
57
|
+
/** Subscribe to token refresh events */
|
|
58
|
+
abstract onTokenRefresh(listener: (token: string) => void): Unsubscribe;
|
|
59
|
+
|
|
60
|
+
/** Subscribe to foreground notification events */
|
|
61
|
+
abstract onNotificationReceived(listener: (notification: PushNotification) => void): Unsubscribe;
|
|
62
|
+
|
|
63
|
+
/** Subscribe to notification opened events (user taps) */
|
|
64
|
+
abstract onNotificationOpened(listener: (notification: PushNotification) => void): Unsubscribe;
|
|
65
|
+
|
|
66
|
+
/** Subscribe to data-only message events (silent/background push) */
|
|
67
|
+
abstract onDataMessage(listener: (message: DataMessage) => void): Unsubscribe;
|
|
68
|
+
}
|
|
31
69
|
```
|
|
32
70
|
|
|
33
|
-
|
|
71
|
+
### PermissionStatus
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
interface PermissionStatus {
|
|
75
|
+
/** Whether notifications permission is granted */
|
|
76
|
+
granted: boolean;
|
|
77
|
+
/** Whether the user can be prompted again (iOS specific) */
|
|
78
|
+
canAskAgain: boolean;
|
|
79
|
+
}
|
|
80
|
+
```
|
|
34
81
|
|
|
35
|
-
|
|
82
|
+
### PushNotification
|
|
36
83
|
|
|
37
84
|
```typescript
|
|
38
|
-
interface
|
|
39
|
-
|
|
40
|
-
|
|
85
|
+
interface PushNotification {
|
|
86
|
+
title?: string;
|
|
87
|
+
body?: string;
|
|
88
|
+
data?: Record<string, unknown>;
|
|
89
|
+
}
|
|
90
|
+
```
|
|
41
91
|
|
|
42
|
-
|
|
43
|
-
requestPermissions(): Promise<boolean>;
|
|
92
|
+
### DataMessage
|
|
44
93
|
|
|
45
|
-
|
|
46
|
-
|
|
94
|
+
```typescript
|
|
95
|
+
interface DataMessage {
|
|
96
|
+
data: Record<string, unknown>;
|
|
97
|
+
}
|
|
98
|
+
```
|
|
47
99
|
|
|
48
|
-
|
|
49
|
-
onNotification(handler: (notification: Notification) => void): () => void;
|
|
100
|
+
### NotificationPlatformEnum
|
|
50
101
|
|
|
51
|
-
|
|
52
|
-
|
|
102
|
+
```typescript
|
|
103
|
+
enum NotificationPlatformEnum {
|
|
104
|
+
APNS = "APNS", // Apple Push Notification Service
|
|
105
|
+
FCM = "FCM", // Firebase Cloud Messaging
|
|
106
|
+
EXPO = "EXPO", // Expo Push Notifications
|
|
53
107
|
}
|
|
54
108
|
```
|
|
55
109
|
|
|
@@ -64,37 +118,64 @@ interface NotificationsAdapter {
|
|
|
64
118
|
|
|
65
119
|
## Custom Adapter
|
|
66
120
|
|
|
67
|
-
|
|
121
|
+
Extend the `NotificationAdapter` abstract class:
|
|
68
122
|
|
|
69
123
|
```typescript
|
|
70
|
-
import
|
|
124
|
+
import {
|
|
125
|
+
NotificationAdapter,
|
|
126
|
+
NotificationPlatformEnum,
|
|
127
|
+
type PermissionStatus,
|
|
128
|
+
type PushNotification,
|
|
129
|
+
type DataMessage,
|
|
130
|
+
type Unsubscribe,
|
|
131
|
+
} from '@teardown/react-native';
|
|
132
|
+
|
|
133
|
+
class CustomNotificationsAdapter extends NotificationAdapter {
|
|
134
|
+
get platform(): NotificationPlatformEnum {
|
|
135
|
+
return NotificationPlatformEnum.FCM;
|
|
136
|
+
}
|
|
71
137
|
|
|
72
|
-
class CustomNotificationsAdapter implements NotificationsAdapter {
|
|
73
138
|
async getToken(): Promise<string | null> {
|
|
74
|
-
// Return push token from your notification library
|
|
75
139
|
return await myNotificationLib.getToken();
|
|
76
140
|
}
|
|
77
141
|
|
|
78
|
-
async requestPermissions(): Promise<
|
|
79
|
-
|
|
80
|
-
return
|
|
142
|
+
async requestPermissions(): Promise<PermissionStatus> {
|
|
143
|
+
const granted = await myNotificationLib.requestPermission();
|
|
144
|
+
return { granted, canAskAgain: !granted };
|
|
81
145
|
}
|
|
82
146
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return
|
|
147
|
+
onTokenRefresh(listener: (token: string) => void): Unsubscribe {
|
|
148
|
+
const subscription = myNotificationLib.onTokenRefresh(listener);
|
|
149
|
+
return () => subscription.remove();
|
|
86
150
|
}
|
|
87
151
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
152
|
+
onNotificationReceived(listener: (notification: PushNotification) => void): Unsubscribe {
|
|
153
|
+
const subscription = myNotificationLib.onMessage((msg) => {
|
|
154
|
+
listener({
|
|
155
|
+
title: msg.notification?.title,
|
|
156
|
+
body: msg.notification?.body,
|
|
157
|
+
data: msg.data,
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
return () => subscription();
|
|
92
161
|
}
|
|
93
162
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
163
|
+
onNotificationOpened(listener: (notification: PushNotification) => void): Unsubscribe {
|
|
164
|
+
const subscription = myNotificationLib.onNotificationOpened((msg) => {
|
|
165
|
+
listener({
|
|
166
|
+
title: msg.notification?.title,
|
|
167
|
+
body: msg.notification?.body,
|
|
168
|
+
data: msg.data,
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
return () => subscription();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
onDataMessage(listener: (message: DataMessage) => void): Unsubscribe {
|
|
175
|
+
const subscription = myNotificationLib.onDataMessage((msg) => {
|
|
176
|
+
listener({ data: msg.data ?? {} });
|
|
177
|
+
});
|
|
178
|
+
return () => subscription();
|
|
98
179
|
}
|
|
99
180
|
}
|
|
100
181
|
```
|
|
@@ -21,74 +21,104 @@ cd ios && pod install
|
|
|
21
21
|
## Usage
|
|
22
22
|
|
|
23
23
|
```typescript
|
|
24
|
-
import {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const
|
|
24
|
+
import { TeardownCore } from '@teardown/react-native';
|
|
25
|
+
import { WixNotificationsAdapter } from '@teardown/react-native/wix';
|
|
26
|
+
import { DeviceInfoAdapter } from '@teardown/react-native/adapters/device-info';
|
|
27
|
+
import { AsyncStorageAdapter } from '@teardown/react-native/adapters/async-storage';
|
|
28
|
+
|
|
29
|
+
const teardown = new TeardownCore({
|
|
30
|
+
org_id: 'your-org-id',
|
|
31
|
+
project_id: 'your-project-id',
|
|
32
|
+
api_key: 'your-api-key',
|
|
33
|
+
storageAdapter: new AsyncStorageAdapter(),
|
|
34
|
+
deviceAdapter: new DeviceInfoAdapter(),
|
|
35
|
+
notificationAdapter: new WixNotificationsAdapter(),
|
|
36
|
+
});
|
|
30
37
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
38
|
+
// Access via NotificationsClient
|
|
39
|
+
if (teardown.notifications) {
|
|
40
|
+
const status = await teardown.notifications.requestPermissions();
|
|
41
|
+
if (status.granted) {
|
|
42
|
+
const token = await teardown.notifications.getToken();
|
|
43
|
+
console.log('Push token:', token);
|
|
44
|
+
}
|
|
35
45
|
}
|
|
36
46
|
```
|
|
37
47
|
|
|
38
48
|
## Import Path
|
|
39
49
|
|
|
40
50
|
```typescript
|
|
41
|
-
import { WixNotificationsAdapter } from '@teardown/react-native/wix
|
|
51
|
+
import { WixNotificationsAdapter } from '@teardown/react-native/wix';
|
|
42
52
|
```
|
|
43
53
|
|
|
44
54
|
## API
|
|
45
55
|
|
|
56
|
+
All methods are accessed via `NotificationsClient`, not directly on the adapter.
|
|
57
|
+
|
|
58
|
+
### requestPermissions()
|
|
59
|
+
|
|
60
|
+
Request notification permissions:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
const status = await teardown.notifications.requestPermissions();
|
|
64
|
+
// Returns: { granted: boolean, canAskAgain: boolean }
|
|
65
|
+
```
|
|
66
|
+
|
|
46
67
|
### getToken()
|
|
47
68
|
|
|
48
69
|
Get the device push token:
|
|
49
70
|
|
|
50
71
|
```typescript
|
|
51
|
-
const token = await notifications.getToken();
|
|
72
|
+
const token = await teardown.notifications.getToken();
|
|
52
73
|
// Returns: device token string or null
|
|
53
74
|
```
|
|
54
75
|
|
|
55
|
-
###
|
|
76
|
+
### onNotificationReceived()
|
|
56
77
|
|
|
57
|
-
|
|
78
|
+
Subscribe to foreground notifications:
|
|
58
79
|
|
|
59
80
|
```typescript
|
|
60
|
-
const
|
|
61
|
-
|
|
81
|
+
const unsubscribe = teardown.notifications.onNotificationReceived((notification) => {
|
|
82
|
+
console.log('Received:', notification.title);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Cleanup
|
|
86
|
+
unsubscribe();
|
|
62
87
|
```
|
|
63
88
|
|
|
64
|
-
###
|
|
89
|
+
### onNotificationOpened()
|
|
65
90
|
|
|
66
|
-
|
|
91
|
+
Subscribe to notification taps:
|
|
67
92
|
|
|
68
93
|
```typescript
|
|
69
|
-
const
|
|
94
|
+
const unsubscribe = teardown.notifications.onNotificationOpened((notification) => {
|
|
95
|
+
console.log('User tapped:', notification.title);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Cleanup
|
|
99
|
+
unsubscribe();
|
|
70
100
|
```
|
|
71
101
|
|
|
72
|
-
###
|
|
102
|
+
### onTokenRefresh()
|
|
73
103
|
|
|
74
|
-
Subscribe to
|
|
104
|
+
Subscribe to token changes:
|
|
75
105
|
|
|
76
106
|
```typescript
|
|
77
|
-
const unsubscribe = notifications.
|
|
78
|
-
console.log('
|
|
107
|
+
const unsubscribe = teardown.notifications.onTokenChange((token) => {
|
|
108
|
+
console.log('New token:', token);
|
|
79
109
|
});
|
|
80
110
|
|
|
81
111
|
// Cleanup
|
|
82
112
|
unsubscribe();
|
|
83
113
|
```
|
|
84
114
|
|
|
85
|
-
###
|
|
115
|
+
### onDataMessage()
|
|
86
116
|
|
|
87
|
-
Subscribe to
|
|
117
|
+
Subscribe to data-only messages (silent push):
|
|
88
118
|
|
|
89
119
|
```typescript
|
|
90
|
-
const unsubscribe = notifications.
|
|
91
|
-
console.log('
|
|
120
|
+
const unsubscribe = teardown.notifications.onDataMessage((message) => {
|
|
121
|
+
console.log('Data message:', message.data);
|
|
92
122
|
});
|
|
93
123
|
|
|
94
124
|
// Cleanup
|
|
@@ -128,6 +158,10 @@ unsubscribe();
|
|
|
128
158
|
import com.wix.reactnativenotifications.RNNotificationsPackage;
|
|
129
159
|
```
|
|
130
160
|
|
|
161
|
+
## Platform
|
|
162
|
+
|
|
163
|
+
Returns `NotificationPlatformEnum.APNS` on iOS, `NotificationPlatformEnum.FCM` on Android.
|
|
164
|
+
|
|
131
165
|
## When to Use
|
|
132
166
|
|
|
133
167
|
- Existing projects using react-native-notifications
|
package/docs/advanced.mdx
CHANGED
|
@@ -31,6 +31,86 @@ export const teardown = new TeardownCore({
|
|
|
31
31
|
});
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
## Push Notifications Setup
|
|
35
|
+
|
|
36
|
+
Enable push notifications by providing a notification adapter:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { TeardownCore } from '@teardown/react-native';
|
|
40
|
+
import { ExpoNotificationsAdapter, ExpoDeviceAdapter } from '@teardown/react-native/expo';
|
|
41
|
+
import { MMKVStorageAdapter } from '@teardown/react-native/adapters/mmkv';
|
|
42
|
+
|
|
43
|
+
const teardown = new TeardownCore({
|
|
44
|
+
org_id: 'your-org-id',
|
|
45
|
+
project_id: 'your-project-id',
|
|
46
|
+
api_key: 'your-api-key',
|
|
47
|
+
storageAdapter: new MMKVStorageAdapter(),
|
|
48
|
+
deviceAdapter: new ExpoDeviceAdapter(),
|
|
49
|
+
notificationAdapter: new ExpoNotificationsAdapter(), // Enable notifications
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Request permissions and get token
|
|
53
|
+
if (teardown.notifications) {
|
|
54
|
+
const status = await teardown.notifications.requestPermissions();
|
|
55
|
+
if (status.granted) {
|
|
56
|
+
const token = await teardown.notifications.getToken();
|
|
57
|
+
// Token is automatically sent with identify() calls
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Handle Notifications
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
const { core } = useTeardown();
|
|
66
|
+
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
if (!core.notifications) return;
|
|
69
|
+
|
|
70
|
+
const unsubs = [
|
|
71
|
+
core.notifications.onNotificationReceived((notification) => {
|
|
72
|
+
// Foreground notification
|
|
73
|
+
console.log('Notification:', notification.title);
|
|
74
|
+
}),
|
|
75
|
+
core.notifications.onNotificationOpened((notification) => {
|
|
76
|
+
// User tapped notification
|
|
77
|
+
navigateToScreen(notification.data?.screen);
|
|
78
|
+
}),
|
|
79
|
+
core.notifications.onDataMessage((message) => {
|
|
80
|
+
// Silent/data message
|
|
81
|
+
syncData(message.data);
|
|
82
|
+
}),
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
return () => unsubs.forEach(unsub => unsub());
|
|
86
|
+
}, [core.notifications]);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Event Tracking
|
|
90
|
+
|
|
91
|
+
Track custom events:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
const { core } = useTeardown();
|
|
95
|
+
|
|
96
|
+
// Track single event
|
|
97
|
+
await core.events.track({
|
|
98
|
+
event_name: 'purchase_completed',
|
|
99
|
+
event_type: 'action',
|
|
100
|
+
properties: {
|
|
101
|
+
product_id: 'abc123',
|
|
102
|
+
amount: 99.99,
|
|
103
|
+
currency: 'USD',
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Track multiple events
|
|
108
|
+
await core.events.trackBatch([
|
|
109
|
+
{ event_name: 'cart_viewed', event_type: 'screen_view' },
|
|
110
|
+
{ event_name: 'item_added', properties: { item_id: 'xyz' } },
|
|
111
|
+
]);
|
|
112
|
+
```
|
|
113
|
+
|
|
34
114
|
## Disable Force Update Checking
|
|
35
115
|
|
|
36
116
|
For debugging or testing:
|
|
@@ -133,12 +213,24 @@ export const useTeardown = () => ({
|
|
|
133
213
|
core: {
|
|
134
214
|
identity: {
|
|
135
215
|
identify: jest.fn().mockResolvedValue({ success: true, data: mockSession }),
|
|
136
|
-
|
|
216
|
+
signOut: jest.fn().mockResolvedValue({ success: true, data: undefined }),
|
|
217
|
+
signOutAll: jest.fn().mockResolvedValue({ success: true, data: undefined }),
|
|
137
218
|
getSessionState: () => mockSession,
|
|
138
219
|
},
|
|
139
220
|
forceUpdate: {
|
|
140
221
|
getVersionStatus: () => ({ type: 'up_to_date' }),
|
|
141
222
|
},
|
|
223
|
+
events: {
|
|
224
|
+
track: jest.fn().mockResolvedValue({ success: true, data: undefined }),
|
|
225
|
+
trackBatch: jest.fn().mockResolvedValue({ success: true, data: undefined }),
|
|
226
|
+
},
|
|
227
|
+
notifications: {
|
|
228
|
+
requestPermissions: jest.fn().mockResolvedValue({ granted: true, canAskAgain: true }),
|
|
229
|
+
getToken: jest.fn().mockResolvedValue('mock-push-token'),
|
|
230
|
+
onNotificationReceived: jest.fn().mockReturnValue(() => {}),
|
|
231
|
+
onNotificationOpened: jest.fn().mockReturnValue(() => {}),
|
|
232
|
+
onDataMessage: jest.fn().mockReturnValue(() => {}),
|
|
233
|
+
},
|
|
142
234
|
},
|
|
143
235
|
});
|
|
144
236
|
|
|
@@ -148,6 +240,7 @@ export const useForceUpdate = () => ({
|
|
|
148
240
|
isUpdateRequired: false,
|
|
149
241
|
isUpdateRecommended: false,
|
|
150
242
|
isUpdateAvailable: false,
|
|
243
|
+
releaseNotes: null,
|
|
151
244
|
});
|
|
152
245
|
```
|
|
153
246
|
|
|
@@ -187,8 +280,11 @@ console.log('Device ID:', await core.device.getDeviceId());
|
|
|
187
280
|
For debugging or logout:
|
|
188
281
|
|
|
189
282
|
```typescript
|
|
190
|
-
|
|
191
|
-
|
|
283
|
+
// Sign out - clears session, keeps device ID
|
|
284
|
+
await core.identity.signOut();
|
|
285
|
+
|
|
286
|
+
// Full reset - clears session AND device ID (fresh install state)
|
|
287
|
+
await core.identity.signOutAll();
|
|
192
288
|
```
|
|
193
289
|
|
|
194
290
|
## Performance
|