├── README.md
├── index.d.ts
├── index.js
└── package.json
/README.md:
--------------------------------------------------------------------------------
1 | # native-notify
2 |
3 | ### You must create a free NativeNotify.com account to receive an App Id and an App Token, or native-notify won't work.
4 | ### Go to https://NativeNotify.com to sign up for free, no credit card required.
5 |
6 |
7 |
8 | ## What is Native Notify?
9 | Native Notify is a React Native Expo Push Notification service. Native Notify makes React Native Expo Push Notifications simple. With this native-notify plugin, you can send your first push notification in under 1 minute.
10 |
11 | Sign up for https://NativeNotify.com for free. No credit card required.
12 |
13 | ## Does native-notify work in Expo managed-workflow?
14 | Yes, native-notify works in Expo managed-workflow or Expo bare-workflow. You do NOT have to eject out of Expo to use native-notify.
15 |
16 | # Setup Guide:
17 |
18 | ### Step 1: Install
19 | ```
20 | npm i native-notify
21 | expo install expo-device expo-notifications
22 | ```
23 |
24 | ### Step 2: Import
25 | Import registerNNPushToken in your App.js file:
26 | ```
27 | import registerNNPushToken from 'native-notify';
28 | ```
29 |
30 | ### Step 3: Make sure your App.js function is a hook function
31 | Your App.js function MUST be a hook function, or your push notifications will NOT work. Here is an example:
32 |
33 | ```
34 | export default function App() {
35 | ...
36 | }
37 | ```
38 |
39 | This link explains how hooks work: https://reactjs.org/docs/hooks-intro.html
40 |
41 | ### Step 4: Paste
42 | Paste this code into your App.js component in the App function:
43 | ```
44 | registerNNPushToken(yourAppId, 'yourAppToken');
45 | ```
46 | You must go to https://NativeNotify.com to receive a free App Id and App Token, or the registerNNPushToken function will not work.
47 |
48 | It's free to sign up. No credit card required.
49 |
50 | ### Example of an App.js component with native-notify code included:
51 | ```
52 | import registerNNPushToken from 'native-notify';
53 |
54 | export default function App() {
55 | registerNNPushToken(yourAppId, 'yourAppToken');
56 |
57 | return (
58 | ...
59 | )
60 | }
61 | ```
62 |
63 | # Use
64 | The registerNNPushToken function will register your user's Native Notify push notification token and will return a data object. You can then send your users push notifications in the https://NativeNotify.com push notification portal.
65 |
66 | You can send data objects with your Native Notify push notifications. Once a user taps on your Native Notify push notification, the value of the data object will be returned to the pushDataObject variable. You can use this value to do things like redirect your users to a particular screen once a Native Notify push notification is tapped.
67 |
68 | ## Show your support
69 | Give a ⭐️ if this project helped you!
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | export default function registerNNPushToken(appId: any, appToken: any): void;
2 | export function registerIndieID(subID: any, appId: any, appToken: any): Promise;
3 | export function unregisterIndieDevice(subID: any, appId: any, appToken: any): Promise;
4 | export function getFollowMaster(masterSubID: any, appId: any, appToken: any): Promise<{
5 | follower_indie_ids: any;
6 | follower_count: any;
7 | following_indie_ids: any;
8 | following_count: any;
9 | }>;
10 | export function registerFollowMasterID(masterSubID: any, appId: any, appToken: any): Promise<"Follow Master Indie ID registered!" | "Follow Master Indie ID already registered.">;
11 | export function registerFollowerID(masterSubID: any, followerSubID: any, appId: any, appToken: any): Promise<"Follower Indie ID registered!" | "Follower Indie ID already registered.">;
12 | export function postFollowingID(masterSubID: any, followingSubID: any, appId: any, appToken: any): Promise<"Following Indie ID posted!" | "Following Indie ID already posted.">;
13 | export function unfollowMasterID(masterSubID: any, followerSubID: any, appId: any, appToken: any): Promise<"Follow Master unfollowed successfully!" | "FollowSubID is not following Follow Master.">;
14 | export function updateFollowersList(masterSubID: any, followingSubID: any, appId: any, appToken: any): Promise<"Follow Master ID removed from Follower List successfully!" | "Follow Master ID is not in the Follower List.">;
15 | export function deleteFollowMaster(appId: any, appToken: any, masterSubID: any): Promise;
16 | export function getPushDataObject(): any;
17 | export function getPushDataInForeground(): any;
18 | export function getNotificationInbox(appId: any, appToken: any): Promise;
19 | export function getUnreadNotificationInboxCount(appId: any, appToken: any): Promise;
20 | export function getIndieNotificationInbox(subId: any, appId: any, appToken: any): Promise;
21 | export function getUnreadIndieNotificationInboxCount(subId: any, appId: any, appToken: any): Promise;
22 | export function deleteIndieNotificationInbox(subId: any, notificationId: any, appId: any, appToken: any): Promise;
23 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect, useRef } from 'react';
2 | import { Platform } from 'react-native';
3 | import * as Device from 'expo-device';
4 | import * as Notifications from 'expo-notifications';
5 | import axios from 'axios';
6 | import Constants from "expo-constants";
7 |
8 | Notifications.setNotificationHandler({handleNotification: async () => ({
9 | shouldShowAlert: true,
10 | shouldPlaySound: true,
11 | shouldSetBadge: true,
12 | })});
13 |
14 | async function registerForPushNotificationsAsync() {
15 | let expoAndroidToken, fcmToken, expoIosToken, apnToken;
16 |
17 | if (Platform.OS === 'android') {
18 | await Notifications.setNotificationChannelAsync('default', {
19 | name: 'default',
20 | importance: Notifications.AndroidImportance.MAX,
21 | vibrationPattern: [0, 250, 250, 250],
22 | lightColor: '#FF231F7C',
23 | });
24 | }
25 |
26 | if (Device.isDevice) {
27 | const { status: existingStatus } = await Notifications.getPermissionsAsync();
28 | let finalStatus = existingStatus;
29 | if (existingStatus !== 'granted') {
30 | try {
31 | const { status } = await Notifications.requestPermissionsAsync();
32 | finalStatus = status;
33 | } catch (error) {
34 | // console.log('An error occurred while requesting notification permissions:', error);
35 | return 'Failed to get push token';
36 | }
37 | }
38 | if (finalStatus !== 'granted') {
39 | return 'Failed to get push token';
40 | }
41 |
42 | if(Platform.OS === 'android') {
43 | expoAndroidToken = (await Notifications.getExpoPushTokenAsync({
44 | projectId: Constants.expoConfig.extra.eas.projectId,
45 | })).data;
46 | fcmToken = (await Notifications.getDevicePushTokenAsync()).data;
47 | } else if(Platform.OS === 'ios') {
48 | expoIosToken = (await Notifications.getExpoPushTokenAsync({
49 | projectId: Constants.expoConfig.extra.eas.projectId,
50 | })).data;
51 | apnToken = (await Notifications.getDevicePushTokenAsync()).data;
52 | }
53 | } else {
54 | console.log('Must use physical device for Push Notifications');
55 | return 'Must use physical device for Push Notifications';
56 | }
57 |
58 | return { expoAndroidToken, fcmToken, expoIosToken, apnToken };
59 | }
60 |
61 | export default function registerNNPushToken(appId, appToken) {
62 | const responseListener = useRef();
63 |
64 | useEffect(() => {
65 | if(Device.isDevice && Platform.OS !== 'web' || Platform.OS === 'android') {
66 | registerForPushNotificationsAsync()
67 | .then(async (res) => {
68 | if(res === 'Must use physical device for Push Notifications' || res === 'Failed to get push token')
69 | return
70 |
71 | const { expoAndroidToken, fcmToken, expoIosToken, apnToken } = res;
72 |
73 | await axios
74 | .post(`https://app.nativenotify.com/api/device/tokens`, {
75 | appId,
76 | appToken,
77 | platformOS: Platform.OS,
78 | expoAndroidToken,
79 | fcmToken,
80 | expoIosToken,
81 | apnToken
82 | })
83 | .then(() => console.log('You can now send a push notification. You successfully registered your Native Notify Push Token!'))
84 | .catch(err => console.log(err));
85 | });
86 |
87 | return () => { Notifications.removeNotificationSubscription(responseListener); };
88 | }
89 | }, []);
90 | }
91 |
92 | export async function registerIndieID(subID, appId, appToken) {
93 | if(Device.isDevice && Platform.OS !== 'web' || Platform.OS === 'android') {
94 | let expoToken = (await Notifications.getExpoPushTokenAsync({
95 | projectId: Constants.expoConfig.extra.eas.projectId,
96 | })).data;
97 | let deviceToken = (await Notifications.getDevicePushTokenAsync()).data;
98 | if(expoToken) {
99 | await axios.post(`https://app.nativenotify.com/api/indie/id`, {
100 | subID,
101 | appId,
102 | appToken,
103 | platformOS: Platform.OS,
104 | expoToken,
105 | deviceToken
106 | })
107 | .then(() => console.log('You successfully registered your Indie ID.'))
108 | .catch(err => console.log(err));
109 | } else {
110 | console.log('Setup Error: Please, follow the "Start Here" instructions BEFORE trying to use this registerIndieID function.')
111 | }
112 | }
113 | }
114 |
115 | export async function unregisterIndieDevice(subID, appId, appToken) {
116 | if(Device.isDevice && Platform.OS !== 'web' || Platform.OS === 'android') {
117 | let expoToken = (await Notifications.getExpoPushTokenAsync({
118 | projectId: Constants.expoConfig.extra.eas.projectId,
119 | })).data;
120 | let deviceToken = (await Notifications.getDevicePushTokenAsync()).data;
121 | if(expoToken) {
122 | await axios.put(`https://app.nativenotify.com/api/unregister/indie/device`, {
123 | appId,
124 | appToken,
125 | subID,
126 | expoToken,
127 | deviceToken
128 | })
129 | .then(() => console.log('You successfully unregistered your device from this Indie Sub ID.'))
130 | .catch(err => console.log(err));
131 | } else {
132 | console.log('Setup Error: Please, follow the "Start Here" instructions BEFORE trying to use this unregisterIndieDevice function.')
133 | }
134 | }
135 | }
136 |
137 | export async function getFollowMaster(masterSubID, appId, appToken) {
138 | let response = await axios.get(`https://app.nativenotify.com/api/follow/master/${masterSubID}/${appId}/${appToken}`)
139 |
140 | return {
141 | follower_indie_ids: response.data.follower_indie_ids,
142 | follower_count: response.data.follower_count,
143 | following_indie_ids: response.data.following_indie_ids,
144 | following_count: response.data.following_count };
145 | }
146 |
147 | export async function registerFollowMasterID(masterSubID, appId, appToken) {
148 | let response = '';
149 |
150 | await axios.post(`https://app.nativenotify.com/api/post/follow/master`, {
151 | masterSubID: masterSubID,
152 | appId: appId,
153 | appToken: appToken
154 | })
155 | .then(() => response = "Follow Master Indie ID registered!")
156 | .catch(() => response = "Follow Master Indie ID already registered.");
157 |
158 | if(response === "Follow Master Indie ID registered!") {
159 | return "Follow Master Indie ID registered!"
160 | }
161 |
162 | if(response === "Follow Master Indie ID already registered.") {
163 | return "Follow Master Indie ID already registered."
164 | }
165 | }
166 |
167 | export async function registerFollowerID(masterSubID, followerSubID, appId, appToken) {
168 | let response = '';
169 |
170 | await axios.post(`https://app.nativenotify.com/api/post/follower`, {
171 | masterSubID: masterSubID,
172 | followerSubID: followerSubID,
173 | appId: appId,
174 | appToken: appToken
175 | })
176 | .then(() => response = "Follower Indie ID registered!")
177 | .catch(() => response = "Follower Indie ID already registered.");
178 |
179 | if(response === "Follower Indie ID registered!") {
180 | return "Follower Indie ID registered!"
181 | }
182 |
183 | if(response === "Follower Indie ID already registered.") {
184 | return "Follower Indie ID already registered."
185 | }
186 | }
187 |
188 | export async function postFollowingID(masterSubID, followingSubID, appId, appToken) {
189 | let response = "";
190 |
191 | await axios.post(`https://app.nativenotify.com/api/post/following`, {
192 | masterSubID: masterSubID,
193 | followingSubID: followingSubID,
194 | appId: appId,
195 | appToken: appToken
196 | })
197 | .then(() => response = "Following Indie ID posted!")
198 | .catch(() => response = "Following Indie ID already posted.");
199 |
200 | if(response === "Following Indie ID posted!") {
201 | return "Following Indie ID posted!"
202 | }
203 |
204 | if(response === "Following Indie ID already posted.") {
205 | return "Following Indie ID already posted."
206 | }
207 | }
208 |
209 | export async function unfollowMasterID(masterSubID, followerSubID, appId, appToken) {
210 | let response = '';
211 |
212 | await axios.put(`https://app.nativenotify.com/api/unfollow/master`, {
213 | masterSubID: masterSubID,
214 | followerSubID: followerSubID,
215 | appId: appId,
216 | appToken: appToken
217 | })
218 | .then(() => response = "Follow Master unfollowed successfully!")
219 | .catch(() => response = "FollowSubID is not following Follow Master.");
220 |
221 | if(response === "Follow Master unfollowed successfully!") {
222 | return "Follow Master unfollowed successfully!"
223 | }
224 |
225 | if(response === "FollowSubID is not following Follow Master.") {
226 | return "FollowSubID is not following Follow Master."
227 | }
228 | }
229 |
230 | export async function updateFollowersList(masterSubID, followingSubID, appId, appToken) {
231 | let response = '';
232 |
233 | await axios.put(`https://app.nativenotify.com/api/master/followers/list`, {
234 | masterSubID: masterSubID,
235 | followingSubID: followingSubID,
236 | appId: appId,
237 | appToken: appToken
238 | })
239 | .then(() => response = "Follow Master ID removed from Follower List successfully!")
240 | .catch(() => response = "Follow Master ID is not in the Follower List.");
241 |
242 | if(response === "Follow Master ID removed from Follower List successfully!") {
243 | return "Follow Master ID removed from Follower List successfully!"
244 | }
245 |
246 | if(response === "Follow Master ID is not in the Follower List.") {
247 | return "Follow Master ID is not in the Follower List."
248 | }
249 | }
250 |
251 | export async function deleteFollowMaster(appId, appToken, masterSubID) {
252 | await axios
253 | .delete(`https://app.nativenotify.com/api/follow/master/${appId}/${appToken}/${masterSubID}`)
254 | .then(() => console.log("Follower Master unfollowed successfully!"))
255 | .catch(() => console.log("Follower Master does not exist."));
256 | }
257 |
258 | export function getPushDataObject() {
259 | const [data, setData] = useState({});
260 |
261 | const responseListener = useRef();
262 |
263 | useEffect(() => {
264 | if(Device.isDevice && Platform.OS !== 'web' || Platform.OS === 'android') {
265 |
266 | responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
267 | setData(response.notification.request.content.data);
268 | });
269 |
270 | return () => { Notifications.removeNotificationSubscription(responseListener.current); };
271 | }
272 | });
273 |
274 | return data;
275 | }
276 |
277 | export function getPushDataInForeground() {
278 | const [data, setData] = useState({});
279 |
280 | const notificationListener = useRef();
281 |
282 | useEffect(() => {
283 | if(Device.isDevice && Platform.OS !== 'web' || Platform.OS === 'android') {
284 |
285 | notificationListener.current = Notifications.addNotificationReceivedListener(response => {
286 | setData(response.request.content.data);
287 | });
288 |
289 | return () => { Notifications.removeNotificationSubscription(notificationListener.current); };
290 | }
291 | });
292 |
293 | return data;
294 | }
295 |
296 | export async function getNotificationInbox(appId, appToken, take, skip) {
297 | if(Device.isDevice && Platform.OS !== 'web' || Platform.OS === 'android') {
298 | let token = (await Notifications.getExpoPushTokenAsync({
299 | projectId: Constants.expoConfig.extra.eas.projectId,
300 | })).data;
301 | if(token) {
302 | await axios.post(`https://app.nativenotify.com/api/notification/inbox/read`, {
303 | appId,
304 | appToken,
305 | expoToken: token
306 | })
307 | }
308 | }
309 |
310 | let response = await axios.get(`https://app.nativenotify.com/api/notification/inbox/${appId}/${appToken}?take=${take}&skip=${skip}`);
311 |
312 | return response.data;
313 | }
314 |
315 | export async function getUnreadNotificationInboxCount(appId, appToken) {
316 | let response;
317 | if(Device.isDevice && Platform.OS !== 'web' || Platform.OS === 'android') {
318 | let token = (await Notifications.getExpoPushTokenAsync({
319 | projectId: Constants.expoConfig.extra.eas.projectId,
320 | })).data;
321 | if(token) {
322 | response = await axios.get(`https://app.nativenotify.com/api/notification/inbox/read/${appId}/${appToken}/${token}`);
323 | }
324 | }
325 |
326 | return response.data.unreadCount;
327 | }
328 |
329 | export async function getIndieNotificationInbox(subId, appId, appToken, take, skip) {
330 | let response = await axios.get(`https://app.nativenotify.com/api/indie/notification/inbox/${subId}/${appId}/${appToken}?take=${take}&skip=${skip}`);
331 |
332 | return response.data;
333 | }
334 |
335 | export async function getUnreadIndieNotificationInboxCount(subId, appId, appToken) {
336 | let response = await axios.get(`https://app.nativenotify.com/api/indie/notification/inbox/read/${subId}/${appId}/${appToken}`);
337 |
338 | return response.data.unreadCount;
339 | }
340 |
341 | export async function deleteIndieNotificationInbox(subId, notificationId, appId, appToken) {
342 | let response = await axios.delete(`https://app.nativenotify.com/api/indie/notification/inbox/notification/${appId}/${appToken}/${notificationId}/${subId}`);
343 |
344 | return response.data;
345 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "native-notify",
3 | "version": "4.0.4",
4 | "description": "Expo Push Notifications (React Native) by https://NativeNotify.com. Send your first Expo push notification in less than a minute.",
5 | "main": "index.js",
6 | "types": "index.d.ts",
7 | "scripts": {
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/NativeNotify/native-notify.git"
13 | },
14 | "keywords": [
15 | "expo",
16 | "push",
17 | "notifications",
18 | "react",
19 | "native",
20 | "notify",
21 | "expo push notifications",
22 | "expo push notification",
23 | "react native push notifications",
24 | "react native push notification",
25 | "expo push notifications react native",
26 | "expo push notification react native",
27 | "react native expo push notifications",
28 | "react native expo push notification",
29 | "native notify",
30 | "native notify push notifications"
31 | ],
32 | "author": "Native Notify, INC",
33 | "license": "MIT",
34 | "bugs": {
35 | "url": "https://github.com/NativeNotify/native-notify/issues"
36 | },
37 | "homepage": "https://github.com/NativeNotify/native-notify#readme",
38 | "dependencies": {
39 | "axios": "^1.5.1"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------