react-native-firebase/lib/modules/notifications/AndroidAction.js

170 lines
4.2 KiB
JavaScript
Raw Normal View History

/**
* @flow
* AndroidAction representation wrapper
*/
import RemoteInput, {
fromNativeAndroidRemoteInput,
} from './AndroidRemoteInput';
import { SemanticAction } from './types';
import type { NativeAndroidAction, SemanticActionType } from './types';
export default class AndroidAction {
_action: string;
_allowGeneratedReplies: boolean | void;
_icon: string;
_remoteInputs: RemoteInput[];
_semanticAction: SemanticActionType | void;
_showUserInterface: boolean | void;
_title: string;
Implement handling of Android actions in background There are some cases when local notification action should be handled in background eg. snoozing the reminder. In case of it launching app UI is not necessary and would be confusing for the end user. Therefore there should be a way to handle local notification action in background. For this reason new property 'runInBackground' was added to the AndroidAction class and TypeScript type. Also new broadcast receiver and service were implemented to handle properly background actions. In order to run particular action in background API consumer need to set its 'runInBackground' property to 'true', eg: ... .android.addAction(new firebase.notifications.Android.Action("snooze", "ic_snooze", "Snooze").setRunInBackground(true)) ... Then, there are two cases that API consumer needs to handle. First when app is in the foreground, standard notification and notification action code path will be executed. This mean, that: * onNotification() listener will be called (which should call displayNotification(), in order to show it to the user), * onNotificationOpen() listener will be called after the action is tapped by the user Secondly, when application is in background or it is not running new 'RNFirebaseBackgroundNotificationAction' handler will be called. To properly handle this case API consumer should create a background asynchronous handler: const handleAsyncTask = async (notificationOpen: NotifficationOpen) => { if (notificationOpen && notificationOpen.notification) { const action = notificationOpen.action; const notificationId = notificationOpen.notification.notificationId; if (action === "snooze") { console.log("Reschedule notification for later time", notificationId); } else { console.log("unsupported action", action); } // hide the notification firebase.notifications().removeDeliveredNotification(notificationId); } } Next hander should be registered to headless handler: AppRegistry.registerHeadlessTask('RNFirebaseBackgroundNotificationAction', () => handleAsyncTask); Finally AndroidManifest.xml file must be modified, to include receiver and service definition: <receiver android:name="io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionReceiver" android:exported="true"> <intent-filter> <action android:name="io.invertase.firebase.notifications.BackgroundAction"/> </intent-filter> </receiver> <service android:name="io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionsService"/> Now when ever 'Snooze' action is pressed it will launch 'handleAsyncTask' function in the background or onNotificationOpen() when app is in foreground. And reschedule the notification for the later time.
2018-05-11 21:09:32 +00:00
_runInBackground: boolean | void;
constructor(action: string, icon: string, title: string) {
this._action = action;
this._icon = icon;
this._remoteInputs = [];
this._title = title;
}
get action(): string {
return this._action;
}
get allowGeneratedReplies(): ?boolean {
return this._allowGeneratedReplies;
}
get icon(): string {
return this._icon;
}
get remoteInputs(): RemoteInput[] {
return this._remoteInputs;
}
get semanticAction(): ?SemanticActionType {
return this._semanticAction;
}
get showUserInterface(): ?boolean {
return this._showUserInterface;
}
get title(): string {
return this._title;
}
Implement handling of Android actions in background There are some cases when local notification action should be handled in background eg. snoozing the reminder. In case of it launching app UI is not necessary and would be confusing for the end user. Therefore there should be a way to handle local notification action in background. For this reason new property 'runInBackground' was added to the AndroidAction class and TypeScript type. Also new broadcast receiver and service were implemented to handle properly background actions. In order to run particular action in background API consumer need to set its 'runInBackground' property to 'true', eg: ... .android.addAction(new firebase.notifications.Android.Action("snooze", "ic_snooze", "Snooze").setRunInBackground(true)) ... Then, there are two cases that API consumer needs to handle. First when app is in the foreground, standard notification and notification action code path will be executed. This mean, that: * onNotification() listener will be called (which should call displayNotification(), in order to show it to the user), * onNotificationOpen() listener will be called after the action is tapped by the user Secondly, when application is in background or it is not running new 'RNFirebaseBackgroundNotificationAction' handler will be called. To properly handle this case API consumer should create a background asynchronous handler: const handleAsyncTask = async (notificationOpen: NotifficationOpen) => { if (notificationOpen && notificationOpen.notification) { const action = notificationOpen.action; const notificationId = notificationOpen.notification.notificationId; if (action === "snooze") { console.log("Reschedule notification for later time", notificationId); } else { console.log("unsupported action", action); } // hide the notification firebase.notifications().removeDeliveredNotification(notificationId); } } Next hander should be registered to headless handler: AppRegistry.registerHeadlessTask('RNFirebaseBackgroundNotificationAction', () => handleAsyncTask); Finally AndroidManifest.xml file must be modified, to include receiver and service definition: <receiver android:name="io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionReceiver" android:exported="true"> <intent-filter> <action android:name="io.invertase.firebase.notifications.BackgroundAction"/> </intent-filter> </receiver> <service android:name="io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionsService"/> Now when ever 'Snooze' action is pressed it will launch 'handleAsyncTask' function in the background or onNotificationOpen() when app is in foreground. And reschedule the notification for the later time.
2018-05-11 21:09:32 +00:00
get runInBackground(): ?boolean {
return this._runInBackground;
}
/**
*
* @param remoteInput
* @returns {AndroidAction}
*/
addRemoteInput(remoteInput: RemoteInput): AndroidAction {
if (!(remoteInput instanceof RemoteInput)) {
throw new Error(
`AndroidAction:addRemoteInput expects an 'RemoteInput' but got type ${typeof remoteInput}`
);
}
this._remoteInputs.push(remoteInput);
return this;
}
/**
*
* @param allowGeneratedReplies
* @returns {AndroidAction}
*/
setAllowGenerateReplies(allowGeneratedReplies: boolean): AndroidAction {
this._allowGeneratedReplies = allowGeneratedReplies;
return this;
}
/**
*
* @param semanticAction
* @returns {AndroidAction}
*/
setSemanticAction(semanticAction: SemanticActionType): AndroidAction {
if (!Object.values(SemanticAction).includes(semanticAction)) {
throw new Error(
`AndroidAction:setSemanticAction Invalid Semantic Action: ${semanticAction}`
);
}
this._semanticAction = semanticAction;
return this;
}
/**
*
* @param showUserInterface
* @returns {AndroidAction}
*/
setShowUserInterface(showUserInterface: boolean): AndroidAction {
this._showUserInterface = showUserInterface;
return this;
}
Implement handling of Android actions in background There are some cases when local notification action should be handled in background eg. snoozing the reminder. In case of it launching app UI is not necessary and would be confusing for the end user. Therefore there should be a way to handle local notification action in background. For this reason new property 'runInBackground' was added to the AndroidAction class and TypeScript type. Also new broadcast receiver and service were implemented to handle properly background actions. In order to run particular action in background API consumer need to set its 'runInBackground' property to 'true', eg: ... .android.addAction(new firebase.notifications.Android.Action("snooze", "ic_snooze", "Snooze").setRunInBackground(true)) ... Then, there are two cases that API consumer needs to handle. First when app is in the foreground, standard notification and notification action code path will be executed. This mean, that: * onNotification() listener will be called (which should call displayNotification(), in order to show it to the user), * onNotificationOpen() listener will be called after the action is tapped by the user Secondly, when application is in background or it is not running new 'RNFirebaseBackgroundNotificationAction' handler will be called. To properly handle this case API consumer should create a background asynchronous handler: const handleAsyncTask = async (notificationOpen: NotifficationOpen) => { if (notificationOpen && notificationOpen.notification) { const action = notificationOpen.action; const notificationId = notificationOpen.notification.notificationId; if (action === "snooze") { console.log("Reschedule notification for later time", notificationId); } else { console.log("unsupported action", action); } // hide the notification firebase.notifications().removeDeliveredNotification(notificationId); } } Next hander should be registered to headless handler: AppRegistry.registerHeadlessTask('RNFirebaseBackgroundNotificationAction', () => handleAsyncTask); Finally AndroidManifest.xml file must be modified, to include receiver and service definition: <receiver android:name="io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionReceiver" android:exported="true"> <intent-filter> <action android:name="io.invertase.firebase.notifications.BackgroundAction"/> </intent-filter> </receiver> <service android:name="io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionsService"/> Now when ever 'Snooze' action is pressed it will launch 'handleAsyncTask' function in the background or onNotificationOpen() when app is in foreground. And reschedule the notification for the later time.
2018-05-11 21:09:32 +00:00
/**
*
* @param runInBackground
* @returns {AndroidAction}
*/
setRunInBackground(runInBackground: boolean): AndroidAction {
this._runInBackground = runInBackground
return this;
}
build(): NativeAndroidAction {
if (!this._action) {
throw new Error('AndroidAction: Missing required `action` property');
} else if (!this._icon) {
throw new Error('AndroidAction: Missing required `icon` property');
} else if (!this._title) {
throw new Error('AndroidAction: Missing required `title` property');
}
return {
action: this._action,
allowGeneratedReplies: this._allowGeneratedReplies,
icon: this._icon,
remoteInputs: this._remoteInputs.map(remoteInput => remoteInput.build()),
semanticAction: this._semanticAction,
showUserInterface: this._showUserInterface,
title: this._title,
Implement handling of Android actions in background There are some cases when local notification action should be handled in background eg. snoozing the reminder. In case of it launching app UI is not necessary and would be confusing for the end user. Therefore there should be a way to handle local notification action in background. For this reason new property 'runInBackground' was added to the AndroidAction class and TypeScript type. Also new broadcast receiver and service were implemented to handle properly background actions. In order to run particular action in background API consumer need to set its 'runInBackground' property to 'true', eg: ... .android.addAction(new firebase.notifications.Android.Action("snooze", "ic_snooze", "Snooze").setRunInBackground(true)) ... Then, there are two cases that API consumer needs to handle. First when app is in the foreground, standard notification and notification action code path will be executed. This mean, that: * onNotification() listener will be called (which should call displayNotification(), in order to show it to the user), * onNotificationOpen() listener will be called after the action is tapped by the user Secondly, when application is in background or it is not running new 'RNFirebaseBackgroundNotificationAction' handler will be called. To properly handle this case API consumer should create a background asynchronous handler: const handleAsyncTask = async (notificationOpen: NotifficationOpen) => { if (notificationOpen && notificationOpen.notification) { const action = notificationOpen.action; const notificationId = notificationOpen.notification.notificationId; if (action === "snooze") { console.log("Reschedule notification for later time", notificationId); } else { console.log("unsupported action", action); } // hide the notification firebase.notifications().removeDeliveredNotification(notificationId); } } Next hander should be registered to headless handler: AppRegistry.registerHeadlessTask('RNFirebaseBackgroundNotificationAction', () => handleAsyncTask); Finally AndroidManifest.xml file must be modified, to include receiver and service definition: <receiver android:name="io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionReceiver" android:exported="true"> <intent-filter> <action android:name="io.invertase.firebase.notifications.BackgroundAction"/> </intent-filter> </receiver> <service android:name="io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionsService"/> Now when ever 'Snooze' action is pressed it will launch 'handleAsyncTask' function in the background or onNotificationOpen() when app is in foreground. And reschedule the notification for the later time.
2018-05-11 21:09:32 +00:00
runInBackground: this._runInBackground
};
}
}
export const fromNativeAndroidAction = (
nativeAction: NativeAndroidAction
): AndroidAction => {
const action = new AndroidAction(
nativeAction.action,
nativeAction.icon,
nativeAction.title
);
if (nativeAction.allowGeneratedReplies) {
action.setAllowGenerateReplies(nativeAction.allowGeneratedReplies);
}
if (nativeAction.remoteInputs) {
nativeAction.remoteInputs.forEach(remoteInput => {
action.addRemoteInput(fromNativeAndroidRemoteInput(remoteInput));
});
}
if (nativeAction.semanticAction) {
action.setSemanticAction(nativeAction.semanticAction);
}
if (nativeAction.showUserInterface) {
action.setShowUserInterface(nativeAction.showUserInterface);
}
Implement handling of Android actions in background There are some cases when local notification action should be handled in background eg. snoozing the reminder. In case of it launching app UI is not necessary and would be confusing for the end user. Therefore there should be a way to handle local notification action in background. For this reason new property 'runInBackground' was added to the AndroidAction class and TypeScript type. Also new broadcast receiver and service were implemented to handle properly background actions. In order to run particular action in background API consumer need to set its 'runInBackground' property to 'true', eg: ... .android.addAction(new firebase.notifications.Android.Action("snooze", "ic_snooze", "Snooze").setRunInBackground(true)) ... Then, there are two cases that API consumer needs to handle. First when app is in the foreground, standard notification and notification action code path will be executed. This mean, that: * onNotification() listener will be called (which should call displayNotification(), in order to show it to the user), * onNotificationOpen() listener will be called after the action is tapped by the user Secondly, when application is in background or it is not running new 'RNFirebaseBackgroundNotificationAction' handler will be called. To properly handle this case API consumer should create a background asynchronous handler: const handleAsyncTask = async (notificationOpen: NotifficationOpen) => { if (notificationOpen && notificationOpen.notification) { const action = notificationOpen.action; const notificationId = notificationOpen.notification.notificationId; if (action === "snooze") { console.log("Reschedule notification for later time", notificationId); } else { console.log("unsupported action", action); } // hide the notification firebase.notifications().removeDeliveredNotification(notificationId); } } Next hander should be registered to headless handler: AppRegistry.registerHeadlessTask('RNFirebaseBackgroundNotificationAction', () => handleAsyncTask); Finally AndroidManifest.xml file must be modified, to include receiver and service definition: <receiver android:name="io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionReceiver" android:exported="true"> <intent-filter> <action android:name="io.invertase.firebase.notifications.BackgroundAction"/> </intent-filter> </receiver> <service android:name="io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionsService"/> Now when ever 'Snooze' action is pressed it will launch 'handleAsyncTask' function in the background or onNotificationOpen() when app is in foreground. And reschedule the notification for the later time.
2018-05-11 21:09:32 +00:00
if (nativeAction.runInBackground) {
action.setRunInBackground(nativeAction.runInBackground);
}
return action;
};