@janiscommerce/app-push-notification 0.0.2 → 0.0.4

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 CHANGED
@@ -1,8 +1,20 @@
1
1
  # Changelog
2
2
 
3
- [Unreleased]
3
+ ## [Unreleased]
4
4
 
5
- ## [0.0.1] - 2024-05-03
5
+ ## [0.0.4] - 2024-06-25
6
+
7
+ ### Added
8
+
9
+ - Added notification channels
10
+
11
+ ## [0.0.3] - 2024-06-13
12
+
13
+ ### Added
14
+
15
+ - additional info to send in subscription
16
+
17
+ ## [0.0.2] - 2024-05-03
6
18
 
7
19
  ### Added
8
20
 
package/README.md CHANGED
@@ -34,7 +34,7 @@ For more information about this, read https://rnfirebase.io/reference/messaging/
34
34
  ## Functions
35
35
 
36
36
  <dl>
37
- <dt><a href="#NotificationProvider">NotificationProvider(children, appName, events, environment)</a> ⇒ <code>null</code> | <code>React.element</code></dt>
37
+ <dt><a href="#NotificationProvider">NotificationProvider(children, appName, events, environment, additionalInfo, channelConfigs)</a> ⇒ <code>null</code> | <code>React.element</code></dt>
38
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
39
  </dd>
40
40
  <dt><a href="#setupBackgroundMessageHandler">setupBackgroundMessageHandler(callback)</a></dt>
@@ -70,6 +70,10 @@ For more information about this, read https://rnfirebase.io/reference/messaging/
70
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
71
  </tr>
72
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>
73
77
  <td>addNewEvent</td>
74
78
  <td>This function allows you to add a new event to receive notifications.</td>
75
79
  </tr>
@@ -87,7 +91,7 @@ For more information about this, read https://rnfirebase.io/reference/messaging/
87
91
 
88
92
  <a name="NotificationProvider"></a>
89
93
 
90
- ## NotificationProvider(children, appName, events, environment) ⇒ <code>null</code> \| <code>React.element</code>
94
+ ## NotificationProvider(children, appName, events, environment, additionalInfo, channelConfigs) ⇒ <code>null</code> \| <code>React.element</code>
91
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.
92
96
 
93
97
  **Kind**: global function
@@ -102,6 +106,8 @@ It is the main component of the package, it is a HOC that is responsible for han
102
106
  | appName | <code>string</code> | name of the aplication |
103
107
  | events | <code>Array.&lt;string&gt;</code> | is an array that will contain the events to which the user wants to subscribe |
104
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 |
110
+ | channelConfigs | <code>Array.&lt;(string\|object)&gt;</code> | is the configuration that will be used to create new notification channels |
105
111
 
106
112
  **Example**
107
113
  ```js
@@ -139,6 +145,7 @@ is a hook, which returns the elements contained within the notifications context
139
145
  | backgroundNotification | An object containing all data received when a background push notification is triggered. |
140
146
  | subscribeError | An object containing all data received from a notification service subscription failure. |
141
147
  | 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. |
148
+ | updateSuscription | This function is responsible for updating the subscription to the notification service |
142
149
  | addNewEvent | This function allows you to add a new event to receive notifications. |
143
150
  | deleteReceivedNotification | An util that clears the foreground or background notification state to the depending on the type it receives by parameter
144
151
  | getSubscribedEvents | This function returns an array with the events to which the user is subscribed. |
@@ -18,6 +18,7 @@ export const NotificationContext = React.createContext(null);
18
18
  * | backgroundNotification | An object containing all data received when a background push notification is triggered. |
19
19
  * | subscribeError | An object containing all data received from a notification service subscription failure. |
20
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 |
21
22
  * | addNewEvent | This function allows you to add a new event to receive notifications. |
22
23
  * | deleteReceivedNotification | An util that clears the foreground or background notification state to the depending on the type it receives by parameter
23
24
  * | getSubscribedEvents | This function returns an array with the events to which the user is subscribed. |
@@ -9,6 +9,11 @@ import {
9
9
  isObject,
10
10
  } from '../utils';
11
11
  import usePushNotification from '../usePushNotification';
12
+ import {
13
+ makeDefaultChannel,
14
+ makeNotificationChannels,
15
+ parseNotificationChannel,
16
+ } from '../utils/channel';
12
17
 
13
18
  /**
14
19
  * @function NotificationProvider
@@ -17,6 +22,8 @@ import usePushNotification from '../usePushNotification';
17
22
  * @param {string} appName name of the aplication
18
23
  * @param {Array<string>} events is an array that will contain the events to which the user wants to subscribe
19
24
  * @param {string} environment The environment is necessary for the API that we are going to use to subscribe the device to notifications.
25
+ * @param {object} additionalInfo fields to be sent as part of the body of the subscription request
26
+ * @param {Array<string | object>} channelConfigs is the configuration that will be used to create new notification channels
20
27
  * @throws null when not receive a children argument
21
28
  * @returns {null | React.element}
22
29
  * @example
@@ -34,13 +41,22 @@ import usePushNotification from '../usePushNotification';
34
41
  * )
35
42
  */
36
43
 
37
- const NotificationProvider = ({children, appName, events, environment}) => {
44
+ const NotificationProvider = ({
45
+ children,
46
+ appName,
47
+ events,
48
+ environment,
49
+ additionalInfo,
50
+ channelConfigs = [],
51
+ }) => {
38
52
  if (!children) return null;
39
53
 
40
54
  const validAppName = !!appName && isString(appName) ? appName : '';
41
55
  const validEnvironment =
42
56
  !!environment && isString(environment) ? environment : '';
43
57
  const validEvents = !!events && isArray(events) ? events : [];
58
+ const validChannelConfigs =
59
+ !!channelConfigs && isArray(channelConfigs) ? channelConfigs : [];
44
60
 
45
61
  const isRegistered = useRef(false);
46
62
  const {
@@ -53,6 +69,7 @@ const NotificationProvider = ({children, appName, events, environment}) => {
53
69
  validEvents,
54
70
  validAppName,
55
71
  isRegistered,
72
+ additionalInfo,
56
73
  );
57
74
 
58
75
  // @function handlerForegroundData
@@ -87,6 +104,18 @@ const NotificationProvider = ({children, appName, events, environment}) => {
87
104
  return updateNotificationState({backgroundNotification: data});
88
105
  };
89
106
 
107
+ const createNotificationChannels = async () => {
108
+ /* istanbul ignore else */
109
+ if (validChannelConfigs) {
110
+ const parsedChannelConfigs = validChannelConfigs
111
+ ?.map((config) => parseNotificationChannel(config))
112
+ .filter(Boolean);
113
+
114
+ await makeNotificationChannels(parsedChannelConfigs);
115
+ }
116
+ await makeDefaultChannel();
117
+ };
118
+
90
119
  useEffect(() => {
91
120
  const alreadySuscribed = isRegistered.current;
92
121
  if (environment && appName && !!pushEvents.length && !alreadySuscribed) {
@@ -94,6 +123,10 @@ const NotificationProvider = ({children, appName, events, environment}) => {
94
123
  }
95
124
  }, [pushEvents]);
96
125
 
126
+ useEffect(() => {
127
+ createNotificationChannels();
128
+ }, []);
129
+
97
130
  /* istanbul ignore next */
98
131
  useEffect(() => {
99
132
  const foregroundMessageHandler = setupForegroundMessageHandler(
@@ -4,7 +4,13 @@ import {getFCMToken, isArray, isString} from './utils';
4
4
  import SubscribeNotifications from './utils/api/SubscribeNotifications';
5
5
  import UnSubscribeNotifications from './utils/api/UnSubscribeNotifications';
6
6
 
7
- const usePushNotification = (environment, events, appName, isRegistered) => {
7
+ const usePushNotification = (
8
+ environment,
9
+ events,
10
+ appName,
11
+ isRegistered,
12
+ additionalInfo,
13
+ ) => {
8
14
  const [notificationState, setNotificationState] = useState({
9
15
  deviceToken: null,
10
16
  foregroundNotification: {},
@@ -54,6 +60,7 @@ const usePushNotification = (environment, events, appName, isRegistered) => {
54
60
  events: pushEvents,
55
61
  deviceToken: token,
56
62
  request: Request,
63
+ additionalInfo,
57
64
  });
58
65
 
59
66
  isRegistered.current = true;
@@ -63,6 +70,31 @@ const usePushNotification = (environment, events, appName, isRegistered) => {
63
70
  }
64
71
  }, [pushEvents]);
65
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
+
66
98
  /**
67
99
  * @function cancelNotifications
68
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.
@@ -161,6 +193,7 @@ const usePushNotification = (environment, events, appName, isRegistered) => {
161
193
  updateNotificationState,
162
194
  getSubscribedEvents,
163
195
  deleteReceivedNotification,
196
+ updateSuscription,
164
197
  };
165
198
  };
166
199
 
@@ -1,11 +1,11 @@
1
- import {isString, isArray} from '../../index';
1
+ import {isString, isArray, isObject} from '../../index';
2
2
 
3
3
  const SubscribeNotifications = async (params = {}) => {
4
4
  try {
5
5
  if (!params || !Object.keys(params).length)
6
6
  throw new Error('params is not a valid object');
7
7
 
8
- const {deviceToken, events, appName, request} = params;
8
+ const {deviceToken, events, appName, request, additionalInfo} = params;
9
9
 
10
10
  if (!deviceToken || !isString(deviceToken))
11
11
  throw new Error('device token is invalid or null');
@@ -19,10 +19,16 @@ const SubscribeNotifications = async (params = {}) => {
19
19
  if (!parsedEvents.length)
20
20
  throw new Error('events to be suscribed are invalids');
21
21
 
22
+ const validAdditionalInfo =
23
+ isObject(additionalInfo) && !!Object.keys(additionalInfo).length;
24
+
22
25
  const body = {
23
26
  token: deviceToken,
24
27
  events: parsedEvents,
25
28
  platformApplicationName: appName,
29
+ ...(validAdditionalInfo && {
30
+ additionalInfo,
31
+ }),
26
32
  };
27
33
 
28
34
  const response = await request.post({
@@ -0,0 +1,71 @@
1
+ import notifee, {AndroidImportance} from '@notifee/react-native';
2
+ import {isObject, isString} from '..';
3
+
4
+ export const parseChannelConfiguration = (params = {}) => {
5
+ if (!params || !isObject(params)) return null;
6
+
7
+ const {name, id = '', description = ''} = params;
8
+
9
+ if (!name || !isString(name)) return null;
10
+
11
+ const isValidDescription = !!description && isString(description);
12
+ const hasValidId = !!id && isString(id);
13
+
14
+ return {
15
+ name,
16
+ id: hasValidId ? id : name,
17
+ importance: AndroidImportance.HIGH,
18
+ ...(isValidDescription && {
19
+ description,
20
+ }),
21
+ };
22
+ };
23
+
24
+ export const parseNotificationChannel = (channel) => {
25
+ const channelType = typeof channel;
26
+ const allowedConfigs = ['string', 'object'];
27
+
28
+ if (!allowedConfigs.includes(channelType)) return null;
29
+ const channelData = channelType === 'string' ? {name: channel} : channel;
30
+
31
+ const parsedChannel = parseChannelConfiguration(channelData);
32
+
33
+ return parsedChannel;
34
+ };
35
+
36
+ /* eslint-disable consistent-return */
37
+ export const makeNotificationChannel = async (channelConfig = {}) => {
38
+ const {id, name} = channelConfig;
39
+
40
+ if (!id || !name || !isString(id) || !isString(name)) return null;
41
+
42
+ try {
43
+ await notifee.createChannel(channelConfig);
44
+ } catch (error) {
45
+ return Promise.reject(error);
46
+ }
47
+ };
48
+
49
+ /* eslint-disable consistent-return */
50
+ export const makeNotificationChannels = async (channelConfigs) => {
51
+ try {
52
+ await notifee.createChannels(channelConfigs);
53
+ } catch (error) {
54
+ return Promise.reject(error);
55
+ }
56
+ };
57
+
58
+ /* eslint-disable consistent-return */
59
+ export const makeDefaultChannel = async () => {
60
+ try {
61
+ const parsedChannel = parseChannelConfiguration({
62
+ id: 'default_channel',
63
+ name: 'Common notifications',
64
+ description: 'Default channel to receive notifications',
65
+ });
66
+
67
+ await makeNotificationChannel(parsedChannel);
68
+ } catch (error) {
69
+ return Promise.reject(error);
70
+ }
71
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@janiscommerce/app-push-notification",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
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",
@@ -28,6 +28,7 @@
28
28
  "license": "ISC",
29
29
  "dependencies": {
30
30
  "@janiscommerce/app-request": "^2.2.0",
31
+ "@notifee/react-native": "^7.8.2",
31
32
  "@react-native-async-storage/async-storage": "^1.18.1",
32
33
  "@react-native-firebase/app": "^18.3.1",
33
34
  "@react-native-firebase/messaging": "^18.3.1",