@janiscommerce/app-push-notification 0.0.3 → 0.0.5
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 -0
- package/README.md +28 -2
- package/lib/NotificationProvider/index.js +32 -0
- package/lib/constants/defaultChannelConfigs.js +13 -0
- package/lib/utils/channel/index.js +75 -0
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -29,12 +29,37 @@ 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
|
+
## Customize background notification sound:
|
|
33
|
+
|
|
34
|
+
To customize the background notification sound, you can pass the `backgroundNotificationSound` parameter to the `NotificationProvider` component. By default, it uses the 'default' sound.
|
|
35
|
+
|
|
36
|
+
```javascript
|
|
37
|
+
import NotificationProvider from '@janiscommerce/app-push-notification'
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<NotificationProvider
|
|
41
|
+
appName='pickingApp'
|
|
42
|
+
events={["picking:session:created","picking:session:assigned"]}
|
|
43
|
+
environment='beta'
|
|
44
|
+
backgroundNotificationSound='custom_sound' // Custom sound file name
|
|
45
|
+
>
|
|
46
|
+
<MyComponent/>
|
|
47
|
+
</NotificationProvider>
|
|
48
|
+
)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
To use a custom sound on Android, you must:
|
|
52
|
+
1. Place the sound file in the `android/app/src/main/res/raw/` folder
|
|
53
|
+
2. The file name must be lowercase and without special characters
|
|
54
|
+
3. The sound file must be in .mp3, .wav, or .aac format
|
|
55
|
+
4. Pass the exactly file name (without extension) as the value of `backgroundNotificationSound`
|
|
56
|
+
|
|
32
57
|
# This library provides the following components and methods:
|
|
33
58
|
|
|
34
59
|
## Functions
|
|
35
60
|
|
|
36
61
|
<dl>
|
|
37
|
-
<dt><a href="#NotificationProvider">NotificationProvider(children, appName, events, environment, additionalInfo)</a> ⇒ <code>null</code> | <code>React.element</code></dt>
|
|
62
|
+
<dt><a href="#NotificationProvider">NotificationProvider(children, appName, events, environment, additionalInfo, channelConfigs)</a> ⇒ <code>null</code> | <code>React.element</code></dt>
|
|
38
63
|
<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
64
|
</dd>
|
|
40
65
|
<dt><a href="#setupBackgroundMessageHandler">setupBackgroundMessageHandler(callback)</a></dt>
|
|
@@ -91,7 +116,7 @@ For more information about this, read https://rnfirebase.io/reference/messaging/
|
|
|
91
116
|
|
|
92
117
|
<a name="NotificationProvider"></a>
|
|
93
118
|
|
|
94
|
-
## NotificationProvider(children, appName, events, environment, additionalInfo) ⇒ <code>null</code> \| <code>React.element</code>
|
|
119
|
+
## NotificationProvider(children, appName, events, environment, additionalInfo, channelConfigs) ⇒ <code>null</code> \| <code>React.element</code>
|
|
95
120
|
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.
|
|
96
121
|
|
|
97
122
|
**Kind**: global function
|
|
@@ -107,6 +132,7 @@ It is the main component of the package, it is a HOC that is responsible for han
|
|
|
107
132
|
| events | <code>Array.<string></code> | is an array that will contain the events to which the user wants to subscribe |
|
|
108
133
|
| environment | <code>string</code> | The environment is necessary for the API that we are going to use to subscribe the device to notifications. |
|
|
109
134
|
| additionalInfo | <code>object</code> | fields to be sent as part of the body of the subscription request |
|
|
135
|
+
| channelConfigs | <code>Array.<(string\|object)></code> | is the configuration that will be used to create new notification channels |
|
|
110
136
|
|
|
111
137
|
**Example**
|
|
112
138
|
```js
|
|
@@ -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
|
|
@@ -18,6 +23,8 @@ import usePushNotification from '../usePushNotification';
|
|
|
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.
|
|
20
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
|
|
27
|
+
* @param {string} backgroundNotificationSound is the sound that will be played when the app is in the background
|
|
21
28
|
* @throws null when not receive a children argument
|
|
22
29
|
* @returns {null | React.element}
|
|
23
30
|
* @example
|
|
@@ -41,6 +48,8 @@ const NotificationProvider = ({
|
|
|
41
48
|
events,
|
|
42
49
|
environment,
|
|
43
50
|
additionalInfo,
|
|
51
|
+
channelConfigs = [],
|
|
52
|
+
backgroundNotificationSound,
|
|
44
53
|
}) => {
|
|
45
54
|
if (!children) return null;
|
|
46
55
|
|
|
@@ -48,6 +57,13 @@ const NotificationProvider = ({
|
|
|
48
57
|
const validEnvironment =
|
|
49
58
|
!!environment && isString(environment) ? environment : '';
|
|
50
59
|
const validEvents = !!events && isArray(events) ? events : [];
|
|
60
|
+
const validChannelConfigs =
|
|
61
|
+
!!channelConfigs && isArray(channelConfigs) ? channelConfigs : [];
|
|
62
|
+
|
|
63
|
+
const safeBackgroundSound =
|
|
64
|
+
isString(backgroundNotificationSound) && backgroundNotificationSound?.trim()
|
|
65
|
+
? backgroundNotificationSound.trim()
|
|
66
|
+
: 'default';
|
|
51
67
|
|
|
52
68
|
const isRegistered = useRef(false);
|
|
53
69
|
const {
|
|
@@ -95,6 +111,18 @@ const NotificationProvider = ({
|
|
|
95
111
|
return updateNotificationState({backgroundNotification: data});
|
|
96
112
|
};
|
|
97
113
|
|
|
114
|
+
const createNotificationChannels = async () => {
|
|
115
|
+
/* istanbul ignore else */
|
|
116
|
+
if (validChannelConfigs) {
|
|
117
|
+
const parsedChannelConfigs = validChannelConfigs
|
|
118
|
+
?.map((config) => parseNotificationChannel(config))
|
|
119
|
+
.filter(Boolean);
|
|
120
|
+
|
|
121
|
+
await makeNotificationChannels(parsedChannelConfigs);
|
|
122
|
+
}
|
|
123
|
+
await makeDefaultChannel({sound: safeBackgroundSound});
|
|
124
|
+
};
|
|
125
|
+
|
|
98
126
|
useEffect(() => {
|
|
99
127
|
const alreadySuscribed = isRegistered.current;
|
|
100
128
|
if (environment && appName && !!pushEvents.length && !alreadySuscribed) {
|
|
@@ -102,6 +130,10 @@ const NotificationProvider = ({
|
|
|
102
130
|
}
|
|
103
131
|
}, [pushEvents]);
|
|
104
132
|
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
createNotificationChannels();
|
|
135
|
+
}, []);
|
|
136
|
+
|
|
105
137
|
/* istanbul ignore next */
|
|
106
138
|
useEffect(() => {
|
|
107
139
|
const foregroundMessageHandler = setupForegroundMessageHandler(
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {AndroidImportance, AndroidVisibility} from '@notifee/react-native';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_CHANNEL_CONFIGS = {
|
|
4
|
+
badge: true,
|
|
5
|
+
importance: AndroidImportance.HIGH,
|
|
6
|
+
lights: true,
|
|
7
|
+
sound: 'default',
|
|
8
|
+
vibration: true,
|
|
9
|
+
vibrationPattern: [500, 1000, 500, 1000],
|
|
10
|
+
visibility: AndroidVisibility.PUBLIC,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default DEFAULT_CHANNEL_CONFIGS;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import notifee, {AndroidImportance} from '@notifee/react-native';
|
|
2
|
+
import DEFAULT_CHANNEL_CONFIGS from '../../constants/defaultChannelConfigs';
|
|
3
|
+
import {isObject, isString} from '..';
|
|
4
|
+
|
|
5
|
+
export const parseChannelConfiguration = (params = {}) => {
|
|
6
|
+
if (!params || !isObject(params)) return null;
|
|
7
|
+
|
|
8
|
+
const {name, id = '', description = '', ...restConfigs} = params;
|
|
9
|
+
|
|
10
|
+
if (!name || !isString(name)) return null;
|
|
11
|
+
|
|
12
|
+
const isValidDescription = !!description && isString(description);
|
|
13
|
+
const hasValidId = !!id && isString(id);
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
...DEFAULT_CHANNEL_CONFIGS,
|
|
17
|
+
...restConfigs,
|
|
18
|
+
name,
|
|
19
|
+
id: hasValidId ? id : name,
|
|
20
|
+
importance: AndroidImportance.HIGH,
|
|
21
|
+
...(isValidDescription && {
|
|
22
|
+
description,
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const parseNotificationChannel = (channel) => {
|
|
28
|
+
const channelType = typeof channel;
|
|
29
|
+
const allowedConfigs = ['string', 'object'];
|
|
30
|
+
|
|
31
|
+
if (!allowedConfigs.includes(channelType)) return null;
|
|
32
|
+
const channelData = channelType === 'string' ? {name: channel} : channel;
|
|
33
|
+
|
|
34
|
+
const parsedChannel = parseChannelConfiguration(channelData);
|
|
35
|
+
|
|
36
|
+
return parsedChannel;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/* eslint-disable consistent-return */
|
|
40
|
+
export const makeNotificationChannel = async (channelConfig = {}) => {
|
|
41
|
+
const {id, name} = channelConfig;
|
|
42
|
+
|
|
43
|
+
if (!id || !name || !isString(id) || !isString(name)) return null;
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
await notifee.createChannel(channelConfig);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return Promise.reject(error);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/* eslint-disable consistent-return */
|
|
53
|
+
export const makeNotificationChannels = async (channelConfigs) => {
|
|
54
|
+
try {
|
|
55
|
+
await notifee.createChannels(channelConfigs);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return Promise.reject(error);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/* eslint-disable consistent-return */
|
|
62
|
+
export const makeDefaultChannel = async (configs = {}) => {
|
|
63
|
+
try {
|
|
64
|
+
const parsedChannel = parseChannelConfiguration({
|
|
65
|
+
id: 'channel_default',
|
|
66
|
+
name: 'Operational notifications',
|
|
67
|
+
description: 'Default channel to receive operational notifications',
|
|
68
|
+
...configs,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
await makeNotificationChannel(parsedChannel);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
return Promise.reject(error);
|
|
74
|
+
}
|
|
75
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@janiscommerce/app-push-notification",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
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",
|