react-native-firebase/lib/modules/messaging/index.js

194 lines
5.0 KiB
JavaScript
Raw Normal View History

/**
* @flow
* Messaging (FCM) representation wrapper
*/
import { Platform } from 'react-native';
import { SharedEventEmitter } from '../../utils/events';
import INTERNALS from '../../utils/internals';
import { getLogger } from '../../utils/log';
import ModuleBase from '../../utils/ModuleBase';
import { getNativeModule } from '../../utils/native';
import { isFunction, isObject } from '../../utils';
import RemoteMessage from './RemoteMessage';
2017-03-02 12:58:15 +00:00
import type App from '../core/app';
2018-02-23 16:11:59 +00:00
import type { NativeInboundRemoteMessage } from './types';
2018-02-23 16:11:59 +00:00
type OnMessage = RemoteMessage => any;
type OnMessageObserver = {
next: OnMessage,
};
2017-03-02 12:58:15 +00:00
2018-04-19 15:01:40 +00:00
type OnTokenRefresh = string => any;
type OnTokenRefreshObserver = {
next: OnTokenRefresh,
};
2017-10-03 08:49:46 +00:00
const NATIVE_EVENTS = [
'messaging_message_received',
'messaging_token_refreshed',
];
export const MODULE_NAME = 'RNFirebaseMessaging';
export const NAMESPACE = 'messaging';
2017-03-02 12:58:15 +00:00
/**
* @class Messaging
*/
export default class Messaging extends ModuleBase {
constructor(app: App) {
super(app, {
events: NATIVE_EVENTS,
moduleName: MODULE_NAME,
multiApp: false,
hasShards: false,
namespace: NAMESPACE,
});
2017-03-02 12:58:15 +00:00
SharedEventEmitter.addListener(
// sub to internal native event - this fans out to
// public event name: onMessage
'messaging_message_received',
2018-02-23 16:11:59 +00:00
(message: NativeInboundRemoteMessage) => {
SharedEventEmitter.emit('onMessage', new RemoteMessage(message));
}
);
2017-03-02 12:58:15 +00:00
SharedEventEmitter.addListener(
// sub to internal native event - this fans out to
// public event name: onMessage
'messaging_token_refreshed',
(token: string) => {
SharedEventEmitter.emit('onTokenRefresh', token);
}
);
// Tell the native module that we're ready to receive events
if (Platform.OS === 'ios') {
getNativeModule(this).jsInitialised();
}
2017-03-02 12:58:15 +00:00
}
getToken(): Promise<string> {
return getNativeModule(this).getToken();
2017-03-02 12:58:15 +00:00
}
onMessage(nextOrObserver: OnMessage | OnMessageObserver): () => any {
2018-02-23 16:11:59 +00:00
let listener: RemoteMessage => any;
if (isFunction(nextOrObserver)) {
// $FlowExpectedError: Not coping with the overloaded method signature
listener = nextOrObserver;
} else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) {
listener = nextOrObserver.next;
} else {
throw new Error(
'Messaging.onMessage failed: First argument must be a function or observer object with a `next` function.'
2018-01-25 18:25:39 +00:00
);
}
2017-03-02 12:58:15 +00:00
getLogger(this).info('Creating onMessage listener');
2018-02-08 17:07:20 +00:00
2018-02-23 16:11:59 +00:00
SharedEventEmitter.addListener('onMessage', listener);
return () => {
getLogger(this).info('Removing onMessage listener');
2018-02-23 16:11:59 +00:00
SharedEventEmitter.removeListener('onMessage', listener);
};
}
onTokenRefresh(
nextOrObserver: OnTokenRefresh | OnTokenRefreshObserver
): () => any {
2018-04-19 15:01:40 +00:00
let listener: string => any;
if (isFunction(nextOrObserver)) {
// $FlowExpectedError: Not coping with the overloaded method signature
listener = nextOrObserver;
} else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) {
listener = nextOrObserver.next;
} else {
throw new Error(
'Messaging.OnTokenRefresh failed: First argument must be a function or observer object with a `next` function.'
);
}
2017-03-02 12:58:15 +00:00
getLogger(this).info('Creating onTokenRefresh listener');
SharedEventEmitter.addListener('onTokenRefresh', listener);
2017-03-02 12:58:15 +00:00
return () => {
getLogger(this).info('Removing onTokenRefresh listener');
SharedEventEmitter.removeListener('onTokenRefresh', listener);
};
2017-03-02 12:58:15 +00:00
}
requestPermission(): Promise<void> {
return getNativeModule(this).requestPermission();
2017-03-21 11:26:16 +00:00
}
/**
* NON WEB-SDK METHODS
*/
2018-02-05 18:04:10 +00:00
hasPermission(): Promise<boolean> {
return getNativeModule(this).hasPermission();
}
2017-03-02 12:58:15 +00:00
sendMessage(remoteMessage: RemoteMessage): Promise<void> {
if (!(remoteMessage instanceof RemoteMessage)) {
2018-03-23 17:03:53 +00:00
return Promise.reject(
new Error(
`Messaging:sendMessage expects a 'RemoteMessage' but got type ${typeof remoteMessage}`
)
);
}
2018-03-23 17:03:53 +00:00
try {
return getNativeModule(this).sendMessage(remoteMessage.build());
} catch (error) {
return Promise.reject(error);
}
}
subscribeToTopic(topic: string): Promise<void> {
return getNativeModule(this).subscribeToTopic(topic);
}
unsubscribeFromTopic(topic: string): Promise<void> {
return getNativeModule(this).unsubscribeFromTopic(topic);
2017-03-02 12:58:15 +00:00
}
/**
* KNOWN UNSUPPORTED METHODS
*/
deleteToken() {
throw new Error(
INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(
'messaging',
'deleteToken'
)
);
}
setBackgroundMessageHandler() {
throw new Error(
INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(
'messaging',
'setBackgroundMessageHandler'
)
);
}
useServiceWorker() {
throw new Error(
INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(
'messaging',
'useServiceWorker'
)
);
}
2017-03-02 12:58:15 +00:00
}
export const statics = {
RemoteMessage,
};