diff --git a/src/android/com/adobe/phonegap/push/FCMService.java b/src/android/com/adobe/phonegap/push/FCMService.java index db1738a72..d29ca9915 100644 --- a/src/android/com/adobe/phonegap/push/FCMService.java +++ b/src/android/com/adobe/phonegap/push/FCMService.java @@ -55,15 +55,15 @@ public class FCMService extends FirebaseMessagingService implements PushConstant private static HashMap> messageMap = new HashMap>(); public void setNotification(int notId, String message) { - ArrayList messageList = messageMap.get(notId); - if (messageList == null) { - messageList = new ArrayList(); - messageMap.put(notId, messageList); - } if (message.isEmpty()) { - messageList.clear(); + messageMap.remove(notId); } else { + ArrayList messageList = messageMap.get(notId); + if (messageList == null) { + messageList = new ArrayList(); + messageMap.put(notId, messageList); + } messageList.add(message); } } @@ -98,11 +98,28 @@ public void onMessageReceived(RemoteMessage message) { String titleKey = prefs.getString(TITLE_KEY, TITLE); extras = normalizeExtras(applicationContext, extras, messageKey, titleKey); + String clearNotifications = extras.getString(CLEAR_NOTIFICATIONS); if (clearBadge) { PushPlugin.setApplicationIconBadgeNumber(getApplicationContext(), 0); } + if (clearNotifications != null) { + Log.d(LOG_TAG, clearNotifications); + try { + Log.d(LOG_TAG, "cancel notifications " + clearNotifications); + JSONArray notificationIds = new JSONArray(clearNotifications); + if (notificationIds.length() != 0) { + for (int i = 0; i < notificationIds.length(); i++) { + int clearNotificationId = notificationIds.getInt(i); + PushPlugin.clearNotification(getApplicationContext(), clearNotificationId); + } + } + } catch (JSONException e) { + Log.e(LOG_TAG, "malformed clear notifications =[" + clearNotifications + "]"); + } + } + // if we are in the foreground and forceShow is `false` only send data if (!forceShow && PushPlugin.isInForeground()) { Log.d(LOG_TAG, "foreground"); @@ -128,6 +145,24 @@ else if (forceShow && PushPlugin.isInForeground()) { } } } + /* + * Cancel a notification + */ + private void cancelNotification(int notificationId) { + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + String appName = getAppName(this); + + if (notificationId != 0) { + Log.d(LOG_TAG, "cancel notification id: " + notificationId); + setNotification(notificationId, ""); + try { + notificationManager.cancel(appName, notificationId); + } catch (NullPointerException e) { + Log.e(LOG_TAG, "could not cancel notification id: " + notificationId); + } + } + } + /* * Change a values key in the extras bundle @@ -659,13 +694,35 @@ private void setNotificationOngoing(Bundle extras, NotificationCompat.Builder mB private void setNotificationMessage(int notId, Bundle extras, NotificationCompat.Builder mBuilder) { String message = extras.getString(MESSAGE); + String lines = extras.getString(LINES); String style = extras.getString(STYLE, STYLE_TEXT); if (STYLE_INBOX.equals(style)) { setNotification(notId, message); mBuilder.setContentText(fromHtml(message)); - ArrayList messageList = messageMap.get(notId); + ArrayList messageList = new ArrayList(); + if (lines != null) { + setNotification(notId, ""); + try { + JSONArray linesList = new JSONArray(lines); + if (linesList.length() != 0) { + for (int i = 0; i < linesList.length(); i++) { + messageList.add(linesList.optString(i)); + setNotification(notId, linesList.optString(i)); + } + } + } catch (JSONException e) { + // nope + } + } else { + ArrayList cachedMessages = messageMap.get(notId); + messageList.add(message); + for (int i = 0; i < cachedMessages.size(); i++) { + messageList.addAll(cachedMessages); + } + } + Integer sizeList = messageList.size(); if (sizeList > 1) { String sizeListMessage = sizeList.toString(); @@ -677,7 +734,7 @@ private void setNotificationMessage(int notId, Bundle extras, NotificationCompat NotificationCompat.InboxStyle notificationInbox = new NotificationCompat.InboxStyle() .setBigContentTitle(fromHtml(extras.getString(TITLE))).setSummaryText(fromHtml(stacking)); - for (int i = messageList.size() - 1; i >= 0; i--) { + for (int i=0; i 0) { + NSLog(@"Push Plugin clearing notId %@", clearNotificationId); + [pushHandler clearRealNotification:clearNotificationId]; + } + } + } + } + } @catch (NSException *exception) { + NSLog(@"Push Plugin could not parse clearNotifications array"); + } +} + - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler @@ -195,9 +228,10 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"]; pushHandler.notificationMessage = notification.request.content.userInfo; pushHandler.isInline = YES; + pushHandler.tapped = false; [pushHandler notificationReceived]; - completionHandler(UNNotificationPresentationOptionNone); + completionHandler(UNNotificationPresentationOptionBadge); } - (void)userNotificationCenter:(UNUserNotificationCenter *)center diff --git a/src/ios/PushPlugin.h b/src/ios/PushPlugin.h index 4b6ec930a..a2bc25c58 100644 --- a/src/ios/PushPlugin.h +++ b/src/ios/PushPlugin.h @@ -35,6 +35,7 @@ { NSDictionary *notificationMessage; BOOL isInline; + BOOL tapped; NSString *notificationCallbackId; NSString *callback; BOOL clearBadge; @@ -51,6 +52,7 @@ @property (nonatomic, strong) NSDictionary *notificationMessage; @property BOOL isInline; +@property BOOL tapped; @property BOOL coldstart; @property BOOL clearBadge; @property (nonatomic, strong) NSMutableDictionary *handlerObj; @@ -60,6 +62,7 @@ - (void)subscribe:(CDVInvokedUrlCommand*)command; - (void)unsubscribe:(CDVInvokedUrlCommand*)command; - (void)clearNotification:(CDVInvokedUrlCommand*)command; +- (void)clearRealNotification:(NSNumber*)notId; - (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken; - (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error; diff --git a/src/ios/PushPlugin.m b/src/ios/PushPlugin.m index 0290c8ecc..a613c81c5 100644 --- a/src/ios/PushPlugin.m +++ b/src/ios/PushPlugin.m @@ -36,6 +36,7 @@ @implementation PushPlugin : CDVPlugin @synthesize notificationMessage; @synthesize isInline; +@synthesize tapped; @synthesize coldstart; @synthesize callbackId; @@ -454,6 +455,12 @@ - (void)notificationReceived { [additionalData setObject:[NSNumber numberWithBool:NO] forKey:@"coldstart"]; } + if (tapped) { + [additionalData setObject:[NSNumber numberWithBool:YES] forKey:@"tapped"]; + } else { + [additionalData setObject:[NSNumber numberWithBool:NO] forKey:@"tapped"]; + } + [message setObject:additionalData forKey:@"additionalData"]; // send notification message @@ -463,12 +470,12 @@ - (void)notificationReceived { self.coldstart = NO; self.notificationMessage = nil; + self.tapped = false; } } -- (void)clearNotification:(CDVInvokedUrlCommand *)command +- (void)clearRealNotification:(NSNumber *)notId { - NSNumber *notId = [command.arguments objectAtIndex:0]; [[UNUserNotificationCenter currentNotificationCenter] getDeliveredNotificationsWithCompletionHandler:^(NSArray * _Nonnull notifications) { /* * If the server generates a unique "notId" for every push notification, there should only be one match in these arrays, but if not, it will delete @@ -481,13 +488,19 @@ - (void)clearNotification:(CDVInvokedUrlCommand *)command [matchingNotificationIdentifiers addObject:notification.request.identifier]; } [[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:matchingNotificationIdentifiers]; - - NSString *message = [NSString stringWithFormat:@"Cleared notification with ID: %@", notId]; - CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message]; - [self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId]; }]; } +- (void)clearNotification:(CDVInvokedUrlCommand *)command +{ + NSNumber *notId = [command.arguments objectAtIndex:0]; + [self clearRealNotification: notId]; + + NSString *message = [NSString stringWithFormat:@"Cleared notification with ID: %@", notId]; + CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message]; + [self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId]; +} + - (void)setApplicationIconBadgeNumber:(CDVInvokedUrlCommand *)command { NSMutableDictionary* options = [command.arguments objectAtIndex:0];