[notifications] Specific notificationPressed data type including action
This commit is contained in:
parent
303cb4c428
commit
8e84dd576b
|
@ -38,7 +38,7 @@ RCT_EXPORT_MODULE();
|
||||||
- (void)configure {
|
- (void)configure {
|
||||||
// If we're on iOS 10 then we need to set this as a delegate for the UNUserNotificationCenter
|
// If we're on iOS 10 then we need to set this as a delegate for the UNUserNotificationCenter
|
||||||
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||||
// [UNUserNotificationCenter currentNotificationCenter].delegate = self;
|
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set static instance for use from AppDelegate
|
// Set static instance for use from AppDelegate
|
||||||
|
@ -51,20 +51,22 @@ RCT_EXPORT_MODULE();
|
||||||
// *******************************************************
|
// *******************************************************
|
||||||
|
|
||||||
- (void)didReceiveLocalNotification:(nonnull UILocalNotification *)notification {
|
- (void)didReceiveLocalNotification:(nonnull UILocalNotification *)notification {
|
||||||
NSString *event;
|
#if !defined(__IPHONE_10_0) || __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_10_0
|
||||||
if (RCTSharedApplication().applicationState == UIApplicationStateBackground) {
|
NSString *event;
|
||||||
// notification_displayed
|
if (RCTSharedApplication().applicationState == UIApplicationStateBackground) {
|
||||||
event = NOTIFICATIONS_NOTIFICATION_DISPLAYED;
|
// notification_displayed
|
||||||
} else if (RCTSharedApplication().applicationState == UIApplicationStateInactive) {
|
event = NOTIFICATIONS_NOTIFICATION_DISPLAYED;
|
||||||
// notification_displayed
|
} else if (RCTSharedApplication().applicationState == UIApplicationStateInactive) {
|
||||||
event = NOTIFICATIONS_NOTIFICATION_PRESSED;
|
// notification_displayed
|
||||||
} else {
|
event = NOTIFICATIONS_NOTIFICATION_PRESSED;
|
||||||
// notification_received
|
} else {
|
||||||
event = NOTIFICATIONS_NOTIFICATION_RECEIVED;
|
// notification_received
|
||||||
}
|
event = NOTIFICATIONS_NOTIFICATION_RECEIVED;
|
||||||
|
}
|
||||||
|
|
||||||
NSDictionary *message = [self parseUILocalNotification:notification];
|
NSDictionary *message = [self parseUILocalNotification:notification];
|
||||||
[RNFirebaseUtil sendJSEvent:self name:event body:message];
|
[RNFirebaseUtil sendJSEvent:self name:event body:message];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen for background messages
|
// Listen for background messages
|
||||||
|
@ -85,11 +87,16 @@ RCT_EXPORT_MODULE();
|
||||||
event = NOTIFICATIONS_NOTIFICATION_PRESSED;
|
event = NOTIFICATIONS_NOTIFICATION_PRESSED;
|
||||||
} else {
|
} else {
|
||||||
// notification_received
|
// notification_received
|
||||||
event = NOTIFICATIONS_NOTIFICATION_RECEIVED;
|
// On IOS 10, foreground notifications also go through willPresentNotification
|
||||||
|
// This prevents duplicate messages from hitting the JS app
|
||||||
|
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
event = NOTIFICATIONS_NOTIFICATION_RECEIVED;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Proper notification structure
|
NSDictionary *message = [self parseUserInfo:userInfo messageType:@"RemoteNotification" category:nil];
|
||||||
NSDictionary *message = [self parseUserInfo:userInfo messageType:@"RemoteNotification" clickAction:nil];
|
|
||||||
|
|
||||||
[RNFirebaseUtil sendJSEvent:self name:event body:message];
|
[RNFirebaseUtil sendJSEvent:self name:event body:message];
|
||||||
}
|
}
|
||||||
|
@ -104,6 +111,7 @@ RCT_EXPORT_MODULE();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NSString *event;
|
NSString *event;
|
||||||
if (RCTSharedApplication().applicationState == UIApplicationStateBackground) {
|
if (RCTSharedApplication().applicationState == UIApplicationStateBackground) {
|
||||||
// notification_displayed
|
// notification_displayed
|
||||||
|
@ -113,16 +121,19 @@ RCT_EXPORT_MODULE();
|
||||||
event = NOTIFICATIONS_NOTIFICATION_PRESSED;
|
event = NOTIFICATIONS_NOTIFICATION_PRESSED;
|
||||||
} else {
|
} else {
|
||||||
// notification_received
|
// notification_received
|
||||||
event = NOTIFICATIONS_NOTIFICATION_RECEIVED;
|
// On IOS 10, foreground notifications also go through willPresentNotification
|
||||||
|
// This prevents duplicate messages from hitting the JS app
|
||||||
|
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
event = NOTIFICATIONS_NOTIFICATION_RECEIVED;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Proper notification structure
|
NSDictionary *message = [self parseUserInfo:userInfo messageType:@"RemoteNotificationHandler" category:nil];
|
||||||
NSDictionary *message = [self parseUserInfo:userInfo messageType:@"RemoteNotificationHandler" clickAction:nil];
|
|
||||||
|
|
||||||
// TODO: Callback handler
|
|
||||||
// [_callbackHandlers setObject:[completionHandler copy] forKey:message[@"messageId"]];
|
|
||||||
|
|
||||||
[RNFirebaseUtil sendJSEvent:self name:event body:message];
|
[RNFirebaseUtil sendJSEvent:self name:event body:message];
|
||||||
|
completionHandler(UIBackgroundFetchResultNoData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// *******************************************************
|
// *******************************************************
|
||||||
|
@ -181,7 +192,7 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
|
||||||
#else
|
#else
|
||||||
withCompletionHandler:(void(^)())completionHandler {
|
withCompletionHandler:(void(^)())completionHandler {
|
||||||
#endif
|
#endif
|
||||||
NSDictionary *message = [self parseUNNotification:response.notification messageType:@"NotificationResponse"];
|
NSDictionary *message = [self parseUNNotificationResponse:response messageType:@"NotificationResponse"];
|
||||||
|
|
||||||
[RNFirebaseUtil sendJSEvent:self name:NOTIFICATIONS_NOTIFICATION_PRESSED body:message];
|
[RNFirebaseUtil sendJSEvent:self name:NOTIFICATIONS_NOTIFICATION_PRESSED body:message];
|
||||||
completionHandler();
|
completionHandler();
|
||||||
|
@ -253,7 +264,7 @@ RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve rejecte
|
||||||
} else {
|
} else {
|
||||||
NSDictionary *remoteNotification = [self bridge].launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
|
NSDictionary *remoteNotification = [self bridge].launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
|
||||||
if (remoteNotification) {
|
if (remoteNotification) {
|
||||||
NSDictionary *message = [self parseUserInfo:remoteNotification messageType:@"InitialMessage" clickAction:nil];
|
NSDictionary *message = [self parseUserInfo:remoteNotification messageType:@"InitialMessage" category:nil];
|
||||||
resolve(message);
|
resolve(message);
|
||||||
} else {
|
} else {
|
||||||
resolve(nil);
|
resolve(nil);
|
||||||
|
@ -560,17 +571,27 @@ RCT_EXPORT_METHOD(scheduleNotification:(NSDictionary*) notification
|
||||||
return notification;
|
return notification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSDictionary*)parseUNNotificationResponse:(UNNotificationResponse *)response
|
||||||
|
messageType:(NSString *)messageType {
|
||||||
|
NSMutableDictionary *notificationResponse = [[NSMutableDictionary alloc] init];
|
||||||
|
NSDictionary *notification = [self parseUNNotification:response.notification messageType:messageType];
|
||||||
|
notificationResponse[@"notification"] = notification;
|
||||||
|
notificationResponse[@"action"] = response.actionIdentifier;
|
||||||
|
|
||||||
|
return notificationResponse;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSDictionary*)parseUNNotification:(UNNotification *)notification
|
- (NSDictionary*)parseUNNotification:(UNNotification *)notification
|
||||||
messageType:(NSString *)messageType {
|
messageType:(NSString *)messageType {
|
||||||
NSDictionary *userInfo = notification.request.content.userInfo;
|
NSDictionary *userInfo = notification.request.content.userInfo;
|
||||||
NSString *clickAction = notification.request.content.categoryIdentifier;
|
NSString *category = notification.request.content.categoryIdentifier;
|
||||||
|
|
||||||
return [self parseUserInfo:userInfo messageType:messageType clickAction:clickAction];
|
return [self parseUserInfo:userInfo messageType:messageType category:category];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDictionary*)parseUserInfo:(NSDictionary *)userInfo
|
- (NSDictionary*)parseUserInfo:(NSDictionary *)userInfo
|
||||||
messageType:(NSString *) messageType
|
messageType:(NSString *) messageType
|
||||||
clickAction:(NSString *) clickAction {
|
category:(NSString *) category {
|
||||||
|
|
||||||
NSMutableDictionary *notification = [[NSMutableDictionary alloc] init];
|
NSMutableDictionary *notification = [[NSMutableDictionary alloc] init];
|
||||||
NSMutableDictionary *data = [[NSMutableDictionary alloc] init];
|
NSMutableDictionary *data = [[NSMutableDictionary alloc] init];
|
||||||
|
@ -585,22 +606,15 @@ RCT_EXPORT_METHOD(scheduleNotification:(NSDictionary*) notification
|
||||||
for (id k3 in alert) {
|
for (id k3 in alert) {
|
||||||
if ([k3 isEqualToString:@"body"]) {
|
if ([k3 isEqualToString:@"body"]) {
|
||||||
notification[@"body"] = alert[k3];
|
notification[@"body"] = alert[k3];
|
||||||
} else if ([k3 isEqualToString:@"loc-args"]) {
|
|
||||||
// TODO: What to do with this?
|
|
||||||
// notif[@"bodyLocalizationArgs"] = alert[k3];
|
|
||||||
} else if ([k3 isEqualToString:@"loc-key"]) {
|
|
||||||
// TODO: What to do with this?
|
|
||||||
// notif[@"bodyLocalizationKey"] = alert[k3];
|
|
||||||
} else if ([k3 isEqualToString:@"subtitle"]) {
|
} else if ([k3 isEqualToString:@"subtitle"]) {
|
||||||
notification[@"subtitle"] = alert[k3];
|
notification[@"subtitle"] = alert[k3];
|
||||||
} else if ([k3 isEqualToString:@"title"]) {
|
} else if ([k3 isEqualToString:@"title"]) {
|
||||||
notification[@"title"] = alert[k3];
|
notification[@"title"] = alert[k3];
|
||||||
} else if ([k3 isEqualToString:@"title-loc-args"]) {
|
} else if ([k3 isEqualToString:@"loc-args"]
|
||||||
// TODO: What to do with this?
|
|| [k3 isEqualToString:@"loc-key"]
|
||||||
// notif[@"titleLocalizationArgs"] = alert[k3];
|
|| [k3 isEqualToString:@"title-loc-args"]
|
||||||
} else if ([k3 isEqualToString:@"title-loc-key"]) {
|
|| [k3 isEqualToString:@"title-loc-key"]) {
|
||||||
// TODO: What to do with this?
|
// Ignore known keys
|
||||||
// notif[@"titleLocalizationKey"] = alert[k3];
|
|
||||||
} else {
|
} else {
|
||||||
NSLog(@"Unknown alert key: %@", k2);
|
NSLog(@"Unknown alert key: %@", k2);
|
||||||
}
|
}
|
||||||
|
@ -617,15 +631,13 @@ RCT_EXPORT_METHOD(scheduleNotification:(NSDictionary*) notification
|
||||||
}
|
}
|
||||||
} else if ([k1 isEqualToString:@"gcm.message_id"]) {
|
} else if ([k1 isEqualToString:@"gcm.message_id"]) {
|
||||||
notification[@"notificationId"] = userInfo[k1];
|
notification[@"notificationId"] = userInfo[k1];
|
||||||
} else if ([k1 isEqualToString:@"google.c.a.ts"]) {
|
|
||||||
// TODO: What to do with this?
|
|
||||||
// message[@"sentTime"] = userInfo[k1];
|
|
||||||
} else if ([k1 isEqualToString:@"gcm.n.e"]
|
} else if ([k1 isEqualToString:@"gcm.n.e"]
|
||||||
|| [k1 isEqualToString:@"gcm.notification.sound2"]
|
|| [k1 isEqualToString:@"gcm.notification.sound2"]
|
||||||
|| [k1 isEqualToString:@"google.c.a.c_id"]
|
|| [k1 isEqualToString:@"google.c.a.c_id"]
|
||||||
|| [k1 isEqualToString:@"google.c.a.c_l"]
|
|| [k1 isEqualToString:@"google.c.a.c_l"]
|
||||||
|| [k1 isEqualToString:@"google.c.a.e"]
|
|| [k1 isEqualToString:@"google.c.a.e"]
|
||||||
|| [k1 isEqualToString:@"google.c.a.udt"]) {
|
|| [k1 isEqualToString:@"google.c.a.udt"]
|
||||||
|
|| [k1 isEqualToString:@"google.c.a.ts"]) {
|
||||||
// Ignore known keys
|
// Ignore known keys
|
||||||
} else {
|
} else {
|
||||||
// Assume custom data
|
// Assume custom data
|
||||||
|
@ -633,6 +645,10 @@ RCT_EXPORT_METHOD(scheduleNotification:(NSDictionary*) notification
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ios[@"category"]) {
|
||||||
|
ios[@"category"] = category;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: What to do with this?
|
// TODO: What to do with this?
|
||||||
// message[@"messageType"] = messageType;
|
// message[@"messageType"] = messageType;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,11 @@ import { generatePushID, isObject } from '../../utils';
|
||||||
|
|
||||||
import type { NativeNotification } from './types';
|
import type { NativeNotification } from './types';
|
||||||
|
|
||||||
|
export type NotificationPressed = {
|
||||||
|
action: string,
|
||||||
|
notification: Notification,
|
||||||
|
};
|
||||||
|
|
||||||
export default class Notification {
|
export default class Notification {
|
||||||
// iOS 8/9 | 10+ | Android
|
// iOS 8/9 | 10+ | Android
|
||||||
_android: AndroidNotification;
|
_android: AndroidNotification;
|
||||||
|
|
|
@ -18,7 +18,12 @@ import {
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
import type App from '../core/app';
|
import type App from '../core/app';
|
||||||
import type { NativeNotification, Schedule } from './types';
|
import type { NotificationPressed } from './Notification';
|
||||||
|
import type {
|
||||||
|
NativeNotification,
|
||||||
|
NativeNotificationPressed,
|
||||||
|
Schedule,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
type OnNotification = Notification => any;
|
type OnNotification = Notification => any;
|
||||||
|
|
||||||
|
@ -26,6 +31,12 @@ type OnNotificationObserver = {
|
||||||
next: OnNotification,
|
next: OnNotification,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type OnNotificationPressed = NotificationPressed => any;
|
||||||
|
|
||||||
|
type OnNotificationPressedObserver = {
|
||||||
|
next: OnNotificationPressed,
|
||||||
|
};
|
||||||
|
|
||||||
const NATIVE_EVENTS = [
|
const NATIVE_EVENTS = [
|
||||||
'notifications_notification_displayed',
|
'notifications_notification_displayed',
|
||||||
'notifications_notification_pressed',
|
'notifications_notification_pressed',
|
||||||
|
@ -61,18 +72,6 @@ export default class Notifications extends ModuleBase {
|
||||||
namespace: NAMESPACE,
|
namespace: NAMESPACE,
|
||||||
});
|
});
|
||||||
|
|
||||||
SharedEventEmitter.addListener(
|
|
||||||
// sub to internal native event - this fans out to
|
|
||||||
// public event name: onNotificationPressed
|
|
||||||
'notifications_notification_pressed',
|
|
||||||
(notification: NativeNotification) => {
|
|
||||||
SharedEventEmitter.emit(
|
|
||||||
'onNotificationPressed',
|
|
||||||
new Notification(notification)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
SharedEventEmitter.addListener(
|
SharedEventEmitter.addListener(
|
||||||
// sub to internal native event - this fans out to
|
// sub to internal native event - this fans out to
|
||||||
// public event name: onNotificationDisplayed
|
// public event name: onNotificationDisplayed
|
||||||
|
@ -85,6 +84,18 @@ export default class Notifications extends ModuleBase {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
SharedEventEmitter.addListener(
|
||||||
|
// sub to internal native event - this fans out to
|
||||||
|
// public event name: onNotificationPressed
|
||||||
|
'notifications_notification_pressed',
|
||||||
|
(notificationPressed: NativeNotificationPressed) => {
|
||||||
|
SharedEventEmitter.emit('onNotificationPressed', {
|
||||||
|
action: notificationPressed.action,
|
||||||
|
notification: new Notification(notificationPressed.notification),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
SharedEventEmitter.addListener(
|
SharedEventEmitter.addListener(
|
||||||
// sub to internal native event - this fans out to
|
// sub to internal native event - this fans out to
|
||||||
// public event name: onNotification
|
// public event name: onNotification
|
||||||
|
@ -193,11 +204,10 @@ export default class Notifications extends ModuleBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
onNotificationPressed(
|
onNotificationPressed(
|
||||||
nextOrObserver: OnNotification | OnNotificationObserver
|
nextOrObserver: OnNotificationPressed | OnNotificationPressedObserver
|
||||||
): () => any {
|
): () => any {
|
||||||
let listener: Notification => any;
|
let listener;
|
||||||
if (isFunction(nextOrObserver)) {
|
if (isFunction(nextOrObserver)) {
|
||||||
// $FlowBug: Not coping with the overloaded method signature
|
|
||||||
listener = nextOrObserver;
|
listener = nextOrObserver;
|
||||||
} else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) {
|
} else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) {
|
||||||
listener = nextOrObserver.next;
|
listener = nextOrObserver.next;
|
||||||
|
|
|
@ -160,3 +160,8 @@ export type NativeNotification = {|
|
||||||
subtitle?: string,
|
subtitle?: string,
|
||||||
title: string,
|
title: string,
|
||||||
|};
|
|};
|
||||||
|
|
||||||
|
export type NativeNotificationPressed = {|
|
||||||
|
action: string,
|
||||||
|
notification: NativeNotification,
|
||||||
|
|};
|
||||||
|
|
Loading…
Reference in New Issue