From d429db7e862aa841398fddc93baa6c3af6258ccc Mon Sep 17 00:00:00 2001 From: Chris Bianca Date: Tue, 30 Jan 2018 11:15:59 +0000 Subject: [PATCH] [fcm] First steps towards identifying the new API for messaging / notifications --- ios/RNFirebase.xcodeproj/project.pbxproj | 6 + ios/RNFirebase/RNFirebaseEvents.h | 3 + .../messaging/NewRNFirebaseMessaging.h | 23 +++ .../messaging/NewRNFirebaseMessaging.m | 132 +++++++++++++ lib/modules/core/firebase-app.js | 9 + lib/modules/core/firebase.js | 11 ++ lib/modules/messaging/messagingIndex.js | 186 ++++++++++++++++++ .../notifications/notificationsIndex.js | 138 +++++++++++++ lib/types/index.js | 11 ++ tests/ios/Podfile.lock | 4 +- tests/src/firebase.js | 14 ++ 11 files changed, 535 insertions(+), 2 deletions(-) create mode 100644 ios/RNFirebase/messaging/NewRNFirebaseMessaging.h create mode 100644 ios/RNFirebase/messaging/NewRNFirebaseMessaging.m create mode 100644 lib/modules/messaging/messagingIndex.js create mode 100644 lib/modules/notifications/notificationsIndex.js diff --git a/ios/RNFirebase.xcodeproj/project.pbxproj b/ios/RNFirebase.xcodeproj/project.pbxproj index 92df426e..bc43b797 100644 --- a/ios/RNFirebase.xcodeproj/project.pbxproj +++ b/ios/RNFirebase.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ 8376F7141F7C149100D45A85 /* RNFirebaseFirestoreDocumentReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F70E1F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.m */; }; 8376F7151F7C149100D45A85 /* RNFirebaseFirestore.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F7101F7C149000D45A85 /* RNFirebaseFirestore.m */; }; 8376F7161F7C149100D45A85 /* RNFirebaseFirestoreCollectionReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F7111F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.m */; }; + 838E36FE201B9169004DCD3A /* NewRNFirebaseMessaging.m in Sources */ = {isa = PBXBuildFile; fileRef = 838E36FD201B9169004DCD3A /* NewRNFirebaseMessaging.m */; }; 839D916C1EF3E20B0077C7C8 /* RNFirebaseAdMob.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D914F1EF3E20A0077C7C8 /* RNFirebaseAdMob.m */; }; 839D916D1EF3E20B0077C7C8 /* RNFirebaseAdMobInterstitial.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91511EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.m */; }; 839D916E1EF3E20B0077C7C8 /* RNFirebaseAdMobRewardedVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91531EF3E20A0077C7C8 /* RNFirebaseAdMobRewardedVideo.m */; }; @@ -66,6 +67,8 @@ 8376F7111F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseFirestoreCollectionReference.m; sourceTree = ""; }; 8376F7121F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseFirestoreDocumentReference.h; sourceTree = ""; }; 8376F7131F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseFirestoreCollectionReference.h; sourceTree = ""; }; + 838E36FC201B9169004DCD3A /* NewRNFirebaseMessaging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NewRNFirebaseMessaging.h; sourceTree = ""; }; + 838E36FD201B9169004DCD3A /* NewRNFirebaseMessaging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NewRNFirebaseMessaging.m; sourceTree = ""; }; 839D914E1EF3E20A0077C7C8 /* RNFirebaseAdMob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMob.h; sourceTree = ""; }; 839D914F1EF3E20A0077C7C8 /* RNFirebaseAdMob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAdMob.m; sourceTree = ""; }; 839D91501EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMobInterstitial.h; sourceTree = ""; }; @@ -256,6 +259,8 @@ 839D91631EF3E20A0077C7C8 /* messaging */ = { isa = PBXGroup; children = ( + 838E36FC201B9169004DCD3A /* NewRNFirebaseMessaging.h */, + 838E36FD201B9169004DCD3A /* NewRNFirebaseMessaging.m */, 839D91641EF3E20A0077C7C8 /* RNFirebaseMessaging.h */, 839D91651EF3E20A0077C7C8 /* RNFirebaseMessaging.m */, ); @@ -343,6 +348,7 @@ 839D916C1EF3E20B0077C7C8 /* RNFirebaseAdMob.m in Sources */, 17AF4F6B1F59CDBF00C02336 /* RNFirebaseLinks.m in Sources */, 8376F7161F7C149100D45A85 /* RNFirebaseFirestoreCollectionReference.m in Sources */, + 838E36FE201B9169004DCD3A /* NewRNFirebaseMessaging.m in Sources */, 8376F7151F7C149100D45A85 /* RNFirebaseFirestore.m in Sources */, 839D91701EF3E20B0077C7C8 /* RNFirebaseAuth.m in Sources */, 8323CF091F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.m in Sources */, diff --git a/ios/RNFirebase/RNFirebaseEvents.h b/ios/RNFirebase/RNFirebaseEvents.h index d75c875b..26ce5f3e 100644 --- a/ios/RNFirebase/RNFirebaseEvents.h +++ b/ios/RNFirebase/RNFirebaseEvents.h @@ -32,7 +32,10 @@ static NSString *const STORAGE_DOWNLOAD_SUCCESS = @"download_success"; static NSString *const STORAGE_DOWNLOAD_FAILURE = @"download_failure"; // Messaging +static NSString *const MESSAGING_MESSAGE_RECEIVED = @"messaging_message_received"; static NSString *const MESSAGING_TOKEN_REFRESHED = @"messaging_token_refreshed"; + +// TODO: Remove static NSString *const MESSAGING_NOTIFICATION_RECEIVED = @"messaging_notification_received"; // AdMob diff --git a/ios/RNFirebase/messaging/NewRNFirebaseMessaging.h b/ios/RNFirebase/messaging/NewRNFirebaseMessaging.h new file mode 100644 index 00000000..53511103 --- /dev/null +++ b/ios/RNFirebase/messaging/NewRNFirebaseMessaging.h @@ -0,0 +1,23 @@ +#ifndef NewRNFirebaseMessaging_h +#define NewRNFirebaseMessaging_h +#import + +#if __has_include() +#import +#import +#import + +@interface NewRNFirebaseMessaging : RCTEventEmitter + +#if !TARGET_OS_TV + +#endif + +@end + +#else +@interface NewRNFirebaseMessaging : NSObject +@end +#endif + +#endif diff --git a/ios/RNFirebase/messaging/NewRNFirebaseMessaging.m b/ios/RNFirebase/messaging/NewRNFirebaseMessaging.m new file mode 100644 index 00000000..0880b834 --- /dev/null +++ b/ios/RNFirebase/messaging/NewRNFirebaseMessaging.m @@ -0,0 +1,132 @@ +#import "NewRNFirebaseMessaging.h" + +#if __has_include() +@import UserNotifications; +#import "RNFirebaseEvents.h" +#import "RNFirebaseUtil.h" +#import +#import + +#import +#import +#import + +@interface NewRNFirebaseMessaging () + +@end + +@implementation NewRNFirebaseMessaging + +RCT_EXPORT_MODULE() + +- (id)init { + self = [super init]; + if (self != nil) { + NSLog(@"Setting up RNFirebaseMessaging instance"); + [self initialiseMessaging]; + } + return self; +} + +- (void)initialiseMessaging { + // Establish Firebase managed data channel + [FIRMessaging messaging].shouldEstablishDirectChannel = YES; +} + +- (void)dealloc { + +} + +// ** Start React Module methods ** +RCT_EXPORT_METHOD(getToken:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { + resolve([[FIRInstanceID instanceID] token]); +} + +RCT_EXPORT_METHOD(requestPermission:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { + if (RCTRunningInAppExtension()) { + reject(@"request_permission_unavailable", @"requestPermission is not supported in App Extensions", nil); + return; + } + + if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) { + UIUserNotificationType types = (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge); + [RCTSharedApplication() registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:types categories:nil]]; + // Unfortunately on iOS 9 or below, there's no way to tell whether the user accepted or + // rejected the permissions popup + // TODO: Is there something we can listen for? + resolve(@{@"status":@"unknown"}); + } else { + // iOS 10 or later + #if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + // For iOS 10 display notification (sent via APNS) + UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge; + [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) { + if (granted) { + resolve(@{@"status": @"granted"}); + } else { + reject(@"permission_error", @"Failed to grant permission", error); + } + }]; + #endif + } + + dispatch_async(dispatch_get_main_queue(), ^{ + [RCTSharedApplication() registerForRemoteNotifications]; + }); +} + +// Non Web SDK methods + +RCT_EXPORT_METHOD(deleteInstanceId:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { + [[FIRInstanceID instanceID] deleteIDWithHandler:^(NSError * _Nullable error) { + if (!error) { + resolve(nil); + } else { + reject(@"instance_id_error", @"Failed to delete instance id", error); + } + }]; +} + +RCT_EXPORT_METHOD(getBadgeNumber: (RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { + resolve(@([RCTSharedApplication() applicationIconBadgeNumber])); +} + +RCT_EXPORT_METHOD(getInitialNotification:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject){ + UILocalNotification *localUserInfo = [self bridge].launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]; + if (localUserInfo) { + resolve([[localUserInfo userInfo] copy]); + } else { + resolve([[self bridge].launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] copy]); + } +} + +RCT_EXPORT_METHOD(subscribeToTopic: (NSString*) topic) { + [[FIRMessaging messaging] subscribeToTopic:topic]; +} + +RCT_EXPORT_METHOD(unsubscribeFromTopic: (NSString*) topic) { + [[FIRMessaging messaging] unsubscribeFromTopic:topic]; +} + + +RCT_EXPORT_METHOD(setBadgeNumber: (NSInteger*) number) { + dispatch_async(dispatch_get_main_queue(), ^{ + [RCTSharedApplication() setApplicationIconBadgeNumber:*number]; + }); +} + +- (NSArray *)supportedEvents { + return @[MESSAGING_MESSAGE_RECEIVED, MESSAGING_TOKEN_REFRESHED]; +} + ++ (BOOL)requiresMainQueueSetup +{ + return YES; +} + +@end + +#else +@implementation NewRNFirebaseMessaging +@end +#endif diff --git a/lib/modules/core/firebase-app.js b/lib/modules/core/firebase-app.js index 1f81e6aa..0c79517f 100644 --- a/lib/modules/core/firebase-app.js +++ b/lib/modules/core/firebase-app.js @@ -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); diff --git a/lib/modules/core/firebase.js b/lib/modules/core/firebase.js index 13aad29d..119d9fc6 100644 --- a/lib/modules/core/firebase.js +++ b/lib/modules/core/firebase.js @@ -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, diff --git a/lib/modules/messaging/messagingIndex.js b/lib/modules/messaging/messagingIndex.js new file mode 100644 index 00000000..9d7f4247 --- /dev/null +++ b/lib/modules/messaging/messagingIndex.js @@ -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 { + return getNativeModule(this).deleteToken(token); + } + + getToken(): Promise { + 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 { + return getNativeModule(this).requestPermission(); + } + + /** + * NON WEB-SDK METHODS + */ + deleteInstanceId(): Promise { + return getNativeModule(this).deleteInstanceId(); + } + + getBadgeNumber(): Promise { + return getNativeModule(this).getBadgeNumber(); + } + + getInitialMessage(): Promise { + return getNativeModule(this).getInitialMessage(); + } + + sendMessage(remoteMessage: RemoteMessage): Promise { + 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, +}; diff --git a/lib/modules/notifications/notificationsIndex.js b/lib/modules/notifications/notificationsIndex.js new file mode 100644 index 00000000..9620292f --- /dev/null +++ b/lib/modules/notifications/notificationsIndex.js @@ -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 { + 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 { + 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.} + */ + getScheduledNotifications(): Promise { + 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 { + 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 { + 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); + } +} diff --git a/lib/types/index.js b/lib/types/index.js index 0308f711..ce894079 100644 --- a/lib/types/index.js +++ b/lib/types/index.js @@ -19,6 +19,8 @@ import type Links from '../modules/links'; import { typeof statics as LinksStatics } from '../modules/links'; import type Messaging from '../modules/messaging'; import { typeof statics as MessagingStatics } from '../modules/messaging'; +import type NewMessaging from '../modules/messaging/messagingIndex'; +import { typeof statics as NewMessagingStatics } from '../modules/messaging/messagingIndex'; import type ModuleBase from '../utils/ModuleBase'; import type Performance from '../modules/perf'; import { typeof statics as PerformanceStatics } from '../modules/perf'; @@ -58,6 +60,8 @@ export type FirebaseModuleName = | 'RNFirebaseFirestore' | 'RNFirebaseLinks' | 'RNFirebaseMessaging' + | 'NewRNFirebaseMessaging' + | 'RNFirebaseNotifications' | 'RNFirebasePerformance' | 'RNFirebaseStorage' | 'RNFirebaseUtils'; @@ -73,6 +77,8 @@ export type FirebaseNamespace = | 'firestore' | 'links' | 'messaging' + | 'newmessaging' + | 'notifications' | 'perf' | 'storage' | 'utils'; @@ -217,6 +223,11 @@ export type MessagingModule = { nativeModuleExists: boolean, } & MessagingStatics; +export type NewMessagingModule = { + (): NewMessaging, + nativeModuleExists: boolean, +} & NewMessagingStatics; + /* Performance types */ export type PerformanceModule = { diff --git a/tests/ios/Podfile.lock b/tests/ios/Podfile.lock index 480652fa..c964fec5 100644 --- a/tests/ios/Podfile.lock +++ b/tests/ios/Podfile.lock @@ -164,7 +164,7 @@ PODS: - React/Core - React/fishhook - React/RCTBlob - - RNFirebase (3.2.0): + - RNFirebase (3.2.2): - React - yoga (0.52.0.React) @@ -228,7 +228,7 @@ SPEC CHECKSUMS: nanopb: 5601e6bca2dbf1ed831b519092ec110f66982ca3 Protobuf: 8a9838fba8dae3389230e1b7f8c104aa32389c03 React: 61a6bdf17a9ff16875c230e6ff278d9de274e16c - RNFirebase: 22b1917fec663706907bc901ed665ac4f8b9bfd6 + RNFirebase: 5cf5405d1b67c9720ce63a2da3d6d5346415d0f7 yoga: 646606bf554d54a16711f35596178522fbc00480 PODFILE CHECKSUM: 67c98bcb203cb992da590bcab6f690f727653ca5 diff --git a/tests/src/firebase.js b/tests/src/firebase.js index c98816fd..f78cfe1d 100644 --- a/tests/src/firebase.js +++ b/tests/src/firebase.js @@ -7,6 +7,20 @@ import DatabaseContents from './tests/support/DatabaseContents'; RNfirebase.database.enableLogging(true); RNfirebase.firestore.enableLogging(true); +RNfirebase.newmessaging() + .requestPermission() + .then(response => { + console.log('requestPermission:', response); + RNfirebase.newmessaging() + .getToken() + .then(token => { + console.log('token: ', token); + }); + }) + .catch(error => { + console.error('requestPermission:', error); + }); + const config = { apiKey: 'AIzaSyDnVqNhxU0Biit9nCo4RorAh5ulQQwko3E', authDomain: 'rnfirebase-b9ad4.firebaseapp.com',