From 22ede3303d640364782a14a6813a5b8efc9e459e Mon Sep 17 00:00:00 2001 From: Mike Hardy Date: Mon, 9 Nov 2020 15:32:19 -0500 Subject: [PATCH] fix(messaging): BREAKING drop iOS FCM direct channel + upstream send APIs This is part of the forward port to firebase-ios-sdk v7.0.0 Note that upstream send is still possible on Android, but cloud functions are the recommended way to send messages in firebase BREAKING CHANGE: Upstream send should be done with cloud functions. FCM Direct channel has no replacement. --- packages/messaging/e2e/remoteMessage.e2e.js | 32 +++++++++---- .../RNFBMessaging+FIRMessagingDelegate.m | 10 ---- .../RNFBMessaging+NSNotificationCenter.m | 46 ------------------- .../ios/RNFBMessaging/RNFBMessagingModule.m | 13 ------ .../RNFBMessaging/RNFBMessagingSerializer.h | 2 - .../RNFBMessaging/RNFBMessagingSerializer.m | 4 -- packages/messaging/lib/index.d.ts | 8 ++++ packages/messaging/lib/index.js | 3 ++ 8 files changed, 35 insertions(+), 83 deletions(-) diff --git a/packages/messaging/e2e/remoteMessage.e2e.js b/packages/messaging/e2e/remoteMessage.e2e.js index 81aafcb211..38807fc38b 100644 --- a/packages/messaging/e2e/remoteMessage.e2e.js +++ b/packages/messaging/e2e/remoteMessage.e2e.js @@ -16,7 +16,23 @@ */ describe('messaging().sendMessage(*)', () => { - it('throws if no object provided', () => { + it('throws if used on ios', () => { + if (device.getPlatform() === 'ios') { + try { + firebase.messaging().sendMessage(123); + return Promise.reject(new Error('Did not throw Error.')); + } catch (e) { + e.message.should.containEql( + 'firebase.messaging().sendMessage() is only supported on Android devices.', + ); + return Promise.resolve(); + } + } else { + Promise.resolve(); + } + }); + + android.it('throws if no object provided', () => { try { firebase.messaging().sendMessage(123); return Promise.reject(new Error('Did not throw Error.')); @@ -26,11 +42,11 @@ describe('messaging().sendMessage(*)', () => { } }); - it('uses default values', async () => { + android.it('uses default values', async () => { firebase.messaging().sendMessage({}); }); - describe('to', () => { + android.describe('to', () => { it('throws if not a string', () => { try { firebase.messaging().sendMessage({ @@ -50,7 +66,7 @@ describe('messaging().sendMessage(*)', () => { }); }); - describe('messageId', () => { + android.describe('messageId', () => { it('throws if not a string', () => { try { firebase.messaging().sendMessage({ @@ -70,7 +86,7 @@ describe('messaging().sendMessage(*)', () => { }); }); - describe('ttl', () => { + android.describe('ttl', () => { it('throws if not a number', () => { try { firebase.messaging().sendMessage({ @@ -114,7 +130,7 @@ describe('messaging().sendMessage(*)', () => { }); }); - describe('data', () => { + android.describe('data', () => { it('throws if not an object', () => { try { firebase.messaging().sendMessage({ @@ -136,7 +152,7 @@ describe('messaging().sendMessage(*)', () => { }); }); - describe('collapseKey', () => { + android.describe('collapseKey', () => { it('throws if not a string', () => { try { firebase.messaging().sendMessage({ @@ -156,7 +172,7 @@ describe('messaging().sendMessage(*)', () => { }); }); - describe('messageType', () => { + android.describe('messageType', () => { it('throws if not a string', () => { try { firebase.messaging().sendMessage({ diff --git a/packages/messaging/ios/RNFBMessaging/RNFBMessaging+FIRMessagingDelegate.m b/packages/messaging/ios/RNFBMessaging/RNFBMessaging+FIRMessagingDelegate.m index 87f78ab2a3..e0ffa9dd05 100644 --- a/packages/messaging/ios/RNFBMessaging/RNFBMessaging+FIRMessagingDelegate.m +++ b/packages/messaging/ios/RNFBMessaging/RNFBMessaging+FIRMessagingDelegate.m @@ -64,14 +64,4 @@ - (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSStrin } } -- (void)messaging:(nonnull FIRMessaging *)messaging didReceiveMessage:(nonnull FIRMessagingRemoteMessage *)remoteMessage { - // If the users AppDelegate implements messaging:didReceiveMessage: then call it - SEL messaging_didReceiveMessageSelector = - NSSelectorFromString(@"messaging:didReceiveMessage:"); - if ([[GULAppDelegateSwizzler sharedApplication].delegate respondsToSelector:messaging_didReceiveMessageSelector]) { - void (*usersDidReceiveMessageIMP)(id, SEL, FIRMessaging *, FIRMessagingRemoteMessage *) = (typeof(usersDidReceiveMessageIMP)) &objc_msgSend; - usersDidReceiveMessageIMP([GULAppDelegateSwizzler sharedApplication].delegate, messaging_didReceiveMessageSelector, messaging, remoteMessage); - } -} - @end diff --git a/packages/messaging/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.m b/packages/messaging/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.m index 7872b8042e..abe2e8d6a8 100644 --- a/packages/messaging/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.m +++ b/packages/messaging/ios/RNFBMessaging/RNFBMessaging+NSNotificationCenter.m @@ -51,18 +51,6 @@ - (void)observe { // ObjC - > Mutates the root React components initialProps to toggle `isHeadless` state [[NSNotificationCenter defaultCenter] addObserver:strongSelf selector:@selector(application_onDidEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil]; - // Firebase Messaging - // JS -> `onSendError` events - [[NSNotificationCenter defaultCenter] addObserver:strongSelf selector:@selector(messaging_onSendErrorNotification:) name:FIRMessagingSendErrorNotification object:nil]; - - // Firebase Messaging - // JS -> `onMessageSent` events - [[NSNotificationCenter defaultCenter] addObserver:strongSelf selector:@selector(messaging_onSendSuccessNotification:) name:FIRMessagingSendSuccessNotification object:nil]; - - // Firebase Messaging - // JS -> `onDeletedMessages` events - [[NSNotificationCenter defaultCenter] addObserver:strongSelf selector:@selector(messaging_onDeletedMessagesNotification) name:FIRMessagingMessagesDeletedNotification object:nil]; - }); } @@ -71,40 +59,6 @@ + (void)load { [[self sharedInstance] observe]; } -#pragma mark - -#pragma mark Firebase Messaging Notifications - -// Firebase Messaging -// JS -> `onSendError` -- (void)messaging_onSendErrorNotification:(NSNotification *)notification { - NSDictionary *userInfo = notification.userInfo; - NSError *error = (NSError *) userInfo[@"error"]; - NSString *messageID = (NSString *) userInfo[@"messageID"]; - [[RNFBRCTEventEmitter shared] sendEventWithName:@"messaging_message_send_error" body:@{ - @"messageId": messageID, - @"error": @{ - @"code": @"unknown", - @"message": error.localizedDescription - } - }]; -} - -// Firebase Messaging -// JS -> `onMessageSent` -- (void)messaging_onSendSuccessNotification:(NSNotification *)notification { - NSDictionary *userInfo = notification.userInfo; - NSString *messageID = (NSString *) userInfo[@"messageID"]; - [[RNFBRCTEventEmitter shared] sendEventWithName:@"messaging_message_sent" body:@{ - @"messageId": messageID - }]; -} - -// Firebase Messaging -// JS -> `onDeletedMessages` -- (void)messaging_onDeletedMessagesNotification { - [[RNFBRCTEventEmitter shared] sendEventWithName:@"messaging_message_deleted" body:@{}]; -} - #pragma mark - #pragma mark Application Notifications diff --git a/packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.m b/packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.m index 21c7bf7de5..6199d75985 100644 --- a/packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.m +++ b/packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.m @@ -306,19 +306,6 @@ - (NSDictionary *)constantsToExport { } } -RCT_EXPORT_METHOD(sendMessage: - (NSDictionary *) message - :(RCTPromiseResolveBlock) resolve - :(RCTPromiseRejectBlock) reject -) { - NSString *to = message[@"to"]; - NSNumber *ttl = message[@"ttl"]; - NSDictionary *data = message[@"data"]; - NSString *messageId = message[@"messageId"]; - [[FIRMessaging messaging] sendMessage:data to:to withMessageID:messageId timeToLive:[ttl intValue]]; - resolve(nil); -} - RCT_EXPORT_METHOD(subscribeToTopic: (NSString *) topic :(RCTPromiseResolveBlock) resolve diff --git a/packages/messaging/ios/RNFBMessaging/RNFBMessagingSerializer.h b/packages/messaging/ios/RNFBMessaging/RNFBMessagingSerializer.h index 344c3df3fb..8347e07611 100644 --- a/packages/messaging/ios/RNFBMessaging/RNFBMessagingSerializer.h +++ b/packages/messaging/ios/RNFBMessaging/RNFBMessagingSerializer.h @@ -23,8 +23,6 @@ + (NSString *)APNSTokenFromNSData:(NSData *)tokenData; -+ (NSDictionary *)remoteMessageToDict:(FIRMessagingRemoteMessage *)remoteMessage; - + (NSDictionary *)notificationToDict:(UNNotification *)notification; + (NSDictionary *)remoteMessageUserInfoToDict:(NSDictionary *)userInfo; diff --git a/packages/messaging/ios/RNFBMessaging/RNFBMessagingSerializer.m b/packages/messaging/ios/RNFBMessaging/RNFBMessagingSerializer.m index d4ceb3c955..a1c1daf70c 100644 --- a/packages/messaging/ios/RNFBMessaging/RNFBMessagingSerializer.m +++ b/packages/messaging/ios/RNFBMessaging/RNFBMessagingSerializer.m @@ -31,10 +31,6 @@ + (NSString *)APNSTokenFromNSData:(NSData *)tokenData { return [token copy]; } -+ (NSDictionary *)remoteMessageToDict:(FIRMessagingRemoteMessage *)remoteMessage { - return [self remoteMessageUserInfoToDict:remoteMessage.appData]; -} - + (NSDictionary *)notificationToDict:(UNNotification *)notification { return [self remoteMessageUserInfoToDict:notification.request.content.userInfo]; } diff --git a/packages/messaging/lib/index.d.ts b/packages/messaging/lib/index.d.ts index 20fd7a5935..5fa852de75 100644 --- a/packages/messaging/lib/index.d.ts +++ b/packages/messaging/lib/index.d.ts @@ -839,6 +839,8 @@ export namespace FirebaseMessagingTypes { * unsubscribe(); * ``` * + * NOTE: Android only + * * @param listener Called when the FCM deletes pending messages. */ onDeletedMessages(listener: () => void): () => void; @@ -859,6 +861,8 @@ export namespace FirebaseMessagingTypes { * unsubscribe(); * ``` * + * NOTE: Android only + * * @param listener Called when the FCM sends the remote message to FCM. */ onMessageSent(listener: (messageId: string) => any): () => void; @@ -880,6 +884,8 @@ export namespace FirebaseMessagingTypes { * unsubscribe(); * ``` * + * NOTE: Android only + * * @param listener */ onSendError(listener: (evt: SendErrorEvent) => any): () => void; @@ -925,6 +931,8 @@ export namespace FirebaseMessagingTypes { * }); * ``` * + * NOTE: Android only + * * @param message A `RemoteMessage` interface. */ sendMessage(message: RemoteMessage): Promise; diff --git a/packages/messaging/lib/index.js b/packages/messaging/lib/index.js index bdc05fb06b..afb4385006 100644 --- a/packages/messaging/lib/index.js +++ b/packages/messaging/lib/index.js @@ -328,6 +328,9 @@ class FirebaseMessagingModule extends FirebaseModule { } sendMessage(remoteMessage) { + if (isIOS) { + throw new Error(`firebase.messaging().sendMessage() is only supported on Android devices.`); + } let options; try { options = remoteMessageOptions(this.app.options.messagingSenderId, remoteMessage);