2017-05-30 07:26:40 +00:00
|
|
|
import { NativeEventEmitter, NativeModules, Platform } from 'react-native';
|
2017-03-02 12:58:15 +00:00
|
|
|
import { Base } from './../base';
|
2017-05-25 22:39:06 +00:00
|
|
|
import { nativeSDKMissing } from './../../utils';
|
2017-03-30 15:25:27 +00:00
|
|
|
import RemoteMessage from './RemoteMessage';
|
2017-03-02 12:58:15 +00:00
|
|
|
|
|
|
|
const FirebaseMessaging = NativeModules.RNFirebaseMessaging;
|
2017-05-31 14:22:15 +00:00
|
|
|
const FirebaseMessagingEvt = FirebaseMessaging && new NativeEventEmitter(FirebaseMessaging);
|
2017-03-17 16:04:39 +00:00
|
|
|
|
2017-03-30 15:25:27 +00:00
|
|
|
const EVENT_TYPE = {
|
2017-05-30 07:26:40 +00:00
|
|
|
RefreshToken: 'messaging_token_refreshed',
|
|
|
|
Notification: 'messaging_notification_received',
|
2017-03-17 16:04:39 +00:00
|
|
|
};
|
|
|
|
|
2017-03-30 15:25:27 +00:00
|
|
|
const NOTIFICATION_TYPE = {
|
2017-03-17 16:04:39 +00:00
|
|
|
Remote: 'remote_notification',
|
|
|
|
NotificationResponse: 'notification_response',
|
|
|
|
WillPresent: 'will_present_notification',
|
|
|
|
Local: 'local_notification',
|
|
|
|
};
|
|
|
|
|
2017-03-30 15:25:27 +00:00
|
|
|
const REMOTE_NOTIFICATION_RESULT = {
|
2017-03-17 16:04:39 +00:00
|
|
|
NewData: 'UIBackgroundFetchResultNewData',
|
|
|
|
NoData: 'UIBackgroundFetchResultNoData',
|
|
|
|
ResultFailed: 'UIBackgroundFetchResultFailed',
|
|
|
|
};
|
|
|
|
|
2017-03-30 15:25:27 +00:00
|
|
|
const WILL_PRESENT_RESULT = {
|
2017-03-17 16:04:39 +00:00
|
|
|
All: 'UNNotificationPresentationOptionAll',
|
|
|
|
None: 'UNNotificationPresentationOptionNone',
|
|
|
|
};
|
2017-03-02 12:58:15 +00:00
|
|
|
|
2017-03-17 16:04:39 +00:00
|
|
|
/**
|
|
|
|
* IOS only finish function
|
|
|
|
* @param data
|
|
|
|
*/
|
|
|
|
function finish(data) {
|
|
|
|
if (Platform.OS !== 'ios') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!this._finishCalled && this._completionHandlerId) {
|
2017-03-27 12:26:26 +00:00
|
|
|
let result = data;
|
2017-03-17 16:04:39 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
return;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-02 12:58:15 +00:00
|
|
|
/**
|
|
|
|
* @class Messaging
|
|
|
|
*/
|
|
|
|
export default class Messaging extends Base {
|
|
|
|
constructor(firebase, options = {}) {
|
|
|
|
super(firebase, options);
|
2017-05-31 14:22:15 +00:00
|
|
|
if (!FirebaseMessaging) {
|
2017-05-25 22:39:06 +00:00
|
|
|
return nativeSDKMissing('messaging');
|
|
|
|
}
|
|
|
|
|
2017-03-02 12:58:15 +00:00
|
|
|
this.namespace = 'firebase:messaging';
|
|
|
|
}
|
|
|
|
|
2017-03-17 16:04:39 +00:00
|
|
|
get EVENT_TYPE() {
|
|
|
|
return EVENT_TYPE;
|
|
|
|
}
|
|
|
|
|
|
|
|
get NOTIFICATION_TYPE() {
|
|
|
|
return NOTIFICATION_TYPE;
|
|
|
|
}
|
|
|
|
|
|
|
|
get REMOTE_NOTIFICATION_RESULT() {
|
|
|
|
return REMOTE_NOTIFICATION_RESULT;
|
2017-03-02 12:58:15 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 16:04:39 +00:00
|
|
|
get WILL_PRESENT_RESULT() {
|
|
|
|
return WILL_PRESENT_RESULT;
|
2017-03-02 12:58:15 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 16:04:39 +00:00
|
|
|
/**
|
|
|
|
* Returns the notification that triggered application open
|
|
|
|
* @returns {*}
|
|
|
|
*/
|
|
|
|
getInitialNotification() {
|
|
|
|
return FirebaseMessaging.getInitialNotification();
|
2017-03-02 12:58:15 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 16:04:39 +00:00
|
|
|
/**
|
|
|
|
* Returns the fcm token for the current device
|
|
|
|
* @returns {*|Promise.<String>}
|
|
|
|
*/
|
2017-03-02 12:58:15 +00:00
|
|
|
getToken() {
|
2017-03-15 12:57:36 +00:00
|
|
|
return FirebaseMessaging.getToken();
|
2017-03-02 12:58:15 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 16:04:39 +00:00
|
|
|
/**
|
|
|
|
* 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 FirebaseMessaging.createLocalNotification(_notification);
|
2017-03-02 12:58:15 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 16:04:39 +00:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @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 FirebaseMessaging.scheduleLocalNotification(_notification);
|
2017-03-02 12:58:15 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 16:04:39 +00:00
|
|
|
/**
|
|
|
|
* Returns an array of all scheduled notifications
|
|
|
|
* @returns {Promise.<Array>}
|
|
|
|
*/
|
|
|
|
getScheduledLocalNotifications() {
|
|
|
|
return FirebaseMessaging.getScheduledLocalNotifications();
|
2017-03-02 12:58:15 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 16:04:39 +00:00
|
|
|
/**
|
|
|
|
* 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 FirebaseMessaging.cancelAllLocalNotifications();
|
|
|
|
return FirebaseMessaging.cancelLocalNotification(id);
|
2017-03-02 12:58:15 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 16:04:39 +00:00
|
|
|
/**
|
|
|
|
* Remove a delivered notification - using '*' will remove
|
|
|
|
* all delivered notifications.
|
|
|
|
* @param id
|
|
|
|
* @returns {*}
|
|
|
|
*/
|
|
|
|
removeDeliveredNotification(id: string) {
|
|
|
|
if (!id) return null;
|
|
|
|
if (id === '*') return FirebaseMessaging.removeAllDeliveredNotifications();
|
|
|
|
return FirebaseMessaging.removeDeliveredNotification(id);
|
2017-03-02 12:58:15 +00:00
|
|
|
}
|
|
|
|
|
2017-03-21 11:26:16 +00:00
|
|
|
/**
|
|
|
|
* Request notification permission
|
|
|
|
* @platforms ios
|
|
|
|
* @returns {*|Promise.<*>}
|
|
|
|
*/
|
|
|
|
requestPermissions() {
|
|
|
|
return FirebaseMessaging.requestPermissions();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-03-17 16:04:39 +00:00
|
|
|
/**
|
|
|
|
* Set notification count badge number
|
2017-03-21 11:26:16 +00:00
|
|
|
* @param n
|
2017-03-17 16:04:39 +00:00
|
|
|
*/
|
2017-03-21 11:26:16 +00:00
|
|
|
setBadgeNumber(n: number) {
|
|
|
|
FirebaseMessaging.setBadgeNumber(n);
|
2017-03-02 12:58:15 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 16:04:39 +00:00
|
|
|
/**
|
|
|
|
* set notification count badge number
|
|
|
|
* @returns {Promise.<Number>}
|
|
|
|
*/
|
|
|
|
getBadgeNumber() {
|
|
|
|
return FirebaseMessaging.getBadgeNumber();
|
2017-03-02 12:58:15 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 16:04:39 +00:00
|
|
|
/**
|
|
|
|
* Subscribe to messages / notifications
|
|
|
|
* @param listener
|
|
|
|
* @returns {*}
|
|
|
|
*/
|
2017-06-19 11:25:58 +00:00
|
|
|
onMessage(listener: Function): () => any {
|
2017-06-19 12:14:36 +00:00
|
|
|
const rnListener = FirebaseMessagingEvt.addListener(
|
2017-05-30 07:26:40 +00:00
|
|
|
EVENT_TYPE.Notification,
|
|
|
|
async(event) => {
|
|
|
|
const data = {
|
|
|
|
...event,
|
|
|
|
finish,
|
|
|
|
};
|
|
|
|
await listener(data);
|
|
|
|
|
|
|
|
if (!data._finishCalled) {
|
|
|
|
data.finish();
|
|
|
|
}
|
2017-03-17 16:04:39 +00:00
|
|
|
}
|
2017-06-19 12:14:36 +00:00
|
|
|
);
|
|
|
|
return () => rnListener.remove();
|
2017-03-17 16:04:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Subscribe to token refresh events
|
|
|
|
* @param listener
|
|
|
|
* @returns {*}
|
|
|
|
*/
|
2017-06-19 11:25:58 +00:00
|
|
|
onTokenRefresh(listener: Function): () => any {
|
2017-06-19 12:14:36 +00:00
|
|
|
const rnListener = FirebaseMessagingEvt.addListener(EVENT_TYPE.RefreshToken, listener);
|
|
|
|
return () => rnListener.remove();
|
2017-03-02 12:58:15 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 16:04:39 +00:00
|
|
|
/**
|
|
|
|
* Subscribe to a topic
|
|
|
|
* @param topic
|
|
|
|
*/
|
|
|
|
subscribeToTopic(topic: String) {
|
|
|
|
FirebaseMessaging.subscribeToTopic(topic);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unsubscribe from a topic
|
|
|
|
* @param topic
|
|
|
|
*/
|
|
|
|
unsubscribeFromTopic(topic: String) {
|
|
|
|
FirebaseMessaging.unsubscribeFromTopic(topic);
|
2017-03-02 12:58:15 +00:00
|
|
|
}
|
2017-03-21 15:11:07 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Send an upstream message
|
2017-03-30 15:25:27 +00:00
|
|
|
* @param remoteMessage
|
2017-03-21 15:11:07 +00:00
|
|
|
*/
|
2017-03-30 15:25:27 +00:00
|
|
|
send(remoteMessage: RemoteMessage) {
|
|
|
|
if (!(remoteMessage instanceof RemoteMessage)) {
|
|
|
|
throw new Error('messaging().send requires an instance of RemoteMessage as the first argument.');
|
|
|
|
}
|
|
|
|
|
|
|
|
return FirebaseMessaging.send(remoteMessage.toJSON());
|
2017-03-21 15:11:07 +00:00
|
|
|
}
|
2017-03-02 12:58:15 +00:00
|
|
|
}
|
2017-03-30 15:25:27 +00:00
|
|
|
|
|
|
|
export const statics = {
|
|
|
|
EVENT_TYPE,
|
|
|
|
NOTIFICATION_TYPE,
|
|
|
|
REMOTE_NOTIFICATION_RESULT,
|
|
|
|
WILL_PRESENT_RESULT,
|
|
|
|
RemoteMessage,
|
|
|
|
};
|