@janiscommerce/app-push-notification 0.0.1-beta.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -3
- package/README.md +81 -41
- package/lib/NotificationContext.js +20 -6
- package/lib/NotificationProvider/index.js +81 -65
- package/lib/index.js +3 -3
- package/lib/usePushNotification.js +200 -0
- package/lib/utils/api/SubscribeNotifications/index.js +18 -14
- package/lib/utils/api/UnSubscribeNotifications/index.js +35 -0
- package/lib/utils/index.js +19 -222
- package/package.json +10 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
[Unreleased]
|
|
3
|
+
## [Unreleased]
|
|
4
|
+
|
|
5
|
+
## [0.0.3] - 2024-06-13
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- additional info to send in subscription
|
|
10
|
+
|
|
11
|
+
## [0.0.2] - 2024-05-03
|
|
4
12
|
|
|
5
13
|
### Added
|
|
6
14
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
15
|
+
- NotificationProvider (HOC) to receive notifications at background and foreground
|
|
16
|
+
- Github actions to deploy to npm
|
|
17
|
+
- Callback to handle notification
|
package/README.md
CHANGED
|
@@ -29,12 +29,18 @@ Inside remoteMessage you get the notifications object that contains the informat
|
|
|
29
29
|
|
|
30
30
|
For more information about this, read https://rnfirebase.io/reference/messaging/remotemessage
|
|
31
31
|
|
|
32
|
-
This library provides the following components and methods:
|
|
32
|
+
# This library provides the following components and methods:
|
|
33
33
|
|
|
34
34
|
## Functions
|
|
35
35
|
|
|
36
36
|
<dl>
|
|
37
|
-
<dt><a href="#
|
|
37
|
+
<dt><a href="#NotificationProvider">NotificationProvider(children, appName, events, environment, additionalInfo)</a> ⇒ <code>null</code> | <code>React.element</code></dt>
|
|
38
|
+
<dd><p>It is the main component of the package, it is a HOC that is responsible for handling the logic of subscribing to notifications and receiving messages from the Firebase console. The HOC contains listeners to listen to notifications in the foreground and background, so (unless we cancel the subscription), we will receive notifications from the app even when it is closed.</p>
|
|
39
|
+
</dd>
|
|
40
|
+
<dt><a href="#setupBackgroundMessageHandler">setupBackgroundMessageHandler(callback)</a></dt>
|
|
41
|
+
<dd><p>This function is responsible for handling any callbacks from Firebase cloud messaging in the background or with the application closed</p>
|
|
42
|
+
</dd>
|
|
43
|
+
<dt><a href="#usePushNotification">usePushNotification()</a> ⇒ <code>object</code></dt>
|
|
38
44
|
<dd><p>is a hook, which returns the elements contained within the notifications context. Returns an object containing:</p>
|
|
39
45
|
<table>
|
|
40
46
|
<thead>
|
|
@@ -45,33 +51,47 @@ This library provides the following components and methods:
|
|
|
45
51
|
</thead>
|
|
46
52
|
<tbody><tr>
|
|
47
53
|
<td>deviceToken</td>
|
|
48
|
-
<td>
|
|
54
|
+
<td>Is the token linked to the device, which we use to subscribe it to notifications.</td>
|
|
55
|
+
</tr>
|
|
56
|
+
<tr>
|
|
57
|
+
<td>foregroundNotification</td>
|
|
58
|
+
<td>An object containing all data received when a foreground push notification is triggered.</td>
|
|
59
|
+
</tr>
|
|
60
|
+
<tr>
|
|
61
|
+
<td>backgroundNotification</td>
|
|
62
|
+
<td>An object containing all data received when a background push notification is triggered.</td>
|
|
63
|
+
</tr>
|
|
64
|
+
<tr>
|
|
65
|
+
<td>subscribeError</td>
|
|
66
|
+
<td>An object containing all data received from a notification service subscription failure.</td>
|
|
67
|
+
</tr>
|
|
68
|
+
<tr>
|
|
69
|
+
<td>cancelNotifications</td>
|
|
70
|
+
<td>This util is responsible for making the request to unsubscribe from all notification events. If no arguments are received, the request will be made with the previously registered events.</td>
|
|
71
|
+
</tr>
|
|
72
|
+
<tr>
|
|
73
|
+
<td>updateSuscription</td>
|
|
74
|
+
<td>This function is responsible for updating the subscription to the notification service</td>
|
|
75
|
+
</tr>
|
|
76
|
+
<tr>
|
|
77
|
+
<td>addNewEvent</td>
|
|
78
|
+
<td>This function allows you to add a new event to receive notifications.</td>
|
|
79
|
+
</tr>
|
|
80
|
+
<tr>
|
|
81
|
+
<td>deleteReceivedNotification</td>
|
|
82
|
+
<td>An util that clears the foreground or background notification state to the depending on the type it receives by parameter</td>
|
|
83
|
+
</tr>
|
|
84
|
+
<tr>
|
|
85
|
+
<td>getSubscribedEvents</td>
|
|
86
|
+
<td>This function returns an array with the events to which the user is subscribed.</td>
|
|
49
87
|
</tr>
|
|
50
88
|
</tbody></table>
|
|
51
89
|
</dd>
|
|
52
|
-
<dt><a href="#NotificationProvider">NotificationProvider(children, foregroundCallback, backgroundCallback, config, events, environment)</a> ⇒ <code>null</code> | <code>React.element</code></dt>
|
|
53
|
-
<dd><p>It is the main component of the package, it is a HOC that is responsible for handling the logic of subscribing to notifications and receiving messages from the Firebase console. The HOC contains listeners to listen to notifications in the foreground and background, so (unless we cancel the subscription), we will receive notifications from the app even when it is closed.</p>
|
|
54
|
-
</dd>
|
|
55
90
|
</dl>
|
|
56
91
|
|
|
57
|
-
<a name="useNotification"></a>
|
|
58
|
-
|
|
59
|
-
## useNotification() ⇒ <code>object</code>
|
|
60
|
-
is a hook, which returns the elements contained within the notifications context. Returns an object containing:
|
|
61
|
-
| name | description |
|
|
62
|
-
|----------|----------|
|
|
63
|
-
| deviceToken | is the token linked to the device, which we use to subscribe it to notifications. |
|
|
64
|
-
|
|
65
|
-
**Kind**: global function
|
|
66
|
-
**Example**
|
|
67
|
-
```js
|
|
68
|
-
import {useNotification} from '@janiscommerce/app-push-notification'
|
|
69
|
-
|
|
70
|
-
const {} = useNotification()
|
|
71
|
-
```
|
|
72
92
|
<a name="NotificationProvider"></a>
|
|
73
93
|
|
|
74
|
-
## NotificationProvider(children,
|
|
94
|
+
## NotificationProvider(children, appName, events, environment, additionalInfo) ⇒ <code>null</code> \| <code>React.element</code>
|
|
75
95
|
It is the main component of the package, it is a HOC that is responsible for handling the logic of subscribing to notifications and receiving messages from the Firebase console. The HOC contains listeners to listen to notifications in the foreground and background, so (unless we cancel the subscription), we will receive notifications from the app even when it is closed.
|
|
76
96
|
|
|
77
97
|
**Kind**: global function
|
|
@@ -83,36 +103,56 @@ It is the main component of the package, it is a HOC that is responsible for han
|
|
|
83
103
|
| Param | Type | Description |
|
|
84
104
|
| --- | --- | --- |
|
|
85
105
|
| children | <code>React.element</code> | Component that will be rendered within the HOC, and about which the notification will be displayed |
|
|
86
|
-
|
|
|
87
|
-
| backgroundCallback | <code>function</code> | function that will be executed when a background notification is received. |
|
|
88
|
-
| config | <code>object</code> | It is an object that contains the user's data, which will be used to subscribe the user to notifications. |
|
|
89
|
-
| config.appName | <code>string</code> | name of the aplication |
|
|
90
|
-
| config.accessToken | <code>string</code> | accessToken provided by janis |
|
|
91
|
-
| config.client | <code>string</code> | client provided by janis |
|
|
106
|
+
| appName | <code>string</code> | name of the aplication |
|
|
92
107
|
| events | <code>Array.<string></code> | is an array that will contain the events to which the user wants to subscribe |
|
|
93
108
|
| environment | <code>string</code> | The environment is necessary for the API that we are going to use to subscribe the device to notifications. |
|
|
109
|
+
| additionalInfo | <code>object</code> | fields to be sent as part of the body of the subscription request |
|
|
94
110
|
|
|
95
111
|
**Example**
|
|
96
112
|
```js
|
|
97
113
|
import NotificationProvider from '@janiscommerce/app-push-notification'
|
|
98
114
|
|
|
99
|
-
|
|
100
|
-
//...
|
|
101
|
-
|
|
102
|
-
const foregroundCallback = (remoteMessage) => console.log('a new FCM:',remoteMessage)
|
|
103
|
-
const backgrounCallback = (remoteMessage) => {
|
|
104
|
-
console.log('a new FCM was received in background', remoteMessage)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
115
|
return (
|
|
108
|
-
<NotificationProvider
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
config={client:'fizzmod', accessToken:'access_token_push', appName:'janisAppName'}
|
|
112
|
-
events={['Notification','events','janis']}
|
|
116
|
+
<NotificationProvider
|
|
117
|
+
appName='pickingApp'
|
|
118
|
+
events={["picking:session:created","picking:session:assigned"]}
|
|
113
119
|
environment='beta'
|
|
114
120
|
>
|
|
115
121
|
<MyComponent/>
|
|
116
122
|
</NotificationProvider>
|
|
117
123
|
)
|
|
118
124
|
```
|
|
125
|
+
<a name="setupBackgroundMessageHandler"></a>
|
|
126
|
+
|
|
127
|
+
## setupBackgroundMessageHandler(callback)
|
|
128
|
+
This function is responsible for handling any callbacks from Firebase cloud messaging in the background or with the application closed
|
|
129
|
+
|
|
130
|
+
**Kind**: global function
|
|
131
|
+
|
|
132
|
+
| Param | Type | Description |
|
|
133
|
+
| --- | --- | --- |
|
|
134
|
+
| callback | <code>function</code> | is the function that will receive the payload and render it as appropriate |
|
|
135
|
+
|
|
136
|
+
<a name="usePushNotification"></a>
|
|
137
|
+
|
|
138
|
+
## usePushNotification() ⇒ <code>object</code>
|
|
139
|
+
is a hook, which returns the elements contained within the notifications context. Returns an object containing:
|
|
140
|
+
| name | description |
|
|
141
|
+
|----------|----------|
|
|
142
|
+
| deviceToken | Is the token linked to the device, which we use to subscribe it to notifications. |
|
|
143
|
+
| foregroundNotification | An object containing all data received when a foreground push notification is triggered. |
|
|
144
|
+
| backgroundNotification | An object containing all data received when a background push notification is triggered. |
|
|
145
|
+
| subscribeError | An object containing all data received from a notification service subscription failure. |
|
|
146
|
+
| cancelNotifications | This util is responsible for making the request to unsubscribe from all notification events. If no arguments are received, the request will be made with the previously registered events. |
|
|
147
|
+
| updateSuscription | This function is responsible for updating the subscription to the notification service |
|
|
148
|
+
| addNewEvent | This function allows you to add a new event to receive notifications. |
|
|
149
|
+
| deleteReceivedNotification | An util that clears the foreground or background notification state to the depending on the type it receives by parameter
|
|
150
|
+
| getSubscribedEvents | This function returns an array with the events to which the user is subscribed. |
|
|
151
|
+
|
|
152
|
+
**Kind**: global function
|
|
153
|
+
**Example**
|
|
154
|
+
```js
|
|
155
|
+
import {usePushNotification} from '@janiscommerce/app-push-notification'
|
|
156
|
+
|
|
157
|
+
const { deviceToken, foregroundNotification, backgroundNotification} = usePushNotification()
|
|
158
|
+
```
|
|
@@ -2,17 +2,31 @@ import React from 'react';
|
|
|
2
2
|
|
|
3
3
|
export const NotificationContext = React.createContext(null);
|
|
4
4
|
|
|
5
|
+
/** *
|
|
6
|
+
* @function setupBackgroundMessageHandler
|
|
7
|
+
* @description This function is responsible for handling any callbacks from Firebase cloud messaging in the background or with the application closed
|
|
8
|
+
* @param {Function} callback is the function that will receive the payload and render it as appropriate
|
|
9
|
+
*/
|
|
10
|
+
|
|
5
11
|
/**
|
|
6
|
-
* @function
|
|
12
|
+
* @function usePushNotification
|
|
7
13
|
* @description is a hook, which returns the elements contained within the notifications context. Returns an object containing:
|
|
8
14
|
* | name | description |
|
|
9
15
|
* |----------|----------|
|
|
10
|
-
* | deviceToken
|
|
16
|
+
* | deviceToken | Is the token linked to the device, which we use to subscribe it to notifications. |
|
|
17
|
+
* | foregroundNotification | An object containing all data received when a foreground push notification is triggered. |
|
|
18
|
+
* | backgroundNotification | An object containing all data received when a background push notification is triggered. |
|
|
19
|
+
* | subscribeError | An object containing all data received from a notification service subscription failure. |
|
|
20
|
+
* | cancelNotifications | This util is responsible for making the request to unsubscribe from all notification events. If no arguments are received, the request will be made with the previously registered events. |
|
|
21
|
+
* | updateSuscription | This function is responsible for updating the subscription to the notification service |
|
|
22
|
+
* | addNewEvent | This function allows you to add a new event to receive notifications. |
|
|
23
|
+
* | deleteReceivedNotification | An util that clears the foreground or background notification state to the depending on the type it receives by parameter
|
|
24
|
+
* | getSubscribedEvents | This function returns an array with the events to which the user is subscribed. |
|
|
11
25
|
* @returns {object}
|
|
12
26
|
* @example
|
|
13
|
-
* import {
|
|
14
|
-
*
|
|
15
|
-
* const {} =
|
|
27
|
+
* import {usePushNotification} from '@janiscommerce/app-push-notification'
|
|
28
|
+
*
|
|
29
|
+
* const { deviceToken, foregroundNotification, backgroundNotification} = usePushNotification()
|
|
16
30
|
*/
|
|
17
31
|
|
|
18
|
-
export const
|
|
32
|
+
export const usePushNotification = () => React.useContext(NotificationContext);
|
|
@@ -1,49 +1,33 @@
|
|
|
1
|
-
import React, {useEffect,
|
|
1
|
+
import React, {useEffect, useRef} from 'react';
|
|
2
|
+
import messaging from '@react-native-firebase/messaging';
|
|
2
3
|
import {NotificationContext} from '../NotificationContext';
|
|
3
4
|
import {
|
|
4
|
-
getFCMToken,
|
|
5
|
-
setupBackgroundMessageHandler,
|
|
6
|
-
setupForegroundMessageHandler,
|
|
7
|
-
DefaultAlert,
|
|
8
|
-
isFunction,
|
|
9
5
|
isString,
|
|
10
|
-
isObject,
|
|
11
6
|
isArray,
|
|
12
|
-
|
|
7
|
+
setupForegroundMessageHandler,
|
|
8
|
+
setupNotificationOpenedHandler,
|
|
9
|
+
isObject,
|
|
13
10
|
} from '../utils';
|
|
11
|
+
import usePushNotification from '../usePushNotification';
|
|
14
12
|
|
|
15
13
|
/**
|
|
16
14
|
* @function NotificationProvider
|
|
17
|
-
* @description It is the main component of the package, it is a HOC that is responsible for handling the logic of subscribing to notifications and receiving messages from the Firebase console. The HOC contains listeners to listen to notifications in the foreground and background, so (unless we cancel the subscription), we will receive notifications from the app even when it is closed.
|
|
15
|
+
* @description It is the main component of the package, it is a HOC that is responsible for handling the logic of subscribing to notifications and receiving messages from the Firebase console. The HOC contains listeners to listen to notifications in the foreground and background, so (unless we cancel the subscription), we will receive notifications from the app even when it is closed.
|
|
18
16
|
* @param {React.element} children Component that will be rendered within the HOC, and about which the notification will be displayed
|
|
19
|
-
* @param {
|
|
20
|
-
* @param {function} backgroundCallback function that will be executed when a background notification is received.
|
|
21
|
-
* @param {object} config It is an object that contains the user's data, which will be used to subscribe the user to notifications.
|
|
22
|
-
* @param {string} config.appName name of the aplication
|
|
23
|
-
* @param {string} config.accessToken accessToken provided by janis
|
|
24
|
-
* @param {string} config.client client provided by janis
|
|
17
|
+
* @param {string} appName name of the aplication
|
|
25
18
|
* @param {Array<string>} events is an array that will contain the events to which the user wants to subscribe
|
|
26
19
|
* @param {string} environment The environment is necessary for the API that we are going to use to subscribe the device to notifications.
|
|
20
|
+
* @param {object} additionalInfo fields to be sent as part of the body of the subscription request
|
|
27
21
|
* @throws null when not receive a children argument
|
|
28
22
|
* @returns {null | React.element}
|
|
29
23
|
* @example
|
|
30
|
-
*
|
|
24
|
+
*
|
|
31
25
|
* import NotificationProvider from '@janiscommerce/app-push-notification'
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* //...
|
|
35
|
-
*
|
|
36
|
-
* const foregroundCallback = (remoteMessage) => console.log('a new FCM:',remoteMessage)
|
|
37
|
-
* const backgrounCallback = (remoteMessage) => {
|
|
38
|
-
* console.log('a new FCM was received in background', remoteMessage)
|
|
39
|
-
* }
|
|
40
|
-
*
|
|
26
|
+
*
|
|
41
27
|
* return (
|
|
42
|
-
* <NotificationProvider
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* config={client:'fizzmod', accessToken:'access_token_push', appName:'janisAppName'}
|
|
46
|
-
* events={['Notification','events','janis']}
|
|
28
|
+
* <NotificationProvider
|
|
29
|
+
* appName='pickingApp'
|
|
30
|
+
* events={["picking:session:created","picking:session:assigned"]}
|
|
47
31
|
* environment='beta'
|
|
48
32
|
* >
|
|
49
33
|
* <MyComponent/>
|
|
@@ -53,61 +37,93 @@ import {
|
|
|
53
37
|
|
|
54
38
|
const NotificationProvider = ({
|
|
55
39
|
children,
|
|
56
|
-
|
|
57
|
-
backgroundCallback,
|
|
58
|
-
config,
|
|
40
|
+
appName,
|
|
59
41
|
events,
|
|
60
42
|
environment,
|
|
43
|
+
additionalInfo,
|
|
61
44
|
}) => {
|
|
62
45
|
if (!children) return null;
|
|
63
46
|
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
?
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
47
|
+
const validAppName = !!appName && isString(appName) ? appName : '';
|
|
48
|
+
const validEnvironment =
|
|
49
|
+
!!environment && isString(environment) ? environment : '';
|
|
50
|
+
const validEvents = !!events && isArray(events) ? events : [];
|
|
51
|
+
|
|
52
|
+
const isRegistered = useRef(false);
|
|
53
|
+
const {
|
|
54
|
+
registerDeviceToNotifications,
|
|
55
|
+
updateNotificationState,
|
|
56
|
+
pushEvents,
|
|
57
|
+
...rest
|
|
58
|
+
} = usePushNotification(
|
|
59
|
+
validEnvironment,
|
|
60
|
+
validEvents,
|
|
61
|
+
validAppName,
|
|
62
|
+
isRegistered,
|
|
63
|
+
additionalInfo,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// @function handlerForegroundData
|
|
67
|
+
// @description This function is responsible for updating the state corresponding to 'foregroundNotification' with the data it receives as an argument
|
|
68
|
+
|
|
69
|
+
/* istanbul ignore next */
|
|
70
|
+
const handlerForegroundData = (data) => {
|
|
71
|
+
if (!data || !isObject(data)) return null;
|
|
72
|
+
|
|
73
|
+
return updateNotificationState({foregroundNotification: data});
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// @function handlerBackgroundData
|
|
77
|
+
// @description This function is responsible for updating the state corresponding to 'backgroundNotification' with the data it receives as an argument
|
|
78
|
+
|
|
79
|
+
/* istanbul ignore next */
|
|
80
|
+
const handlerBackgroundData = (data) => {
|
|
81
|
+
if (!data || !isObject(data)) return null;
|
|
82
|
+
|
|
83
|
+
return updateNotificationState({backgroundNotification: data});
|
|
83
84
|
};
|
|
84
85
|
|
|
85
|
-
//
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
// @function handleAppOpeningByNotification
|
|
87
|
+
// @description This function is responsible for saving the information of the notification that forced the opening of the app in the 'backgroundNotification' state
|
|
88
|
+
|
|
89
|
+
/* istanbul ignore next */
|
|
90
|
+
const handleAppOpeningByNotification = async () => {
|
|
91
|
+
const data = await messaging().getInitialNotification();
|
|
92
|
+
|
|
93
|
+
if (!data || !isObject(data)) return null;
|
|
88
94
|
|
|
89
|
-
|
|
90
|
-
// eslint-disable-next-line
|
|
91
|
-
validEvents.forEach(async (event) => {
|
|
92
|
-
if (!event || !isString(event)) return null;
|
|
93
|
-
await topicsSubscription(event);
|
|
94
|
-
});
|
|
95
|
+
return updateNotificationState({backgroundNotification: data});
|
|
95
96
|
};
|
|
96
97
|
|
|
97
98
|
useEffect(() => {
|
|
98
|
-
|
|
99
|
+
const alreadySuscribed = isRegistered.current;
|
|
100
|
+
if (environment && appName && !!pushEvents.length && !alreadySuscribed) {
|
|
101
|
+
registerDeviceToNotifications();
|
|
102
|
+
}
|
|
103
|
+
}, [pushEvents]);
|
|
104
|
+
|
|
105
|
+
/* istanbul ignore next */
|
|
106
|
+
useEffect(() => {
|
|
99
107
|
const foregroundMessageHandler = setupForegroundMessageHandler(
|
|
100
|
-
|
|
108
|
+
handlerForegroundData,
|
|
109
|
+
);
|
|
110
|
+
const backgroundMessageHandler = setupNotificationOpenedHandler(
|
|
111
|
+
handlerBackgroundData,
|
|
101
112
|
);
|
|
113
|
+
handleAppOpeningByNotification();
|
|
102
114
|
|
|
103
115
|
return () => {
|
|
104
116
|
foregroundMessageHandler();
|
|
105
|
-
|
|
117
|
+
backgroundMessageHandler();
|
|
106
118
|
};
|
|
107
119
|
}, []);
|
|
108
120
|
|
|
121
|
+
const contextValues = {
|
|
122
|
+
...rest,
|
|
123
|
+
};
|
|
124
|
+
|
|
109
125
|
return (
|
|
110
|
-
<NotificationContext.Provider value={
|
|
126
|
+
<NotificationContext.Provider value={contextValues}>
|
|
111
127
|
{children}
|
|
112
128
|
</NotificationContext.Provider>
|
|
113
129
|
);
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import NotificationProvider from './NotificationProvider';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import {usePushNotification} from './NotificationContext';
|
|
3
|
+
import {setupBackgroundMessageHandler} from './utils';
|
|
4
4
|
|
|
5
|
-
export {
|
|
5
|
+
export {usePushNotification, setupBackgroundMessageHandler};
|
|
6
6
|
export default NotificationProvider;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import {useCallback, useState} from 'react';
|
|
2
|
+
import RequestInstance from '@janiscommerce/app-request';
|
|
3
|
+
import {getFCMToken, isArray, isString} from './utils';
|
|
4
|
+
import SubscribeNotifications from './utils/api/SubscribeNotifications';
|
|
5
|
+
import UnSubscribeNotifications from './utils/api/UnSubscribeNotifications';
|
|
6
|
+
|
|
7
|
+
const usePushNotification = (
|
|
8
|
+
environment,
|
|
9
|
+
events,
|
|
10
|
+
appName,
|
|
11
|
+
isRegistered,
|
|
12
|
+
additionalInfo,
|
|
13
|
+
) => {
|
|
14
|
+
const [notificationState, setNotificationState] = useState({
|
|
15
|
+
deviceToken: null,
|
|
16
|
+
foregroundNotification: {},
|
|
17
|
+
backgroundNotification: {},
|
|
18
|
+
pushEvents: events,
|
|
19
|
+
subscribeError: {},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const {
|
|
23
|
+
deviceToken,
|
|
24
|
+
foregroundNotification,
|
|
25
|
+
backgroundNotification,
|
|
26
|
+
pushEvents,
|
|
27
|
+
subscribeError,
|
|
28
|
+
} = notificationState;
|
|
29
|
+
|
|
30
|
+
const Request = new RequestInstance({JANIS_ENV: environment});
|
|
31
|
+
|
|
32
|
+
const updateNotificationState = (state) =>
|
|
33
|
+
setNotificationState({...notificationState, ...state});
|
|
34
|
+
|
|
35
|
+
const getSubscribedEvents = () => pushEvents;
|
|
36
|
+
|
|
37
|
+
const getDeviceToken = async () => {
|
|
38
|
+
if (deviceToken) return deviceToken;
|
|
39
|
+
|
|
40
|
+
const fcmToken = await getFCMToken();
|
|
41
|
+
if (!fcmToken || !isString(fcmToken)) return null;
|
|
42
|
+
|
|
43
|
+
return fcmToken;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @function registerDeviceToNotifications
|
|
48
|
+
* @description This function is responsible for registering the device to the notification microservice.
|
|
49
|
+
* @returns {null}
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
const registerDeviceToNotifications = useCallback(async () => {
|
|
53
|
+
const token = await getDeviceToken();
|
|
54
|
+
|
|
55
|
+
if (!token) return null;
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
await SubscribeNotifications({
|
|
59
|
+
appName,
|
|
60
|
+
events: pushEvents,
|
|
61
|
+
deviceToken: token,
|
|
62
|
+
request: Request,
|
|
63
|
+
additionalInfo,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
isRegistered.current = true;
|
|
67
|
+
return updateNotificationState({deviceToken: token, pushEvents});
|
|
68
|
+
} catch (error) {
|
|
69
|
+
return updateNotificationState({pushEvents: [], subscribeError: error});
|
|
70
|
+
}
|
|
71
|
+
}, [pushEvents]);
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @function updateSuscription
|
|
75
|
+
* @description This function is responsible for updating the subscription to the notification service
|
|
76
|
+
* @param {object} props all properties that will be sent as additional data in the subscription
|
|
77
|
+
* @returns {Promise}
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
const updateSuscription = async (props = {}) => {
|
|
81
|
+
try {
|
|
82
|
+
const token = await getDeviceToken();
|
|
83
|
+
|
|
84
|
+
const response = await SubscribeNotifications({
|
|
85
|
+
appName,
|
|
86
|
+
events: pushEvents,
|
|
87
|
+
deviceToken: token,
|
|
88
|
+
request: Request,
|
|
89
|
+
additionalInfo: props,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return response;
|
|
93
|
+
} catch (error) {
|
|
94
|
+
return Promise.reject(error);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @function cancelNotifications
|
|
100
|
+
* @description This util is responsible for making the request to unsubscribe from all notification events. If no arguments are received, the request will be made with the previously registered events.
|
|
101
|
+
* @param {Array<string>} events is the list of events to which I want to unsubscribe the device
|
|
102
|
+
* @returns {Promise}
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
*
|
|
106
|
+
* import {usePushNotification} from '@janiscommerce/app-push-notification
|
|
107
|
+
*
|
|
108
|
+
* const {cancelNotifications} = usePushNotification()
|
|
109
|
+
*/
|
|
110
|
+
|
|
111
|
+
const cancelNotifications = async (cancelEvents) => {
|
|
112
|
+
const eventsAreValid = cancelEvents && isArray(cancelEvents);
|
|
113
|
+
const eventsToCancel = eventsAreValid ? cancelEvents : pushEvents;
|
|
114
|
+
try {
|
|
115
|
+
await UnSubscribeNotifications({
|
|
116
|
+
events: eventsToCancel,
|
|
117
|
+
request: Request,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
if (eventsAreValid) {
|
|
121
|
+
const updatedEvents = pushEvents.filter(
|
|
122
|
+
(e) => !eventsToCancel.includes(e),
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
isRegistered.current = true;
|
|
126
|
+
return updateNotificationState({pushEvents: updatedEvents});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
isRegistered.current = false;
|
|
130
|
+
return updateNotificationState({pushEvents: []});
|
|
131
|
+
} catch (unsubscribeError) {
|
|
132
|
+
return Promise.reject(unsubscribeError);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @function deleteReceivedNotification
|
|
138
|
+
* @description This utility allows you to reset the state corresponding to the type of notification received as an argument.
|
|
139
|
+
* @param {string} notificationType the type of notification you want to delete, it can be a foreground or background notification
|
|
140
|
+
* @returns {null}
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* import {usePushNotification} from '@janiscommerce/app-push-notification
|
|
144
|
+
*
|
|
145
|
+
* const {deleteReceivedNotification} = usePushNotification()
|
|
146
|
+
*
|
|
147
|
+
* const resetForegroundNotification = () => {
|
|
148
|
+
* deleteReceivedNotification('foreground')
|
|
149
|
+
* }
|
|
150
|
+
*/
|
|
151
|
+
|
|
152
|
+
const deleteReceivedNotification = (params = {}) => {
|
|
153
|
+
const {type = ''} = params;
|
|
154
|
+
const allowTypes = ['foreground', 'background'];
|
|
155
|
+
const deleteNotification = {
|
|
156
|
+
foreground: () => updateNotificationState({foregroundNotification: {}}),
|
|
157
|
+
background: () => updateNotificationState({backgroundNotification: {}}),
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
if (!type || !allowTypes.includes(type)) return null;
|
|
161
|
+
|
|
162
|
+
const restartNotification = deleteNotification[type];
|
|
163
|
+
|
|
164
|
+
return restartNotification();
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @function addNewEvent
|
|
169
|
+
* @description This function allows you to add a new event to receive notifications
|
|
170
|
+
* @param {string} event
|
|
171
|
+
*/
|
|
172
|
+
|
|
173
|
+
const addNewEvent = (event) => {
|
|
174
|
+
if (!event || !isString(event)) return null;
|
|
175
|
+
if (pushEvents.includes(event)) {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const updatedEvents = [...pushEvents, event];
|
|
180
|
+
isRegistered.current = false;
|
|
181
|
+
return updateNotificationState({pushEvents: updatedEvents});
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
deviceToken,
|
|
186
|
+
foregroundNotification,
|
|
187
|
+
backgroundNotification,
|
|
188
|
+
subscribeError,
|
|
189
|
+
cancelNotifications,
|
|
190
|
+
addNewEvent,
|
|
191
|
+
pushEvents,
|
|
192
|
+
registerDeviceToNotifications,
|
|
193
|
+
updateNotificationState,
|
|
194
|
+
getSubscribedEvents,
|
|
195
|
+
deleteReceivedNotification,
|
|
196
|
+
updateSuscription,
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
export default usePushNotification;
|
|
@@ -1,42 +1,46 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {isString, isArray, validateOauthData, getHeaders} from '../../index';
|
|
1
|
+
import {isString, isArray, isObject} from '../../index';
|
|
3
2
|
|
|
4
3
|
const SubscribeNotifications = async (params = {}) => {
|
|
5
4
|
try {
|
|
6
5
|
if (!params || !Object.keys(params).length)
|
|
7
6
|
throw new Error('params is not a valid object');
|
|
8
7
|
|
|
9
|
-
const {
|
|
10
|
-
params;
|
|
8
|
+
const {deviceToken, events, appName, request, additionalInfo} = params;
|
|
11
9
|
|
|
12
|
-
if (!validateOauthData(accessToken, client))
|
|
13
|
-
throw new Error('accessToken and client are required');
|
|
14
10
|
if (!deviceToken || !isString(deviceToken))
|
|
15
11
|
throw new Error('device token is invalid or null');
|
|
16
12
|
if (!events || !isArray(events))
|
|
17
13
|
throw new Error('events to be subscribed to are null');
|
|
18
14
|
if (!appName || !isString(appName))
|
|
19
15
|
throw new Error('application name are invalid or null');
|
|
20
|
-
if (!
|
|
21
|
-
throw new Error('environment is invalid or null');
|
|
16
|
+
if (!request) throw new Error('Request is not available');
|
|
22
17
|
|
|
23
18
|
const parsedEvents = events.filter((event) => !!event && isString(event));
|
|
24
19
|
if (!parsedEvents.length)
|
|
25
20
|
throw new Error('events to be suscribed are invalids');
|
|
26
21
|
|
|
27
|
-
const
|
|
28
|
-
|
|
22
|
+
const validAdditionalInfo =
|
|
23
|
+
isObject(additionalInfo) && !!Object.keys(additionalInfo).length;
|
|
24
|
+
|
|
29
25
|
const body = {
|
|
30
|
-
deviceToken,
|
|
26
|
+
token: deviceToken,
|
|
31
27
|
events: parsedEvents,
|
|
32
28
|
platformApplicationName: appName,
|
|
29
|
+
...(validAdditionalInfo && {
|
|
30
|
+
additionalInfo,
|
|
31
|
+
}),
|
|
33
32
|
};
|
|
34
33
|
|
|
35
|
-
const
|
|
34
|
+
const response = await request.post({
|
|
35
|
+
service: 'notification',
|
|
36
|
+
namespace: 'subscribe',
|
|
37
|
+
pathParams: ['push'],
|
|
38
|
+
body,
|
|
39
|
+
});
|
|
36
40
|
|
|
37
|
-
return
|
|
41
|
+
return response;
|
|
38
42
|
} catch (error) {
|
|
39
|
-
return Promise.reject(error?.
|
|
43
|
+
return Promise.reject(error?.result || error);
|
|
40
44
|
}
|
|
41
45
|
};
|
|
42
46
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {isString, isArray} from '../../index';
|
|
2
|
+
|
|
3
|
+
const UnSubscribeNotifications = async (params = {}) => {
|
|
4
|
+
try {
|
|
5
|
+
if (!params || !Object.keys(params).length)
|
|
6
|
+
throw new Error('params is not a valid object');
|
|
7
|
+
|
|
8
|
+
const {events, request} = params;
|
|
9
|
+
|
|
10
|
+
if (!events || !isArray(events))
|
|
11
|
+
throw new Error('events to be subscribed to are null');
|
|
12
|
+
if (!request) throw new Error('Request is not available');
|
|
13
|
+
|
|
14
|
+
const parsedEvents = events.filter((event) => !!event && isString(event));
|
|
15
|
+
if (!parsedEvents.length)
|
|
16
|
+
throw new Error('events to be suscribed are invalids');
|
|
17
|
+
|
|
18
|
+
const body = {
|
|
19
|
+
events: parsedEvents,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const response = await request.post({
|
|
23
|
+
service: 'notification',
|
|
24
|
+
namespace: 'unsubscribe',
|
|
25
|
+
pathParams: ['push'],
|
|
26
|
+
body,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
return response;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
return Promise.reject(error?.result || error);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default UnSubscribeNotifications;
|
package/lib/utils/index.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {Alert} from 'react-native';
|
|
2
1
|
import messaging from '@react-native-firebase/messaging';
|
|
3
2
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
4
|
-
import DeviceInfo from 'react-native-device-info';
|
|
5
3
|
|
|
6
4
|
// Helpers
|
|
7
5
|
|
|
@@ -75,180 +73,19 @@ export const isBoolean = (bool) => typeof bool === 'boolean';
|
|
|
75
73
|
export const isArray = (arr) => !!(arr instanceof Array);
|
|
76
74
|
|
|
77
75
|
/**
|
|
78
|
-
* @function
|
|
79
|
-
* @param {
|
|
80
|
-
* @
|
|
81
|
-
* @returns {
|
|
82
|
-
* @example validateOauthData([], 'fizzmodarg') => false
|
|
83
|
-
* @example validateOauthData('34234sdfrdf', 'fizzmodarg') => true
|
|
84
|
-
*/
|
|
85
|
-
export const validateOauthData = (accessToken, client) => {
|
|
86
|
-
if (!accessToken || !client) return false;
|
|
87
|
-
if (!isString(accessToken) || !isString(client)) return false;
|
|
88
|
-
return true;
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
export const formatDeviceDataForUserAgent = (deviceData) => {
|
|
92
|
-
if (!isObject(deviceData) || !Object.keys(deviceData).length) return {};
|
|
93
|
-
|
|
94
|
-
const keysToCheck = [
|
|
95
|
-
'janis-app-package-name',
|
|
96
|
-
'janis-app-version',
|
|
97
|
-
'janis-app-name',
|
|
98
|
-
'janis-app-build',
|
|
99
|
-
'janis-app-device-os-name',
|
|
100
|
-
'janis-app-device-os-version',
|
|
101
|
-
'janis-app-device-id',
|
|
102
|
-
'janis-app-device-name',
|
|
103
|
-
];
|
|
104
|
-
|
|
105
|
-
const hasSomeValidValues = keysToCheck.some(
|
|
106
|
-
(key) => isString(deviceData[key]) && !!deviceData[key],
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
if (!hasSomeValidValues) return {};
|
|
110
|
-
|
|
111
|
-
const userAgentParts = [];
|
|
112
|
-
|
|
113
|
-
keysToCheck.forEach((key) => {
|
|
114
|
-
const value =
|
|
115
|
-
!deviceData[key] || !isString(deviceData[key])
|
|
116
|
-
? `unknown ${key}`
|
|
117
|
-
: deviceData[key];
|
|
118
|
-
userAgentParts.push(value);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
return {
|
|
122
|
-
'user-agent': `${userAgentParts[0]}/${userAgentParts[1]} (${userAgentParts[2]}; ${userAgentParts[3]}) ${userAgentParts[4]}/${userAgentParts[5]} (${userAgentParts[6]}; ${userAgentParts[7]})`,
|
|
123
|
-
};
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* @function getDeviceData
|
|
128
|
-
* @description return data from device user
|
|
129
|
-
* @returns {{
|
|
130
|
-
* 'application-name': string,
|
|
131
|
-
* 'build-number': string,
|
|
132
|
-
* 'app-version': string,
|
|
133
|
-
* 'bundle-id': string,
|
|
134
|
-
* 'os-name': string,
|
|
135
|
-
* 'device-id': string,
|
|
136
|
-
* 'device-name': string
|
|
137
|
-
* }} - Object with device data
|
|
138
|
-
* @example getDeviceData() => {applicationName: 'AppName', buildNumber: '434', appVersion: '1.5.0', bundleId: 'com.janis.appname', osName: 'android', osVersion: '11', deviceId: '34hf83hf89ahfjo', deviceName: 'Pixel 2'}
|
|
139
|
-
*/
|
|
140
|
-
|
|
141
|
-
export const getDeviceData = () => {
|
|
142
|
-
const applicationName = DeviceInfo.getApplicationName() || '';
|
|
143
|
-
const buildNumber = DeviceInfo.getBuildNumber() || '';
|
|
144
|
-
const appVersion = DeviceInfo.getVersion() || '';
|
|
145
|
-
const bundleId = DeviceInfo.getBundleId() || '';
|
|
146
|
-
const osName = DeviceInfo.getSystemName() || '';
|
|
147
|
-
const osVersion = DeviceInfo.getSystemVersion() || '';
|
|
148
|
-
const deviceId = DeviceInfo.getUniqueId() || '';
|
|
149
|
-
const deviceName = DeviceInfo.getModel() || '';
|
|
150
|
-
|
|
151
|
-
return {
|
|
152
|
-
'janis-app-name': applicationName,
|
|
153
|
-
'janis-app-build': buildNumber,
|
|
154
|
-
'janis-app-version': appVersion,
|
|
155
|
-
'janis-app-package-name': bundleId,
|
|
156
|
-
'janis-app-device-os-name': osName,
|
|
157
|
-
'janis-app-device-os-version': osVersion,
|
|
158
|
-
'janis-app-device-id': deviceId,
|
|
159
|
-
'janis-app-device-name': deviceName,
|
|
160
|
-
};
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
const filterValidHeaders = (headers) => {
|
|
164
|
-
if (!headers || !isObject(headers) || !Object.keys(headers).length) return {};
|
|
165
|
-
|
|
166
|
-
return Object.fromEntries(
|
|
167
|
-
Object.entries(headers).filter(([, value]) => !!value && !!isString(value)),
|
|
168
|
-
);
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* @function getHeaders
|
|
173
|
-
* @param {object} [params={}] - object with params
|
|
174
|
-
* @param {object} [deviceDataHeaders={}] - headers with the device info
|
|
175
|
-
* @param {object} [customHeaders={}] - extra custom headers
|
|
176
|
-
* @param {string} params.client - client name for janis api
|
|
177
|
-
* @param {string} params.accessToken - access token for janis api
|
|
178
|
-
* @param {number} params.page - number of page
|
|
179
|
-
* @param {number} params.pageSize - quantity per page
|
|
180
|
-
* @param {boolean} params.getTotals - request api totals
|
|
181
|
-
* @param {boolean} params.getOnlyTotals - request api totals without body response
|
|
182
|
-
* @description get correct headers for janis api
|
|
183
|
-
* @returns {object}
|
|
76
|
+
* @function promiseWrapper
|
|
77
|
+
* @param {function} fn
|
|
78
|
+
* @description wrapper to execute promise and return tuple with data and error
|
|
79
|
+
* @returns {array<data, error>}
|
|
184
80
|
* @example
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
* accessToken: 'my-access-token',
|
|
188
|
-
* page: 1,
|
|
189
|
-
* pageSize: 10,
|
|
190
|
-
* getTotals: true,
|
|
191
|
-
* getOnlyTotals: false
|
|
192
|
-
* };
|
|
193
|
-
* const deviceDataHeaders = {
|
|
194
|
-
* 'janis-app-name': 'MyApp',
|
|
195
|
-
* 'janis-app-version': '1.0.0',
|
|
196
|
-
* 'janis-app-device-os-name': 'iOS',
|
|
197
|
-
* 'janis-app-device-os-version': '14.5',
|
|
198
|
-
* 'janis-app-device-name': 'iPhone 12',
|
|
199
|
-
* 'janis-app-device-id': '123456789'
|
|
200
|
-
* };
|
|
201
|
-
* const customHeaders = {
|
|
202
|
-
* 'custom-header': 'custom-value'
|
|
203
|
-
* };
|
|
204
|
-
* const headers = getHeaders(params, deviceDataHeaders, customHeaders);
|
|
205
|
-
* // {
|
|
206
|
-
* // 'content-Type': 'application/json',
|
|
207
|
-
* // 'janis-api-key': 'Bearer',
|
|
208
|
-
* // 'janis-client': 'my-client',
|
|
209
|
-
* // 'janis-api-secret': 'my-access-token',
|
|
210
|
-
* // 'x-janis-page': 1,
|
|
211
|
-
* // 'x-janis-page-size': 10,
|
|
212
|
-
* // 'x-janis-totals': true,
|
|
213
|
-
* // 'x-janis-only-totals': false,
|
|
214
|
-
* // 'user-agent': 'MyApp/1.0.0 (iOS 14.5; iPhone 12; 123456789)',
|
|
215
|
-
* // 'custom-header': 'custom-value'
|
|
216
|
-
* // }
|
|
81
|
+
* import {promiseWrapper} from '@janiscommerce/apps-helpers'
|
|
82
|
+
* const [data, error] = await promiseWrapper(promise())
|
|
217
83
|
*/
|
|
218
84
|
|
|
219
|
-
export const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
const validDeviceDataHeaders = filterValidHeaders(deviceDataHeaders);
|
|
224
|
-
const validUserAgentHeader = formatDeviceDataForUserAgent(
|
|
225
|
-
validDeviceDataHeaders,
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
const baseHeaders = {
|
|
229
|
-
'content-Type': 'application/json',
|
|
230
|
-
'janis-api-key': 'Bearer',
|
|
231
|
-
...validUserAgentHeader,
|
|
232
|
-
...validDeviceDataHeaders,
|
|
233
|
-
...validCustomHeaders,
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
if (!isObject(params)) return baseHeaders;
|
|
237
|
-
const {client, accessToken, page, pageSize, getTotals, getOnlyTotals} =
|
|
238
|
-
params;
|
|
239
|
-
|
|
240
|
-
return {
|
|
241
|
-
...baseHeaders,
|
|
242
|
-
...(isString(client) && client && {'janis-client': client}),
|
|
243
|
-
...(isString(accessToken) &&
|
|
244
|
-
accessToken && {'janis-api-secret': accessToken}),
|
|
245
|
-
...(isNumber(page) && page && {'x-janis-page': page}),
|
|
246
|
-
...(isNumber(pageSize) && pageSize && {'x-janis-page-size': pageSize}),
|
|
247
|
-
...(isBoolean(getTotals) && getTotals && {'x-janis-totals': getTotals}),
|
|
248
|
-
...(isBoolean(getOnlyTotals) &&
|
|
249
|
-
getOnlyTotals && {'x-janis-only-totals': getOnlyTotals}),
|
|
250
|
-
};
|
|
251
|
-
};
|
|
85
|
+
export const promiseWrapper = (promise) =>
|
|
86
|
+
promise
|
|
87
|
+
.then((data) => [data, null])
|
|
88
|
+
.catch((error) => Promise.resolve([null, error]));
|
|
252
89
|
|
|
253
90
|
// MESSAGING UTILS
|
|
254
91
|
|
|
@@ -258,7 +95,7 @@ export const getHeaders = (params = {}, customHeaders = {}) => {
|
|
|
258
95
|
* @returns {Promise<string>}
|
|
259
96
|
* @example
|
|
260
97
|
*
|
|
261
|
-
* getFCMToken() => JDF6GJS364uhaGGe384gJHIQs23nbRNFG2859gJSD9gBivajeSJD
|
|
98
|
+
* getFCMToken() => 'JDF6GJS364uhaGGe384gJHIQs23nbRNFG2859gJSD9gBivajeSJD'
|
|
262
99
|
*/
|
|
263
100
|
|
|
264
101
|
export const getFCMToken = async () => {
|
|
@@ -309,58 +146,18 @@ export const setupForegroundMessageHandler = (callback) =>
|
|
|
309
146
|
* @param {Function} callback is the function that will receive the payload and render it as appropriate
|
|
310
147
|
*/
|
|
311
148
|
|
|
312
|
-
export const setupBackgroundMessageHandler = (callback) =>
|
|
149
|
+
export const setupBackgroundMessageHandler = (callback = () => {}) =>
|
|
313
150
|
messaging().setBackgroundMessageHandler(async (remoteMessage) => {
|
|
314
151
|
callback(remoteMessage);
|
|
315
152
|
});
|
|
316
153
|
|
|
317
154
|
/** *
|
|
318
|
-
* @
|
|
319
|
-
* @description
|
|
320
|
-
* @param {
|
|
321
|
-
* @throws null when not receive a valid object as remoteMessage
|
|
322
|
-
* @returns an alert with title and body received from FCM remoteMessage
|
|
323
|
-
*
|
|
155
|
+
* @function setupNotificationOpenedHandler
|
|
156
|
+
* @description This function is responsible for handling any Firebase Cloud Messaging callbacks that the app will have from the background
|
|
157
|
+
* @param {Function} callback is the function that will receive the payload and render it as appropriate
|
|
324
158
|
*/
|
|
325
159
|
|
|
326
|
-
export const
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
const {title, body} = notification;
|
|
331
|
-
|
|
332
|
-
const validTitle = isString(title) ? title : 'A new FCM message arrived!';
|
|
333
|
-
const validateBody = isString(body) ? body : undefined;
|
|
334
|
-
|
|
335
|
-
return Alert.alert(validTitle, validateBody);
|
|
336
|
-
};
|
|
337
|
-
|
|
338
|
-
/* istanbul ignore next */
|
|
339
|
-
export const topicsSubscription = async (topics) => {
|
|
340
|
-
try {
|
|
341
|
-
if (!topics || !isString(topics)) return null;
|
|
342
|
-
|
|
343
|
-
await messaging().subscribeToTopic(topics);
|
|
344
|
-
|
|
345
|
-
return {message: `suscribed to ${topics} topic!`};
|
|
346
|
-
} catch (reason) {
|
|
347
|
-
console.error(reason?.message);
|
|
348
|
-
|
|
349
|
-
return Promise.reject(reason?.message);
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
|
-
|
|
353
|
-
/* istanbul ignore next */
|
|
354
|
-
export const topicsUnsubscription = async (topic) => {
|
|
355
|
-
try {
|
|
356
|
-
if (!topic || !isString(topic)) return null;
|
|
357
|
-
|
|
358
|
-
await messaging().unsubscribeFromTopic(topic);
|
|
359
|
-
|
|
360
|
-
return {message: `unsuscribed to ${topic} topic!`};
|
|
361
|
-
} catch (reason) {
|
|
362
|
-
console.error(reason?.message);
|
|
363
|
-
|
|
364
|
-
return Promise.reject(reason?.message);
|
|
365
|
-
}
|
|
366
|
-
};
|
|
160
|
+
export const setupNotificationOpenedHandler = (callback) =>
|
|
161
|
+
messaging().onNotificationOpenedApp(async (remoteMessage) => {
|
|
162
|
+
callback(remoteMessage);
|
|
163
|
+
});
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@janiscommerce/app-push-notification",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"description": "This package will take care of performing the main actions for registration to receive notifications in the foreground and background.",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"test": "jest",
|
|
9
9
|
"lint": "eslint .",
|
|
10
|
-
"build-docs": "jsdoc2md --template template-readme.hbs --files lib
|
|
10
|
+
"build-docs": "jsdoc2md --template template-readme.hbs --files lib/NotificationProvider/index.js lib/NotificationContext.js > README.md",
|
|
11
11
|
"test:coverage": "jest --collectCoverage",
|
|
12
12
|
"validate:code": "npm run lint -- --fix && jest --collectCoverage"
|
|
13
13
|
},
|
|
@@ -27,30 +27,33 @@
|
|
|
27
27
|
"author": "Janis",
|
|
28
28
|
"license": "ISC",
|
|
29
29
|
"dependencies": {
|
|
30
|
+
"@janiscommerce/app-request": "^2.2.0",
|
|
30
31
|
"@react-native-async-storage/async-storage": "^1.18.1",
|
|
31
32
|
"@react-native-firebase/app": "^18.3.1",
|
|
32
33
|
"@react-native-firebase/messaging": "^18.3.1",
|
|
33
34
|
"axios": "^1.3.6",
|
|
34
|
-
"react-native-device-info": "^
|
|
35
|
+
"react-native-device-info": "^8.5.0"
|
|
35
36
|
},
|
|
36
37
|
"peerDependencies": {
|
|
37
38
|
"react": ">=17.0.2 <=18.2.0",
|
|
38
39
|
"react-native": ">=0.67.5 <=0.72.0"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
|
-
"@babel/core": "^7.
|
|
42
|
+
"@babel/core": "^7.22.10",
|
|
42
43
|
"@babel/eslint-parser": "^7.5.4",
|
|
43
44
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
44
45
|
"@babel/plugin-proposal-object-rest-spread": "^7.20.7",
|
|
45
46
|
"@babel/preset-env": "^7.22.10",
|
|
46
47
|
"@babel/runtime": "^7.12.5",
|
|
48
|
+
"@janiscommerce/app-request": "^2.2.0",
|
|
47
49
|
"@react-native-community/eslint-config": "^2.0.0",
|
|
48
50
|
"@react-native-firebase/app": "^18.3.1",
|
|
49
51
|
"@react-native-firebase/messaging": "^18.3.1",
|
|
50
52
|
"@testing-library/react-native": "^12.0.1",
|
|
51
|
-
"babel-
|
|
53
|
+
"babel-eslint": "^10.1.0",
|
|
54
|
+
"babel-jest": "^26.6.3",
|
|
52
55
|
"babel-loader": "8.2.4",
|
|
53
|
-
"eslint": "
|
|
56
|
+
"eslint": "7.14.0",
|
|
54
57
|
"eslint-config-airbnb": "^18.2.1",
|
|
55
58
|
"eslint-config-prettier": "^8.1.0",
|
|
56
59
|
"eslint-plugin-import": "^2.22.1",
|
|
@@ -68,6 +71,7 @@
|
|
|
68
71
|
"prettier": "^2.4.1",
|
|
69
72
|
"react": "^17.0.2",
|
|
70
73
|
"react-native": "^0.67.5",
|
|
74
|
+
"react-native-device-info": "^8.5.0",
|
|
71
75
|
"react-test-renderer": "^17.0.2"
|
|
72
76
|
},
|
|
73
77
|
"bugs": {
|