[fcm] First steps towards identifying the new API for messaging / notifications

This commit is contained in:
Chris Bianca
2018-01-30 11:15:59 +00:00
parent 09fa3b9e31
commit d429db7e86
11 changed files with 535 additions and 2 deletions

View File

@@ -20,6 +20,9 @@ import Database, { NAMESPACE as DatabaseNamespace } from '../database';
import Firestore, { NAMESPACE as FirestoreNamespace } from '../firestore';
import Links, { NAMESPACE as LinksNamespace } from '../links';
import Messaging, { NAMESPACE as MessagingNamespace } from '../messaging';
import NewMessaging, {
NAMESPACE as NewMessagingNamespace,
} from '../messaging/messagingIndex';
import Performance, { NAMESPACE as PerfNamespace } from '../perf';
import Storage, { NAMESPACE as StorageNamespace } from '../storage';
import Utils, { NAMESPACE as UtilsNamespace } from '../utils';
@@ -46,6 +49,7 @@ export default class App {
firestore: () => Firestore;
links: () => Links;
messaging: () => Messaging;
newmessaging: () => NewMessaging;
perf: () => Performance;
storage: () => Storage;
utils: () => Utils;
@@ -85,6 +89,11 @@ export default class App {
this.firestore = APPS.appModule(this, FirestoreNamespace, Firestore);
this.links = APPS.appModule(this, LinksNamespace, Links);
this.messaging = APPS.appModule(this, MessagingNamespace, Messaging);
this.newmessaging = APPS.appModule(
this,
NewMessagingNamespace,
NewMessaging
);
this.perf = APPS.appModule(this, PerfNamespace, Performance);
this.storage = APPS.appModule(this, StorageNamespace, Storage);
this.utils = APPS.appModule(this, UtilsNamespace, Utils);

View File

@@ -47,6 +47,10 @@ import {
statics as MessagingStatics,
MODULE_NAME as MessagingModuleName,
} from '../messaging';
import {
statics as NewMessagingStatics,
MODULE_NAME as NewMessagingModuleName,
} from '../messaging/messagingIndex';
import {
statics as PerformanceStatics,
MODULE_NAME as PerfModuleName,
@@ -72,6 +76,7 @@ import type {
FirestoreModule,
LinksModule,
MessagingModule,
NewMessagingModule,
PerformanceModule,
StorageModule,
UtilsModule,
@@ -90,6 +95,7 @@ class Firebase {
firestore: FirestoreModule;
links: LinksModule;
messaging: MessagingModule;
newmessaging: NewMessagingModule;
perf: PerformanceModule;
storage: StorageModule;
utils: UtilsModule;
@@ -137,6 +143,11 @@ class Firebase {
MessagingStatics,
MessagingModuleName
);
this.newmessaging = APPS.moduleAndStatics(
'newmessaging',
NewMessagingStatics,
NewMessagingModuleName
);
this.perf = APPS.moduleAndStatics(
'perf',
PerformanceStatics,

View File

@@ -0,0 +1,186 @@
/**
* @flow
* Messaging (FCM) representation wrapper
*/
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 type App from '../core/firebase-app';
type Message = {
// TODO
};
type OnMessage = Message => any;
type OnMessageObserver = {
next: OnMessage,
};
type OnTokenRefresh = String => any;
type OnTokenRefreshObserver = {
next: OnTokenRefresh,
};
type RemoteMessage = {
// TODO
};
const NATIVE_EVENTS = [
'messaging_message_received',
'messaging_token_refreshed',
];
export const MODULE_NAME = 'NewRNFirebaseMessaging';
export const NAMESPACE = 'newmessaging';
/**
* @class Messaging
*/
export default class Messaging extends ModuleBase {
constructor(app: App) {
super(app, {
events: NATIVE_EVENTS,
moduleName: MODULE_NAME,
multiApp: false,
namespace: NAMESPACE,
});
SharedEventEmitter.addListener(
// sub to internal native event - this fans out to
// public event name: onMessage
'messaging_message_received',
(message: Message) => {
SharedEventEmitter.emit('onMessage', message);
}
);
SharedEventEmitter.addListener(
// sub to internal native event - this fans out to
// public event name: onMessage
'messaging_token_refreshed',
(token: string) => {
SharedEventEmitter.emit('onTokenRefresh', token);
}
);
}
deleteToken(token: string): Promise<void> {
return getNativeModule(this).deleteToken(token);
}
getToken(): Promise<string> {
return getNativeModule(this).getToken();
}
onMessage(nextOrObserver: OnMessage | OnMessageObserver): () => any {
let listener;
if (isFunction(nextOrObserver)) {
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.'
);
}
// TODO: iOS finish
getLogger(this).info('Creating onMessage listener');
SharedEventEmitter.addListener('onMessage', listener);
return () => {
getLogger(this).info('Removing onMessage listener');
SharedEventEmitter.removeListener('onMessage', listener);
};
}
onTokenRefresh(
nextOrObserver: OnTokenRefresh | OnTokenRefreshObserver
): () => any {
let listener;
if (isFunction(nextOrObserver)) {
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.'
);
}
getLogger(this).info('Creating onTokenRefresh listener');
SharedEventEmitter.addListener('onTokenRefresh', listener);
return () => {
getLogger(this).info('Removing onTokenRefresh listener');
SharedEventEmitter.removeListener('onTokenRefresh', listener);
};
}
requestPermission(): Promise<void> {
return getNativeModule(this).requestPermission();
}
/**
* NON WEB-SDK METHODS
*/
deleteInstanceId(): Promise<void> {
return getNativeModule(this).deleteInstanceId();
}
getBadgeNumber(): Promise<number> {
return getNativeModule(this).getBadgeNumber();
}
getInitialMessage(): Promise<Message> {
return getNativeModule(this).getInitialMessage();
}
sendMessage(remoteMessage: RemoteMessage): Promise<void> {
return getNativeModule(this).send(remoteMessage);
}
setBadgeNumber(badge: number): void {
getNativeModule(this).setBadgeNumber(badge);
}
subscribeToTopic(topic: string): void {
getNativeModule(this).subscribeToTopic(topic);
}
unsubscribeFromTopic(topic: string): void {
getNativeModule(this).unsubscribeFromTopic(topic);
}
/**
* KNOWN UNSUPPORTED METHODS
*/
setBackgroundMessageHandler() {
throw new Error(
INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(
'messaging',
'setBackgroundMessageHandler'
)
);
}
useServiceWorker() {
throw new Error(
INTERNALS.STRINGS.ERROR_UNSUPPORTED_MODULE_METHOD(
'messaging',
'useServiceWorker'
)
);
}
}
export const statics = {
// RemoteMessage,
};

View File

@@ -0,0 +1,138 @@
/**
* @flow
* Messaging (FCM) representation wrapper
*/
import { SharedEventEmitter } from '../../utils/events';
import { getLogger } from '../../utils/log';
import ModuleBase from '../../utils/ModuleBase';
import { getNativeModule } from '../../utils/native';
import { isFunction, isObject } from '../../utils';
import type App from '../core/firebase-app';
type CreateNotification = {
// TODO
};
type Notification = {
// TODO
};
type OnNotification = Notification => any;
type OnNotificationObserver = {
next: OnNotification,
};
const NATIVE_EVENTS = ['notifications_notification_received'];
export const MODULE_NAME = 'RNFirebaseNotifications';
export const NAMESPACE = 'notifications';
/**
* @class Notifications
*/
export default class Notifications extends ModuleBase {
constructor(app: App) {
super(app, {
events: NATIVE_EVENTS,
moduleName: MODULE_NAME,
multiApp: false,
namespace: NAMESPACE,
});
SharedEventEmitter.addListener(
// sub to internal native event - this fans out to
// public event name: onMessage
'notifications_notification_received',
(notification: Notification) => {
SharedEventEmitter.emit('onNotification', notification);
}
);
}
/**
* Cancel a local notification by id - using '*' will cancel
* all local notifications.
* @param id
* @returns {*}
*/
cancelNotification(id: string): Promise<void> {
if (!id) return Promise.reject(new Error('Missing notification id'));
if (id === '*') return getNativeModule(this).cancelAllLocalNotifications();
return getNativeModule(this).cancelLocalNotification(id);
}
/**
* Create and display a local notification
* @param notification
* @returns {*}
*/
createNotification(notification: CreateNotification): Promise<void> {
const _notification = Object.assign({}, notification);
_notification.id = _notification.id || new Date().getTime().toString();
_notification.local_notification = true;
return getNativeModule(this).createLocalNotification(_notification);
}
/**
* Returns an array of all scheduled notifications
* @returns {Promise.<Array>}
*/
getScheduledNotifications(): Promise<Object[]> {
return getNativeModule(this).getScheduledLocalNotifications();
}
onNotification(
nextOrObserver: OnNotification | OnNotificationObserver
): () => any {
let listener;
if (isFunction(nextOrObserver)) {
listener = nextOrObserver;
} else if (isObject(nextOrObserver) && isFunction(nextOrObserver.next)) {
listener = nextOrObserver.next;
} else {
throw new Error(
'Notifications.onNotification failed: First argument must be a function or observer object with a `next` function.'
);
}
// TODO: iOS finish
getLogger(this).info('Creating onNotification listener');
SharedEventEmitter.addListener('onNotification', listener);
return () => {
getLogger(this).info('Removing onNotification listener');
SharedEventEmitter.removeListener('onNotification', listener);
};
}
/**
* Remove a delivered notification - using '*' will remove
* all delivered notifications.
* @param id
* @returns {*}
*/
removeDeliveredNotification(id: string): Promise<void> {
if (!id) return Promise.reject(new Error('Missing notification id'));
if (id === '*') {
return getNativeModule(this).removeAllDeliveredNotifications();
}
return getNativeModule(this).removeDeliveredNotification(id);
}
/**
*
* @param notification
* @returns {*}
*/
scheduleNotification(notification: CreateNotification): Promise<void> {
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 getNativeModule(this).scheduleLocalNotification(_notification);
}
}