From dffaa859655ff43d03376ef600817ddc5cd82c1d Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Wed, 3 Apr 2019 16:44:40 -0400 Subject: [PATCH 01/16] fix(ios): edge case when non-interactive notification is tapped --- RNNotifications/RNNotifications.m | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/RNNotifications/RNNotifications.m b/RNNotifications/RNNotifications.m index 33786ed64..9f070c6e8 100644 --- a/RNNotifications/RNNotifications.m +++ b/RNNotifications/RNNotifications.m @@ -241,6 +241,26 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNot - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler { NSString* identifier = response.actionIdentifier; + NSDictionary* userInfo = response.notification.request.content.userInfo; + if ([identifier isEqualToString:UNNotificationDefaultActionIdentifier]) { + if ([RNNotificationsBridgeQueue sharedInstance].jsIsReady) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self checkAndSendEvent:RNNotificationOpened body:userInfo]; + }); + } else { + [[RNNotificationsBridgeQueue sharedInstance] postNotification:userInfo]; + } + + completionHandler(); + return; + } + +// TODO: emit this +// if ([identifier isEqualToString:UNNotificationDismissActionIdentifier]) { +// [self checkAndSendEvent:RNNotificationDismissed body:userInfo]; +// return; +// } + NSString* completionKey = [NSString stringWithFormat:@"%@.%@", identifier, [NSString stringWithFormat:@"%ld", (long)[[NSDate date] timeIntervalSince1970]]]; NSMutableDictionary* info = [[NSMutableDictionary alloc] initWithDictionary:@{ @"identifier": identifier, @"completionKey": completionKey }]; @@ -250,8 +270,6 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNoti info[@"text"] = text; } - NSDictionary* userInfo = response.notification.request.content.userInfo; - // add notification custom data if (userInfo != NULL) { info[@"notification"] = userInfo; From ec2d6d7c0d40990cb31a6096d536d56956ad3dfd Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Wed, 3 Apr 2019 18:10:20 -0400 Subject: [PATCH 02/16] fix: mis-emission of notification opened event --- RNNotifications/RNNotifications.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/RNNotifications/RNNotifications.m b/RNNotifications/RNNotifications.m index 9f070c6e8..0a49f3f63 100644 --- a/RNNotifications/RNNotifications.m +++ b/RNNotifications/RNNotifications.m @@ -226,7 +226,8 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNot if (![RNNotificationsBridgeQueue sharedInstance].jsIsReady) { - [RNNotificationsBridgeQueue sharedInstance].openedLocalNotification = notification.request.content.userInfo; + // TODO: schedule emit foreground/background + // [RNNotificationsBridgeQueue sharedInstance].openedLocalNotification = notification.request.content.userInfo; return; } @@ -318,12 +319,15 @@ -(void) handleReceiveNotification:(UIApplicationState)state userInfo:(NSDictiona { case (int)UIApplicationStateActive: [self checkAndSendEvent:RNNotificationReceivedForeground body:userInfo]; + break; case (int)UIApplicationStateInactive: [self checkAndSendEvent:RNNotificationOpened body:userInfo]; + break; default: [self checkAndSendEvent:RNNotificationReceivedBackground body:userInfo]; + break; } } From 8066938e8ca3d9960ccd46ac09228ca685b79ecc Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Wed, 3 Apr 2019 21:12:05 -0400 Subject: [PATCH 03/16] fix: propagate error when user denies permission --- RNNotifications/RNNotifications.m | 41 ++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/RNNotifications/RNNotifications.m b/RNNotifications/RNNotifications.m index 0a49f3f63..6641af0ca 100644 --- a/RNNotifications/RNNotifications.m +++ b/RNNotifications/RNNotifications.m @@ -23,6 +23,8 @@ NSString* const RNNotificationActionReceived = @"notificationActionReceived"; //NSString* const RNNotificationActionDismissed = @"RNNotificationActionDismissed"; +NSString* const RNNErrorDomain = @"RNNNotificationsError"; +static const int RNNErrorCode = -1; //////////////////////////////////////////////////////////////// #pragma mark conversions @@ -189,25 +191,36 @@ - (void)setBridge:(RCTBridge *)bridge #pragma mark private functions //////////////////////////////////////////////////////////////// -+ (void)requestPermissionsWithCategories:(NSMutableSet *)categories +- (void)requestPermissionsWithCategoriesInternal:(NSMutableSet *)categories { dispatch_async(dispatch_get_main_queue(), ^{ UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; [center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){ - if(!error) - { - if (granted) - { - dispatch_async(dispatch_get_main_queue(), ^{ - [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:categories]; - [[UIApplication sharedApplication] registerForRemoteNotifications]; - }); - } + if (error) { + [self sendFailedToRegisterEvent:error]; + return; } + + if (!granted) { + [self sendFailedToRegisterEvent:[RNNotifications errorWithMessage:@"UserDenied"]]; + return; + } + + dispatch_async(dispatch_get_main_queue(), ^{ + [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:categories]; + [[UIApplication sharedApplication] registerForRemoteNotifications]; + }); }]; }); } ++ (NSError *)errorWithMessage:(NSString *)errorMessage +{ + return [NSError errorWithDomain:RNNErrorDomain + code:RNNErrorCode + userInfo:@{ NSLocalizedDescriptionKey: NSLocalizedString(errorMessage, nil) }]; +} + //////////////////////////////////////////////////////////////// #pragma mark NRNNManagerDelegate //////////////////////////////////////////////////////////////// @@ -295,11 +308,17 @@ - (void)application:(UIApplication *)application didRegisterForRemoteNotificatio } - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error +{ + [self sendFailedToRegisterEvent:error]; +} + +- (void)sendFailedToRegisterEvent:(NSError *)error { [self checkAndSendEvent:RNNotificationsRegistrationFailed body:@{@"code": [NSNumber numberWithInteger:error.code], @"domain": error.domain, @"localizedDescription": error.localizedDescription}]; } + //the system calls this method when your app is running in the foreground or background - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { @@ -384,7 +403,7 @@ - (void)startObserving [categories addObject:[RCTConvert UNNotificationCategory:dic]]; } } - [RNNotifications requestPermissionsWithCategories:categories]; + [self requestPermissionsWithCategoriesInternal:categories]; } RCT_EXPORT_METHOD(localNotification:(NSDictionary *)notification withId:(NSString *)notificationId) From 3edca5ffcd1293c22f6b8f13a0c5dcaeb5a3c758 Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Thu, 4 Apr 2019 14:23:24 -0400 Subject: [PATCH 04/16] rename to publish under @exodus in npm --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 6f133d88e..e6b9f6157 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "react-native-notifications", + "name": "@exodus/react-native-notifications", "version": "1.3.0", "description": "Advanced Push Notifications (Silent, interactive notifications) for iOS & Android", "author": "Lidan Hifi ", @@ -50,11 +50,11 @@ }, "repository": { "type": "git", - "url": "https://github.com/wix/react-native-notifications.git" + "url": "https://github.com/ExodusMovement/react-native-notifications.git" }, - "homepage": "https://github.com/wix/react-native-notifications", + "homepage": "https://github.com/ExodusMovement/react-native-notifications", "bugs": { - "url": "https://github.com/wix/react-native-notifications/issues" + "url": "https://github.com/ExodusMovement/react-native-notifications/issues" }, "babel": { "presets": [ From b29368eb7e83be7564c995fe632fcdc5902052d9 Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Thu, 4 Apr 2019 14:24:39 -0400 Subject: [PATCH 05/16] 1.3.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e6b9f6157..c91c21f2f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@exodus/react-native-notifications", - "version": "1.3.0", + "version": "1.3.1", "description": "Advanced Push Notifications (Silent, interactive notifications) for iOS & Android", "author": "Lidan Hifi ", "license": "MIT", From 1e9dfc438ca6d9897ac283a41c43ba081d2840c4 Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Thu, 4 Apr 2019 15:14:05 -0400 Subject: [PATCH 06/16] fix: specify requiresMainQueueSetup -> YES, to remove annoying warning --- RNNotifications/RNNotifications.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/RNNotifications/RNNotifications.m b/RNNotifications/RNNotifications.m index 6641af0ca..b3bd6f104 100644 --- a/RNNotifications/RNNotifications.m +++ b/RNNotifications/RNNotifications.m @@ -174,7 +174,11 @@ - (instancetype)init return self; } - ++ (BOOL)requiresMainQueueSetup +{ + // TODO: figure out if we can return NO + return YES; +} - (void)setBridge:(RCTBridge *)bridge { From 83ea4c6e7e42c773b37b9276fbad6fd6a672093b Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Thu, 4 Apr 2019 15:29:17 -0400 Subject: [PATCH 07/16] 1.3.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c91c21f2f..87b65b12f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@exodus/react-native-notifications", - "version": "1.3.1", + "version": "1.3.2", "description": "Advanced Push Notifications (Silent, interactive notifications) for iOS & Android", "author": "Lidan Hifi ", "license": "MIT", From f5a3011ed284b468381045b1005ad975d49733e4 Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Fri, 5 Apr 2019 15:38:01 -0400 Subject: [PATCH 08/16] feat: support requesting local-only notifications --- RNNotifications/RNNotifications.m | 39 ++++++++++++++++++++----------- index.ios.js | 13 +++++++++-- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/RNNotifications/RNNotifications.m b/RNNotifications/RNNotifications.m index b3bd6f104..d656c4f9b 100644 --- a/RNNotifications/RNNotifications.m +++ b/RNNotifications/RNNotifications.m @@ -195,7 +195,7 @@ - (void)setBridge:(RCTBridge *)bridge #pragma mark private functions //////////////////////////////////////////////////////////////// -- (void)requestPermissionsWithCategoriesInternal:(NSMutableSet *)categories +- (void)requestPermissionsWithCategoriesInternal:(NSSet *)categories requestRemote: (BOOL) requestRemote { dispatch_async(dispatch_get_main_queue(), ^{ UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; @@ -212,7 +212,11 @@ - (void)requestPermissionsWithCategoriesInternal:(NSMutableSet *)categories dispatch_async(dispatch_get_main_queue(), ^{ [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:categories]; - [[UIApplication sharedApplication] registerForRemoteNotifications]; + if (requestRemote) { + [[UIApplication sharedApplication] registerForRemoteNotifications]; + } else { + [self checkAndSendEvent:RNNotificationsRegistered body:@{}]; + } }); }]; }); @@ -396,18 +400,12 @@ - (void)startObserving #pragma mark exported method //////////////////////////////////////////////////////////////// -RCT_EXPORT_METHOD(requestPermissionsWithCategories:(NSArray *)json) +RCT_EXPORT_METHOD(requestPermissionsWithCategories:(NSDictionary *)json) { - NSMutableSet* categories = nil; - if ([json count] > 0) - { - categories = [NSMutableSet new]; - for (NSDictionary* dic in json) - { - [categories addObject:[RCTConvert UNNotificationCategory:dic]]; - } - } - [self requestPermissionsWithCategoriesInternal:categories]; + NSArray *catsArr = [json valueForKey:@"categories"]; + BOOL requestRemote = [json valueForKey:@"remote"]; + NSSet* categories = [RNNotifications interpretNotificationCategories:catsArr]; + [self requestPermissionsWithCategoriesInternal:categories requestRemote:requestRemote]; } RCT_EXPORT_METHOD(localNotification:(NSDictionary *)notification withId:(NSString *)notificationId) @@ -478,6 +476,21 @@ + (void)didNotificationOpen:(NSDictionary *)notification userInfo:notification]; } ++ (NSSet*) interpretNotificationCategories: (NSArray*)json { + NSMutableSet* categories = nil; + if ([json count] > 0) + { + categories = [NSMutableSet new]; + for (NSDictionary* dic in json) + { + [categories addObject:[RCTConvert UNNotificationCategory:dic]]; + } + } + + // return immutable set + return [categories copy]; +} + /* * Helper methods */ diff --git a/index.ios.js b/index.ios.js index 8fe1dd9db..9c0b01dd0 100644 --- a/index.ios.js +++ b/index.ios.js @@ -120,7 +120,13 @@ export default class NotificationsIOS { /** * Sets the notification categories */ - static requestPermissions(categories: Array) { + static requestPermissions(opts) { + // backwards compat + if (Array.isArray(opts)) { + opts = { categories: opts } + } + + const { categories, remote } = opts let notificationCategories = []; if (categories) { @@ -139,7 +145,10 @@ export default class NotificationsIOS { }); } - RNNotifications.requestPermissionsWithCategories(notificationCategories); + RNNotifications.requestPermissionsWithCategories({ + categories: notificationCategories, + remote + }); } /** From 6b53f9dcc4d57254f395dac7b9151aeedbd5e74d Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Fri, 5 Apr 2019 15:50:10 -0400 Subject: [PATCH 09/16] 1.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 87b65b12f..574089317 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@exodus/react-native-notifications", - "version": "1.3.2", + "version": "1.4.0", "description": "Advanced Push Notifications (Silent, interactive notifications) for iOS & Android", "author": "Lidan Hifi ", "license": "MIT", From c959e8ab713b05cd99ade53926b57b6c8caafed2 Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Fri, 5 Apr 2019 15:52:54 -0400 Subject: [PATCH 10/16] fix: default requestPermissions to remote:true --- index.ios.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.ios.js b/index.ios.js index 9c0b01dd0..487acdda7 100644 --- a/index.ios.js +++ b/index.ios.js @@ -126,7 +126,7 @@ export default class NotificationsIOS { opts = { categories: opts } } - const { categories, remote } = opts + const { categories, remote=true } = opts let notificationCategories = []; if (categories) { From 96fdfba1a2c4f2c59274ab320b4cdaf6e0739462 Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Fri, 5 Apr 2019 15:53:53 -0400 Subject: [PATCH 11/16] 1.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 574089317..d957388c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@exodus/react-native-notifications", - "version": "1.4.0", + "version": "1.4.1", "description": "Advanced Push Notifications (Silent, interactive notifications) for iOS & Android", "author": "Lidan Hifi ", "license": "MIT", From 1d144e8bfd6e69847c2435100dc53fa98d2e0bbf Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Fri, 5 Apr 2019 16:16:24 -0400 Subject: [PATCH 12/16] fix: use RCTConvert to interpret options --- RNNotifications/RNNotifications.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RNNotifications/RNNotifications.m b/RNNotifications/RNNotifications.m index d656c4f9b..7bce859e9 100644 --- a/RNNotifications/RNNotifications.m +++ b/RNNotifications/RNNotifications.m @@ -402,8 +402,8 @@ - (void)startObserving RCT_EXPORT_METHOD(requestPermissionsWithCategories:(NSDictionary *)json) { - NSArray *catsArr = [json valueForKey:@"categories"]; - BOOL requestRemote = [json valueForKey:@"remote"]; + NSArray *catsArr = [RCTConvert NSArray:json[@"categories"]]; + BOOL requestRemote = [RCTConvert BOOL:json[@"remote"]]; NSSet* categories = [RNNotifications interpretNotificationCategories:catsArr]; [self requestPermissionsWithCategoriesInternal:categories requestRemote:requestRemote]; } From c35a2e8eaeaf22dcce43964108105c9c27f4d9ab Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Fri, 5 Apr 2019 16:45:43 -0400 Subject: [PATCH 13/16] 1.4.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d957388c0..b17fc4330 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@exodus/react-native-notifications", - "version": "1.4.1", + "version": "1.4.2", "description": "Advanced Push Notifications (Silent, interactive notifications) for iOS & Android", "author": "Lidan Hifi ", "license": "MIT", From 433b0d5ca700f70edc4d344cf56d6e9b4564d97a Mon Sep 17 00:00:00 2001 From: Mark Vayngrib Date: Tue, 9 Nov 2021 15:13:49 -0500 Subject: [PATCH 14/16] docs: rm broken s3 img from readme --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 173f7a61a..e2fb11132 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,12 @@ Handle all the aspects of push notifications for your app, including remote and local notifications, interactive notifications, silent notifications, and more. -**All the native iOS notifications features are supported!** +**All the native iOS notifications features are supported!** _For information regarding proper integration with [react-native-navigation](https://github.com/wix/react-native-navigation), follow [this wiki](https://github.com/wix/react-native-notifications/wiki/Android:-working-with-RNN)._ - ### iOS -Interactive notifications example - - Remote (push) notifications - Local notifications - Background/Managed notifications (notifications that can be cleared from the server, like Facebook messenger and Whatsapp web) @@ -26,7 +23,6 @@ _For information regarding proper integration with [react-native-navigation](htt _Upcoming: local notifications, background-state Rx queue (iOS equivalent)_ - # Table of Content - [Installation and setup](./docs/installation.md) - Setting up the library in your app @@ -37,6 +33,7 @@ _Upcoming: local notifications, background-state Rx queue (iOS equivalent)_ - [Notifications layout control - Android (wiki page)](https://github.com/wix/react-native-notifications/wiki/Android:-Layout-Customization) - Learn how to fully customize your notifications layout on Android! # License + The MIT License. See [LICENSE](LICENSE) From a6a250cb5a410e6e0ae364e665d0ab05c3aabef6 Mon Sep 17 00:00:00 2001 From: Ariene Maiara Ribeiro Date: Mon, 13 Feb 2023 13:40:30 -0300 Subject: [PATCH 15/16] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e2fb11132..cade69b17 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +**This package is outdated.** Check the updated fork on https://github.com/ExodusMovement/react-native-push-notifications + # React Native Notifications [![Build Status](https://travis-ci.org/wix/react-native-notifications.svg)](https://travis-ci.org/wix/react-native-notifications) Handle all the aspects of push notifications for your app, including remote and local notifications, interactive notifications, silent notifications, and more. From 6d752067ac49e266ee533340adcc1f74b3851ae4 Mon Sep 17 00:00:00 2001 From: Ariene Maiara Ribeiro Date: Tue, 14 Feb 2023 13:39:48 -0300 Subject: [PATCH 16/16] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index cade69b17..e2fb11132 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -**This package is outdated.** Check the updated fork on https://github.com/ExodusMovement/react-native-push-notifications - # React Native Notifications [![Build Status](https://travis-ci.org/wix/react-native-notifications.svg)](https://travis-ci.org/wix/react-native-notifications) Handle all the aspects of push notifications for your app, including remote and local notifications, interactive notifications, silent notifications, and more.