Skip to content

Commit

Permalink
fix(messaging): BREAKING drop iOS FCM direct channel + upstream send …
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
mikehardy committed Nov 10, 2020
1 parent 6e59a74 commit 22ede33
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 83 deletions.
32 changes: 24 additions & 8 deletions packages/messaging/e2e/remoteMessage.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.'));
Expand All @@ -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({
Expand All @@ -50,7 +66,7 @@ describe('messaging().sendMessage(*)', () => {
});
});

describe('messageId', () => {
android.describe('messageId', () => {
it('throws if not a string', () => {
try {
firebase.messaging().sendMessage({
Expand All @@ -70,7 +86,7 @@ describe('messaging().sendMessage(*)', () => {
});
});

describe('ttl', () => {
android.describe('ttl', () => {
it('throws if not a number', () => {
try {
firebase.messaging().sendMessage({
Expand Down Expand Up @@ -114,7 +130,7 @@ describe('messaging().sendMessage(*)', () => {
});
});

describe('data', () => {
android.describe('data', () => {
it('throws if not an object', () => {
try {
firebase.messaging().sendMessage({
Expand All @@ -136,7 +152,7 @@ describe('messaging().sendMessage(*)', () => {
});
});

describe('collapseKey', () => {
android.describe('collapseKey', () => {
it('throws if not a string', () => {
try {
firebase.messaging().sendMessage({
Expand All @@ -156,7 +172,7 @@ describe('messaging().sendMessage(*)', () => {
});
});

describe('messageType', () => {
android.describe('messageType', () => {
it('throws if not a string', () => {
try {
firebase.messaging().sendMessage({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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];

});
}

Expand All @@ -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

Expand Down
13 changes: 0 additions & 13 deletions packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@

+ (NSString *)APNSTokenFromNSData:(NSData *)tokenData;

+ (NSDictionary *)remoteMessageToDict:(FIRMessagingRemoteMessage *)remoteMessage;

+ (NSDictionary *)notificationToDict:(UNNotification *)notification;

+ (NSDictionary *)remoteMessageUserInfoToDict:(NSDictionary *)userInfo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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];
}
Expand Down
8 changes: 8 additions & 0 deletions packages/messaging/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,8 @@ export namespace FirebaseMessagingTypes {
* unsubscribe();
* ```
*
* NOTE: Android only
*
* @param listener Called when the FCM deletes pending messages.
*/
onDeletedMessages(listener: () => void): () => void;
Expand All @@ -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;
Expand All @@ -880,6 +884,8 @@ export namespace FirebaseMessagingTypes {
* unsubscribe();
* ```
*
* NOTE: Android only
*
* @param listener
*/
onSendError(listener: (evt: SendErrorEvent) => any): () => void;
Expand Down Expand Up @@ -925,6 +931,8 @@ export namespace FirebaseMessagingTypes {
* });
* ```
*
* NOTE: Android only
*
* @param message A `RemoteMessage` interface.
*/
sendMessage(message: RemoteMessage): Promise<void>;
Expand Down
3 changes: 3 additions & 0 deletions packages/messaging/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 22ede33

Please sign in to comment.