diff --git a/native/ios/Comm/AppDelegate.mm b/native/ios/Comm/AppDelegate.mm --- a/native/ios/Comm/AppDelegate.mm +++ b/native/ios/Comm/AppDelegate.mm @@ -26,8 +26,8 @@ @end #endif +#import "CommIOSNotifications.h" #import "Orientation.h" -#import "RNNotifications.h" #import #import @@ -158,13 +158,13 @@ - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { - [RNNotifications + [CommIOSNotifications didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { - [RNNotifications didFailToRegisterForRemoteNotificationsWithError:error]; + [CommIOSNotifications didFailToRegisterForRemoteNotificationsWithError:error]; } // Required for the notification event. You must call the completion handler @@ -184,8 +184,8 @@ return; } - [RNNotifications didReceiveRemoteNotification:notification - fetchCompletionHandler:completionHandler]; + [CommIOSNotifications didReceiveRemoteNotification:notification + fetchCompletionHandler:completionHandler]; } - (BOOL)handleBackgroundNotification:(NSDictionary *)notification @@ -202,22 +202,9 @@ comm::ThreadOperations::updateSQLiteUnreadStatus(threadID, false); }); } - [[UNUserNotificationCenter currentNotificationCenter] - getDeliveredNotificationsWithCompletionHandler:^( - NSArray *notifications) { - for (UNNotification *notif in notifications) { - if ([notification[@"notificationId"] - isEqual:notif.request.content.userInfo[@"id"]]) { - NSArray *identifiers = - [NSArray arrayWithObjects:notif.request.identifier, nil]; - [[UNUserNotificationCenter currentNotificationCenter] - removeDeliveredNotificationsWithIdentifiers:identifiers]; - } - } - dispatch_async(dispatch_get_main_queue(), ^{ - completionHandler(UIBackgroundFetchResultNewData); - }); - }]; + [CommIOSNotifications + clearNotificationFromNotificationsCenter:notification[@"notificationId"] + completionHandler:completionHandler]; return YES; } return NO; @@ -226,7 +213,7 @@ // Required for the localNotification event. - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { - [RNNotifications didReceiveLocalNotification:notification]; + [CommIOSNotifications didReceiveLocalNotification:notification]; } - (UIInterfaceOrientationMask)application:(UIApplication *)application diff --git a/native/push/ios.js b/native/push/ios.js --- a/native/push/ios.js +++ b/native/push/ios.js @@ -1,6 +1,8 @@ // @flow -import NotificationsIOS from 'react-native-notifications'; +import { NativeModules } from 'react-native'; + +const { CommIOSNotifications } = NativeModules; type PushPermissions = { alert?: boolean, badge?: boolean, sound?: boolean }; @@ -12,7 +14,7 @@ firstRun = false; if (!permissionNeeded) { - const permissions: PushPermissions = await NotificationsIOS.checkPermissions(); + const permissions: PushPermissions = await CommIOSNotifications.checkPermissions(); permissionNeeded = permissionMissing(permissions); } @@ -21,10 +23,10 @@ return; } currentlyActive = true; - await NotificationsIOS.requestPermissions(); + await CommIOSNotifications.requestPermissions(); } - NotificationsIOS.consumeBackgroundQueue(); + CommIOSNotifications.consumeBackgroundQueue(); } function iosPushPermissionResponseReceived() { diff --git a/native/push/push-handler.react.js b/native/push/push-handler.react.js --- a/native/push/push-handler.react.js +++ b/native/push/push-handler.react.js @@ -2,7 +2,14 @@ import * as Haptics from 'expo-haptics'; import * as React from 'react'; -import { AppRegistry, Platform, Alert, LogBox } from 'react-native'; +import { + AppRegistry, + Platform, + Alert, + LogBox, + NativeModules, + NativeEventEmitter, +} from 'react-native'; import type { RemoteMessage, NotificationOpen } from 'react-native-firebase'; import { Notification as InAppNotification } from 'react-native-in-app-message'; import NotificationsIOS from 'react-native-notifications'; @@ -55,6 +62,7 @@ handleAndroidMessage, androidBackgroundMessageTask, } from './android'; +import { CommIOSNotification } from './comm-ios-notification'; import { getFirebase } from './firebase'; import InAppNotif from './in-app-notif.react'; import { @@ -103,6 +111,16 @@ +onPress: () => void, }, }; + +const { CommIOSNotifications } = NativeModules; +const CommIOSNotificationsEventEmitter = new NativeEventEmitter<{ + remoteNotificationsRegistered: Object, + remoteNotificationsRegistrationFailed: Object, + notificationReceivedForeground: Object, + notificationOpened: Object, +}>(CommIOSNotifications); +const CommIOSNotificationsEventSubscriptions = []; + class PushHandler extends React.PureComponent { state: State = { inAppNotifProps: null, @@ -123,21 +141,28 @@ ); this.onForeground(); if (Platform.OS === 'ios') { - NotificationsIOS.addEventListener( - 'remoteNotificationsRegistered', - this.registerPushPermissions, - ); - NotificationsIOS.addEventListener( - 'remoteNotificationsRegistrationFailed', - this.failedToRegisterPushPermissions, - ); - NotificationsIOS.addEventListener( - 'notificationReceivedForeground', - this.iosForegroundNotificationReceived, - ); - NotificationsIOS.addEventListener( - 'notificationOpened', - this.iosNotificationOpened, + CommIOSNotificationsEventSubscriptions.push( + CommIOSNotificationsEventEmitter.addListener( + 'remoteNotificationsRegistered', + registration => + this.registerPushPermissions(registration?.deviceToken), + ), + CommIOSNotificationsEventEmitter.addListener( + 'remoteNotificationsRegistrationFailed', + this.failedToRegisterPushPermissions, + ), + CommIOSNotificationsEventEmitter.addListener( + 'notificationReceivedForeground', + notification => + this.iosForegroundNotificationReceived( + new CommIOSNotification(notification), + ), + ), + CommIOSNotificationsEventEmitter.addListener( + 'notificationOpened', + notification => + this.iosNotificationOpened(new CommIOSNotification(notification)), + ), ); } else if (Platform.OS === 'android') { const firebase = getFirebase(); @@ -168,22 +193,9 @@ this.lifecycleSubscription.remove(); } if (Platform.OS === 'ios') { - NotificationsIOS.removeEventListener( - 'remoteNotificationsRegistered', - this.registerPushPermissions, - ); - NotificationsIOS.removeEventListener( - 'remoteNotificationsRegistrationFailed', - this.failedToRegisterPushPermissions, - ); - NotificationsIOS.removeEventListener( - 'notificationReceivedForeground', - this.iosForegroundNotificationReceived, - ); - NotificationsIOS.removeEventListener( - 'notificationOpened', - this.iosNotificationOpened, - ); + for (const commIOSNotificationsEventSubscription of CommIOSNotificationsEventSubscriptions) { + commIOSNotificationsEventSubscription.remove(); + } } else if (Platform.OS === 'android') { if (this.androidTokenListener) { this.androidTokenListener(); @@ -488,7 +500,13 @@ if (notification.getData().title) { ({ title, body } = mergePrefixIntoBody(notification.getData())); } - this.showInAppNotification(threadID, body, title); + if (body) { + this.showInAppNotification(threadID, body, title); + } else { + console.log( + 'Non-rescind foreground notification without alert received!', + ); + } notification.finish(NotificationsIOS.FetchResult.NewData); };