import { Platform } from 'react-native'; import ModuleBase from './../../utils/ModuleBase'; import RemoteMessage from './RemoteMessage'; const EVENT_TYPE = { RefreshToken: 'messaging_token_refreshed', Notification: 'messaging_notification_received', }; const NOTIFICATION_TYPE = { Remote: 'remote_notification', NotificationResponse: 'notification_response', WillPresent: 'will_present_notification', Local: 'local_notification', }; const REMOTE_NOTIFICATION_RESULT = { NewData: 'UIBackgroundFetchResultNewData', NoData: 'UIBackgroundFetchResultNoData', ResultFailed: 'UIBackgroundFetchResultFailed', }; const WILL_PRESENT_RESULT = { All: 'UNNotificationPresentationOptionAll', None: 'UNNotificationPresentationOptionNone', }; /** * IOS only finish function * @param data */ function finish(data) { if (Platform.OS !== 'ios') { return; } if (!this._finishCalled && this._completionHandlerId) { let result = data; this._finishCalled = true; switch (this._notificationType) { case NOTIFICATION_TYPE.Remote: result = result || REMOTE_NOTIFICATION_RESULT.NoData; if (!Object.values(REMOTE_NOTIFICATION_RESULT).includes(result)) { throw new Error('Invalid REMOTE_NOTIFICATION_RESULT value, use messaging().REMOTE_NOTIFICATION_RESULT'); } FirebaseMessaging.finishRemoteNotification(this._completionHandlerId, result); return; case NOTIFICATION_TYPE.NotificationResponse: FirebaseMessaging.finishNotificationResponse(this._completionHandlerId); return; case NOTIFICATION_TYPE.WillPresent: result = result || (this.show_in_foreground ? WILL_PRESENT_RESULT.All : WILL_PRESENT_RESULT.None); if (!Object.values(WILL_PRESENT_RESULT).includes(result)) { throw new Error('Invalid WILL_PRESENT_RESULT value, use messaging().WILL_PRESENT_RESULT'); } FirebaseMessaging.finishWillPresentNotification(this._completionHandlerId, result); break; default: } } } /** * @class Messaging */ export default class Messaging extends ModuleBase { static _NAMESPACE = 'messaging'; static _NATIVE_MODULE = 'RNFirebaseMessaging'; constructor(firebaseApp: Object, options: Object = {}) { super(firebaseApp, options, true); } get EVENT_TYPE() { return EVENT_TYPE; } get NOTIFICATION_TYPE() { return NOTIFICATION_TYPE; } get REMOTE_NOTIFICATION_RESULT() { return REMOTE_NOTIFICATION_RESULT; } get WILL_PRESENT_RESULT() { return WILL_PRESENT_RESULT; } /** * Returns the notification that triggered application open * @returns {*} */ getInitialNotification() { return this._native.getInitialNotification(); } /** * Returns the fcm token for the current device * @returns {*|Promise.} */ getToken() { return this._native.getToken(); } /** * Create and display a local notification * @param notification * @returns {*} */ createLocalNotification(notification: Object) { const _notification = Object.assign({}, notification); _notification.id = _notification.id || new Date().getTime().toString(); _notification.local_notification = true; return this._native.createLocalNotification(_notification); } /** * * @param notification * @returns {*} */ scheduleLocalNotification(notification: Object) { const _notification = Object.assign({}, notification); if (!notification.id) return Promise.reject(new Error('An id is required to schedule a local notification.')); _notification.local_notification = true; return this._native.scheduleLocalNotification(_notification); } /** * Returns an array of all scheduled notifications * @returns {Promise.} */ getScheduledLocalNotifications() { return this._native.getScheduledLocalNotifications(); } /** * Cancel a local notification by id - using '*' will cancel * all local notifications. * @param id * @returns {*} */ cancelLocalNotification(id: string) { if (!id) return null; if (id === '*') return this._native.cancelAllLocalNotifications(); return this._native.cancelLocalNotification(id); } /** * Remove a delivered notification - using '*' will remove * all delivered notifications. * @param id * @returns {*} */ removeDeliveredNotification(id: string) { if (!id) return null; if (id === '*') return this._native.removeAllDeliveredNotifications(); return this._native.removeDeliveredNotification(id); } /** * Request notification permission * @platforms ios * @returns {*|Promise.<*>} */ requestPermissions() { return this._native.requestPermissions(); } /** * Set notification count badge number * @param n */ setBadgeNumber(n: number) { this._native.setBadgeNumber(n); } /** * set notification count badge number * @returns {Promise.} */ getBadgeNumber() { return this._native.getBadgeNumber(); } /** * Subscribe to messages / notifications * @param listener * @returns {*} */ onMessage(listener: Function): () => any { const rnListener = this._eventEmitter.addListener( EVENT_TYPE.Notification, async (event) => { const data = { ...event, finish, }; await listener(data); if (!data._finishCalled) { data.finish(); } }, ); return () => rnListener.remove(); } /** * Subscribe to token refresh events * @param listener * @returns {*} */ onTokenRefresh(listener: Function): () => any { const rnListener = this._eventEmitter.addListener(EVENT_TYPE.RefreshToken, listener); return () => rnListener.remove(); } /** * Subscribe to a topic * @param topic */ subscribeToTopic(topic: String) { this._native.subscribeToTopic(topic); } /** * Unsubscribe from a topic * @param topic */ unsubscribeFromTopic(topic: String) { this._native.unsubscribeFromTopic(topic); } /** * Send an upstream message * @param remoteMessage */ send(remoteMessage: RemoteMessage) { if (!(remoteMessage instanceof RemoteMessage)) { throw new Error('messaging().send requires an instance of RemoteMessage as the first argument.'); } return this._native.send(remoteMessage.toJSON()); } } export const statics = { EVENT_TYPE, NOTIFICATION_TYPE, REMOTE_NOTIFICATION_RESULT, WILL_PRESENT_RESULT, RemoteMessage, };