-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Add support for the new FCM registration ID. #16133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 18 commits
12a6ad8
c3c3d67
b442d42
fe49a75
f1294be
8c0ba25
b471f82
4b72a42
c28628b
e7aeac8
836b697
dff8587
503c5b6
c12d985
1d4c3f8
e984467
125dac3
d95a204
f7cea1d
fc874aa
26c94d2
6093f94
e7433b8
77ad7f5
fd64ad9
1c52ccb
befa3a4
c28c64d
36fa768
312dcac
95f16b4
ef6663f
3f2164b
0715193
f931f38
e5b0f5e
7d091ff
95ac9aa
e74e1a9
fd07733
2189024
b5955ad
368868e
8b041e0
a80d75c
b7d9007
0d0c684
9cc6576
bd3cdba
adcdb46
f9c3a58
f8ba052
32ef76c
910f4fb
fce9744
38958b9
55f494d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
leojaygoogle marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -51,12 +51,18 @@ | |
| const NSNotificationName FIRMessagingRegistrationTokenRefreshedNotification = | ||
| @"com.firebase.messaging.notif.fcm-token-refreshed"; | ||
|
|
||
| const NSNotificationName FIRMessagingInstallationIdUnregisteredNotification = | ||
| @"com.firebase.messaging.notif.installation-id-unregistered"; | ||
|
|
||
| NSString *const kFIRMessagingUserDefaultsKeyAutoInitEnabled = | ||
| @"com.firebase.messaging.auto-init.enabled"; // Auto Init Enabled key stored in NSUserDefaults | ||
|
|
||
| NSString *const kFIRMessagingPlistAutoInitEnabled = | ||
| @"FirebaseMessagingAutoInitEnabled"; // Auto Init Enabled key stored in Info.plist | ||
|
|
||
| NSString *const kFIRMessagingPlistInstallationIdEnabled = | ||
| @"FirebaseMessagingInstallationIdEnabled"; // Installation ID Enabled key stored in Info.plist | ||
|
|
||
| NSString *const FIRMessagingErrorDomain = @"com.google.fcm"; | ||
|
|
||
| BOOL FIRMessagingIsAPNSSyncMessage(NSDictionary *message) { | ||
|
|
@@ -114,6 +120,8 @@ @interface FIRMessaging () <GULReachabilityDelegate> | |
| /// calling it implicitly during swizzling. | ||
| @property(nonatomic, readwrite, strong) NSMutableSet *loggedMessageIDs; | ||
| @property(nonatomic, readwrite, strong) id<FIRAnalyticsInterop> _Nullable analytics; | ||
| @property(nonatomic, readwrite, strong, nullable) id<NSObject> installationIDObserver; | ||
| @property(nonatomic, readwrite, copy, nullable) NSString *lastKnownFID; | ||
|
|
||
| @end | ||
|
|
||
|
|
@@ -232,7 +240,7 @@ - (void)didCompleteConfigure { | |
| // happens before developers able to set the delegate | ||
| // Hence first token set must be happen here after listener is set | ||
| // TODO(chliangGoogle) Need to investigate better solution. | ||
| [self updateDefaultFCMToken:self.FCMToken]; | ||
| [self updateDefaultFCMToken:[self.tokenManager tokenAndRequestIfNotExist]]; | ||
| }]; | ||
| } else if (self.isAutoInitEnabled && self.APNSToken) { | ||
| // When there is no cached token, must check auto init is enabled. | ||
|
|
@@ -493,7 +501,19 @@ - (void)setAutoInitEnabled:(BOOL)autoInitEnabled { | |
| } | ||
| } | ||
|
|
||
| - (BOOL)isInstallationIdEnabled { | ||
| id isInstallationIdEnabledObject = | ||
| [[NSBundle mainBundle] objectForInfoDictionaryKey:kFIRMessagingPlistInstallationIdEnabled]; | ||
| return [isInstallationIdEnabledObject boolValue]; | ||
| } | ||
|
leojaygoogle marked this conversation as resolved.
|
||
|
|
||
| - (NSString *)FCMToken { | ||
| if (self.isInstallationIdEnabled) { | ||
| FIRMessagingLoggerDebug( | ||
| kFIRMessagingMessageCodeInstallationIdEnabled, | ||
| @"FirebaseMessagingInstallationIdEnabled is set to YES, token is not available."); | ||
| return nil; | ||
| } | ||
| // Gets the current default token, and requests a new one if it doesn't exist. | ||
| NSString *token = [self.tokenManager tokenAndRequestIfNotExist]; | ||
| return token; | ||
|
|
@@ -617,14 +637,27 @@ - (void)setDelegate:(id<FIRMessagingDelegate>)delegate { | |
| // NOTE: Once |didReceiveRegistrationToken:| can be made a required method, this | ||
| // check can be removed. | ||
| - (void)validateDelegateConformsToTokenAvailabilityMethods { | ||
| if (self.delegate && | ||
| ![self.delegate respondsToSelector:@selector(messaging:didReceiveRegistrationToken:)]) { | ||
| FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTokenDelegateMethodsNotImplemented, | ||
| @"The object %@ does not respond to " | ||
| @"-messaging:didReceiveRegistrationToken:. Please implement " | ||
| @"-messaging:didReceiveRegistrationToken: to be provided with an FCM " | ||
| @"token.", | ||
| self.delegate.description); | ||
| if (self.delegate) { | ||
| if ([self isInstallationIdEnabled]) { | ||
| if (![self.delegate respondsToSelector:@selector(messaging:didReceiveRegistration:)]) { | ||
| FIRMessagingLoggerWarn( | ||
| kFIRMessagingMessageCodeTokenDelegateMethodsNotImplemented, | ||
| @"The object %@ does not respond to " | ||
| @"-messaging:didReceiveRegistration:. Please implement " | ||
| @"-messaging:didReceiveRegistration: to be provided with an installation ID.", | ||
| self.delegate.description); | ||
| } | ||
| } else { | ||
| if (![self.delegate respondsToSelector:@selector(messaging:didReceiveRegistrationToken:)]) { | ||
| FIRMessagingLoggerWarn( | ||
| kFIRMessagingMessageCodeTokenDelegateMethodsNotImplemented, | ||
| @"The object %@ does not respond to " | ||
| @"-messaging:didReceiveRegistrationToken:. Please implement " | ||
| @"-messaging:didReceiveRegistrationToken: to be provided with an FCM " | ||
| @"token.", | ||
| self.delegate.description); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -636,8 +669,14 @@ - (void)notifyRefreshedFCMToken { | |
| }); | ||
| return; | ||
| } | ||
| if ([self.delegate respondsToSelector:@selector(messaging:didReceiveRegistrationToken:)]) { | ||
| [self.delegate messaging:self didReceiveRegistrationToken:self.tokenManager.defaultFCMToken]; | ||
| if ([self isInstallationIdEnabled]) { | ||
| if ([self.delegate respondsToSelector:@selector(messaging:didReceiveRegistration:)]) { | ||
| [self.delegate messaging:self didReceiveRegistration:self.tokenManager.defaultFCMToken]; | ||
| } | ||
| } else { | ||
| if ([self.delegate respondsToSelector:@selector(messaging:didReceiveRegistrationToken:)]) { | ||
| [self.delegate messaging:self didReceiveRegistrationToken:self.tokenManager.defaultFCMToken]; | ||
| } | ||
| } | ||
|
|
||
| // Should always trigger the token refresh notification when the delegate method is called | ||
|
|
@@ -646,6 +685,120 @@ - (void)notifyRefreshedFCMToken { | |
| object:self.tokenManager.defaultFCMToken]; | ||
| } | ||
|
|
||
| - (void)notifyInstallationIdUnregistered:(nonnull NSString *)installationID { | ||
| if (![self isInstallationIdEnabled]) { | ||
| return; | ||
| } | ||
|
|
||
| __weak FIRMessaging *weakSelf = self; | ||
| if (![NSThread isMainThread]) { | ||
| dispatch_async(dispatch_get_main_queue(), ^{ | ||
| [weakSelf notifyInstallationIdUnregistered:installationID]; | ||
| }); | ||
| return; | ||
| } | ||
|
|
||
| if ([self.delegate respondsToSelector:@selector(messaging:didUnregister:)]) { | ||
| [self.delegate messaging:self didUnregister:installationID]; | ||
| } | ||
|
|
||
| NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; | ||
| [center postNotificationName:FIRMessagingInstallationIdUnregisteredNotification | ||
| object:installationID]; | ||
| } | ||
|
|
||
| #pragma mark - FID | ||
|
|
||
| - (void)handleInstallationIDDidChangeNotification:(NSNotification *)notification { | ||
| FIRMessaging_WEAKIFY(self); | ||
| [self.installations installationIDWithCompletion:^(NSString *_Nullable identifier, | ||
| NSError *_Nullable error) { | ||
| dispatch_async(dispatch_get_main_queue(), ^{ | ||
| FIRMessaging_STRONGIFY(self); | ||
| if (error || !identifier.length) { | ||
| return; | ||
| } | ||
| // Registration will only be triggered if FID is changed | ||
| if (![identifier isEqualToString:self.lastKnownFID]) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shall we also check if the app instance is registered or not? I think we should avoid creating a registration if the app disables auto-init and never calls
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. also added tests. |
||
| FIRMessagingLoggerInfo(kFIRMessagingMessageCodeInstallationIdRotation, | ||
| @"FID rotated. Registering with the new FID '%@'", identifier); | ||
| self.lastKnownFID = identifier; | ||
| [self retrieveFCMTokenForSenderID:self.tokenManager.fcmSenderID | ||
| completion:^(NSString *_Nullable FCMToken, NSError *_Nullable error){ | ||
| }]; | ||
|
leojaygoogle marked this conversation as resolved.
Outdated
leojaygoogle marked this conversation as resolved.
Outdated
|
||
| } | ||
| }); | ||
| }]; | ||
| } | ||
|
|
||
| - (void)setupInstallationIDObserver { | ||
| if (self.installationIDObserver) { | ||
| return; | ||
| } | ||
| // Monitor FID rotation events. When FID rotates, register with the new FID. | ||
| FIRMessagingLoggerDebug(kFIRMessagingMessageCodeDebug, @"Listening for FID rotation events"); | ||
| FIRMessaging_WEAKIFY(self); | ||
| self.installationIDObserver = [NSNotificationCenter.defaultCenter | ||
|
ncooke3 marked this conversation as resolved.
|
||
| addObserverForName:FIRInstallationIDDidChangeNotification | ||
| object:nil | ||
| queue:nil | ||
| usingBlock:^(NSNotification *notification) { | ||
| FIRMessaging_STRONGIFY(self); | ||
| [self handleInstallationIDDidChangeNotification:notification]; | ||
| }]; | ||
| } | ||
|
|
||
| - (void)register { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method should always trigger the Consider adding a unit test for this scenario.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. also added a test case. |
||
| if (!self.isInstallationIdEnabled) { | ||
| FIRMessagingLoggerError(kFIRMessagingMessageCodeInstallationIdDisabled, | ||
| @"FirebaseMessagingInstallationIdEnabled is not set to YES, so " | ||
| @"FID operations are not supported."); | ||
| return; | ||
| } | ||
| if (!FIRApp.defaultApp.options.GCMSenderID.length) { | ||
| FIRMessagingLoggerError(kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenFetch, | ||
| @"No Sender ID is available to register"); | ||
| return; | ||
| } | ||
| [self setupInstallationIDObserver]; | ||
|
leojaygoogle marked this conversation as resolved.
Outdated
|
||
| [self.tokenManager tokenAndRequestIfNotExist]; | ||
| } | ||
|
|
||
| - (void)unregister { | ||
| if (!self.isInstallationIdEnabled) { | ||
| FIRMessagingLoggerError(kFIRMessagingMessageCodeInstallationIdDisabled, | ||
| @"FirebaseMessagingInstallationIdEnabled is not set to YES, so " | ||
| @"FID operations are not supported."); | ||
| return; | ||
| } | ||
| NSString *senderID = FIRApp.defaultApp.options.GCMSenderID; | ||
| if (!senderID.length) { | ||
| FIRMessagingLoggerError(kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenDelete, | ||
| @"No Sender ID is available to unregister"); | ||
| return; | ||
| } | ||
|
|
||
| FIRMessaging_WEAKIFY(self); | ||
| [self.installations | ||
| installationIDWithCompletion:^(NSString *_Nullable identifier, NSError *_Nullable error) { | ||
| FIRMessaging_STRONGIFY(self); | ||
| if (error || !identifier.length) { | ||
| FIRMessagingLoggerError(kFIRMessagingMessageCodeTokenOperationInstallationIdNotAvailable, | ||
| @"Failed to get installation ID."); | ||
| } else { | ||
| [self.tokenManager | ||
| deleteTokenWithAuthorizedEntity:senderID | ||
| scope:kFIRMessagingDefaultTokenScope | ||
| instanceID:identifier | ||
| handler:^(NSError *_Nullable error) { | ||
| if (!error) { | ||
| [self notifyInstallationIdUnregistered:identifier]; | ||
| } | ||
| }]; | ||
| } | ||
| }]; | ||
| } | ||
|
|
||
| #pragma mark - Topics | ||
|
|
||
| + (NSString *)normalizeTopic:(NSString *)topic { | ||
|
|
@@ -673,7 +826,7 @@ - (void)subscribeToTopic:(NSString *)topic | |
| @"subscribeToTopic.", | ||
| topic, [FIRMessagingPubSub removePrefixFromTopic:topic]); | ||
| } | ||
| __weak FIRMessaging *weakSelf = self; | ||
| FIRMessaging_WEAKIFY(self); | ||
| [self | ||
| retrieveFCMTokenForSenderID:self.tokenManager.fcmSenderID | ||
| completion:^(NSString *_Nullable FCMToken, NSError *_Nullable error) { | ||
|
|
@@ -687,10 +840,10 @@ - (void)subscribeToTopic:(NSString *)topic | |
| } | ||
| return; | ||
| } | ||
| FIRMessaging *strongSelf = weakSelf; | ||
| NSString *normalizeTopic = [[strongSelf class] normalizeTopic:topic]; | ||
| FIRMessaging_STRONGIFY(self); | ||
| NSString *normalizeTopic = [[self class] normalizeTopic:topic]; | ||
| if (normalizeTopic.length) { | ||
| [strongSelf.pubsub subscribeToTopic:normalizeTopic handler:completion]; | ||
| [self.pubsub subscribeToTopic:normalizeTopic handler:completion]; | ||
| return; | ||
| } | ||
| NSString *failureReason = [NSString | ||
|
|
@@ -814,8 +967,14 @@ - (void)notifyDelegateOfFCMTokenAvailability { | |
| }); | ||
| return; | ||
| } | ||
| if ([self.delegate respondsToSelector:@selector(messaging:didReceiveRegistrationToken:)]) { | ||
| [self.delegate messaging:self didReceiveRegistrationToken:self.tokenManager.defaultFCMToken]; | ||
| if ([self isInstallationIdEnabled]) { | ||
| if ([self.delegate respondsToSelector:@selector(messaging:didReceiveRegistration:)]) { | ||
| [self.delegate messaging:self didReceiveRegistration:self.tokenManager.defaultFCMToken]; | ||
| } | ||
| } else { | ||
| if ([self.delegate respondsToSelector:@selector(messaging:didReceiveRegistrationToken:)]) { | ||
| [self.delegate messaging:self didReceiveRegistrationToken:self.tokenManager.defaultFCMToken]; | ||
| } | ||
| } | ||
| // Should always trigger the token refresh notification when the delegate method is called | ||
| NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.