Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 65 additions & 8 deletions src/android/com/adobe/phonegap/push/FCMService.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@ public class FCMService extends FirebaseMessagingService implements PushConstant
private static HashMap<Integer, ArrayList<String>> messageMap = new HashMap<Integer, ArrayList<String>>();

public void setNotification(int notId, String message) {
ArrayList<String> messageList = messageMap.get(notId);
if (messageList == null) {
messageList = new ArrayList<String>();
messageMap.put(notId, messageList);
}

if (message.isEmpty()) {
messageList.clear();
messageMap.remove(notId);
} else {
ArrayList<String> messageList = messageMap.get(notId);
if (messageList == null) {
messageList = new ArrayList<String>();
messageMap.put(notId, messageList);
}
messageList.add(message);
}
}
Expand Down Expand Up @@ -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");
Expand All @@ -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
Expand Down Expand Up @@ -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<String> messageList = messageMap.get(notId);
ArrayList<String> messageList = new ArrayList<String>();
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<String> 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();
Expand All @@ -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<messageList.size(); i++) {
notificationInbox.addLine(fromHtml(messageList.get(i)));
}

Expand Down
1 change: 1 addition & 0 deletions src/android/com/adobe/phonegap/push/PushConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,5 @@ public interface PushConstants {
public static final String ONGOING = "ongoing";
public static final String LIST_CHANNELS = "listChannels";
public static final String CLEAR_NOTIFICATION = "clearNotification";
public static final String LINES = "lines";
}
11 changes: 7 additions & 4 deletions src/android/com/adobe/phonegap/push/PushPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -534,10 +534,13 @@ private void clearAllNotifications() {
}

private void clearNotification(int id) {
final NotificationManager notificationManager = (NotificationManager) cordova.getActivity()
.getSystemService(Context.NOTIFICATION_SERVICE);
String appName = (String) this.cordova.getActivity().getPackageManager()
.getApplicationLabel(this.cordova.getActivity().getApplicationInfo());
PushPlugin.clearNotification(cordova.getActivity(), id);
}

static void clearNotification(Context context, int id) {
final NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
String appName = (String) context.getPackageManager()
.getApplicationLabel(context.getApplicationInfo());
notificationManager.cancel(appName, id);
}

Expand Down
38 changes: 36 additions & 2 deletions src/ios/AppDelegate+notification.m
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N
silent = [contentAvailable integerValue];
}

if (silent == 1) {
NSString * clearNotificationsString = [userInfo objectForKey:@"clearNotifications"];
// don't wakeup the app on clearNotifications - this is a decision based on performance
if (silent == 1 && clearNotificationsString == nil) {
NSLog(@"this should be a silent push");
void (^safeHandler)(UIBackgroundFetchResult) = ^(UIBackgroundFetchResult result){
dispatch_async(dispatch_get_main_queue(), ^{
Expand All @@ -121,15 +123,18 @@ - (void)application:(UIApplication *)application didReceiveRemoteNotification:(N

pushHandler.notificationMessage = userInfo;
pushHandler.isInline = NO;
pushHandler.tapped = false;
[pushHandler notificationReceived];
} else {
[self clearNotifications:userInfo];
NSLog(@"just put it in the shade");
//save it for later
self.launchNotification = userInfo;
completionHandler(UIBackgroundFetchResultNewData);
}

} else {
[self clearNotifications:userInfo];
completionHandler(UIBackgroundFetchResultNoData);
}
}
Expand Down Expand Up @@ -176,6 +181,7 @@ - (void)pushPluginOnApplicationDidBecomeActive:(NSNotification *)notification {

if (self.launchNotification) {
pushHandler.isInline = NO;
pushHandler.tapped = true;
pushHandler.coldstart = [self.coldstart boolValue];
pushHandler.notificationMessage = self.launchNotification;
self.launchNotification = nil;
Expand All @@ -186,6 +192,33 @@ - (void)pushPluginOnApplicationDidBecomeActive:(NSNotification *)notification {
[[NSNotificationCenter defaultCenter] postNotificationName:pushPluginApplicationDidBecomeActiveNotification object:nil];
}

- (void)clearNotifications:(NSDictionary *)userInfo
{
PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"];

@try {
NSString * clearNotificationsString = [userInfo objectForKey:@"clearNotifications"];
if (clearNotificationsString != nil) {
clearNotificationsString = [clearNotificationsString stringByReplacingOccurrencesOfString:@"[" withString:@""];
clearNotificationsString = [clearNotificationsString stringByReplacingOccurrencesOfString:@"]" withString:@""];

NSArray * clearNotificationsArray = [clearNotificationsString componentsSeparatedByString:@","];

for (NSString *notId in clearNotificationsArray){
if ([notId isKindOfClass:[NSString class]]) {
NSNumber *clearNotificationId = @([notId integerValue]);
if (clearNotificationId > 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
Expand All @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/ios/PushPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
{
NSDictionary *notificationMessage;
BOOL isInline;
BOOL tapped;
NSString *notificationCallbackId;
NSString *callback;
BOOL clearBadge;
Expand All @@ -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;
Expand All @@ -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;
Expand Down
25 changes: 19 additions & 6 deletions src/ios/PushPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ @implementation PushPlugin : CDVPlugin

@synthesize notificationMessage;
@synthesize isInline;
@synthesize tapped;
@synthesize coldstart;

@synthesize callbackId;
Expand Down Expand Up @@ -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
Expand All @@ -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<UNNotification *> * _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
Expand All @@ -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];
Expand Down
8 changes: 4 additions & 4 deletions www/push.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/**
* This file has been generated by Babel.
*
*
* DO NOT EDIT IT DIRECTLY
*
*
* Edit the JS source file src/js/push.js
**/'use strict';

Expand Down Expand Up @@ -240,7 +240,7 @@ var PushNotification = function () {
var id = arguments[2];

var idNumber = parseInt(id, 10);
if (isNaN(idNumber) || idNumber > Number.MAX_SAFE_INTEGER || idNumber < 0) {
if (isNaN(idNumber) || idNumber > 2147483647 || idNumber < -2147483648) {
console.log('PushNotification.clearNotification failure: id parameter must' + 'be a valid integer.');
return;
}
Expand Down Expand Up @@ -390,4 +390,4 @@ module.exports = {
* .init helper method.
*/
PushNotification: PushNotification
};
};