Skip to content

Commit fbcb4a1

Browse files
Update InstanceID to listen to a notification from Messaging (#6286)
1 parent 7ba2dd4 commit fbcb4a1

15 files changed

+124
-17
lines changed

Firebase/InstanceID/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 2020-08 -- 4.6.0
2+
- [added] Added a new notification listening token refresh from Messaging and update the token cache in InstanceID. (#6286)
3+
- [fixed] Fixed an issue that token refresh notification is not triggered when use `tokenWithAuthorizedEntity:scope:options:handler` to get token. (#6286)
4+
15
# 2020-07 -- 4.5.1
26
- [changed] Remove FIRInstanceIDURLQueryItem in favor of NSURLQueryItem. (#5835)
37

Firebase/InstanceID/FIRInstanceID.m

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,10 @@ - (void)tokenWithAuthorizedEntity:(NSString *)authorizedEntity
302302
}
303303

304304
FIRInstanceIDTokenHandler newHandler = ^(NSString *token, NSError *error) {
305+
if (!error && [self isDefaultTokenWithAuthorizedEntity:authorizedEntity scope:scope]) {
306+
// The local cache should be updated as it is critical for sending token updates.
307+
self.defaultFCMToken = token;
308+
}
305309
dispatch_async(dispatch_get_main_queue(), ^{
306310
handler(token, error);
307311
});
@@ -381,8 +385,7 @@ - (void)deleteTokenWithAuthorizedEntity:(NSString *)authorizedEntity
381385

382386
FIRInstanceIDDeleteTokenHandler newHandler = ^(NSError *error) {
383387
// If a default token is deleted successfully, reset the defaultFCMToken too.
384-
if (!error && [authorizedEntity isEqualToString:self.fcmSenderID] &&
385-
[scope isEqualToString:kFIRInstanceIDDefaultTokenScope]) {
388+
if (!error && [self isDefaultTokenWithAuthorizedEntity:authorizedEntity scope:scope]) {
386389
self.defaultFCMToken = nil;
387390
}
388391
dispatch_async(dispatch_get_main_queue(), ^{
@@ -707,6 +710,7 @@ - (void)setupNotificationListeners {
707710
name:kFIRInstanceIDAPNSTokenNotification
708711
object:nil];
709712
[self observeFirebaseInstallationIDChanges];
713+
[self observeFirebaseMessagingTokenChanges];
710714
}
711715

712716
#pragma mark - Private Helpers
@@ -763,15 +767,8 @@ - (void)defaultTokenWithRetry:(BOOL)retry handler:(nullable FIRInstanceIDTokenHa
763767

764768
NSDictionary *instanceIDOptions = @{};
765769
BOOL hasFirebaseMessaging = NSClassFromString(kFIRInstanceIDFCMSDKClassString) != nil;
766-
if (hasFirebaseMessaging && self.apnsTokenData) {
767-
BOOL isSandboxApp = (self.apnsTokenType == FIRInstanceIDAPNSTokenTypeSandbox);
768-
if (self.apnsTokenType == FIRInstanceIDAPNSTokenTypeUnknown) {
769-
isSandboxApp = [self isSandboxApp];
770-
}
771-
instanceIDOptions = @{
772-
kFIRInstanceIDTokenOptionsAPNSKey : self.apnsTokenData,
773-
kFIRInstanceIDTokenOptionsAPNSIsSandboxKey : @(isSandboxApp),
774-
};
770+
if (hasFirebaseMessaging) {
771+
instanceIDOptions = [self defaultTokenOptions];
775772
}
776773

777774
FIRInstanceID_WEAKIFY(self);
@@ -871,6 +868,11 @@ - (void)retryGetDefaultTokenAfter:(NSTimeInterval)retryInterval {
871868
});
872869
}
873870

871+
- (BOOL)isDefaultTokenWithAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope {
872+
return [authorizedEntity isEqualToString:self.fcmSenderID] &&
873+
[scope isEqualToString:kFIRInstanceIDDefaultTokenScope];
874+
}
875+
874876
#pragma mark - APNS Token
875877
// This should only be triggered from FCM.
876878
- (void)notifyAPNSTokenIsSet:(NSNotification *)notification {
@@ -1117,4 +1119,40 @@ - (void)observeFirebaseInstallationIDChanges {
11171119
object:nil];
11181120
}
11191121

1122+
- (void)observeFirebaseMessagingTokenChanges {
1123+
[[NSNotificationCenter defaultCenter]
1124+
removeObserver:self
1125+
name:kFIRInstanceIDMessagingUpdateTokenNotification
1126+
object:nil];
1127+
[[NSNotificationCenter defaultCenter]
1128+
addObserver:self
1129+
selector:@selector(messagingTokenDidChangeNotificationReceived:)
1130+
name:kFIRInstanceIDMessagingUpdateTokenNotification
1131+
object:nil];
1132+
}
1133+
1134+
- (void)messagingTokenDidChangeNotificationReceived:(NSNotification *)notification {
1135+
NSString *tokenUpdatedFromMessaging = notification.object;
1136+
if (!tokenUpdatedFromMessaging || [tokenUpdatedFromMessaging isKindOfClass:[NSString class]]) {
1137+
self.defaultFCMToken = tokenUpdatedFromMessaging;
1138+
[self.tokenManager saveDefaultToken:tokenUpdatedFromMessaging
1139+
withOptions:[self defaultTokenOptions]];
1140+
}
1141+
}
1142+
1143+
- (NSDictionary *)defaultTokenOptions {
1144+
NSDictionary *tokenOptions = @{};
1145+
if (self.apnsTokenData) {
1146+
BOOL isSandboxApp = (self.apnsTokenType == FIRInstanceIDAPNSTokenTypeSandbox);
1147+
if (self.apnsTokenType == FIRInstanceIDAPNSTokenTypeUnknown) {
1148+
isSandboxApp = [self isSandboxApp];
1149+
}
1150+
tokenOptions = @{
1151+
kFIRInstanceIDTokenOptionsAPNSKey : self.apnsTokenData,
1152+
kFIRInstanceIDTokenOptionsAPNSIsSandboxKey : @(isSandboxApp),
1153+
};
1154+
}
1155+
return tokenOptions;
1156+
}
1157+
11201158
@end

Firebase/InstanceID/FIRInstanceIDAuthKeyChain.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ NS_ASSUME_NONNULL_BEGIN
9090
account:(NSString *)account
9191
handler:(nullable void (^)(NSError *))handler;
9292

93+
- (void)setDataInCache:(NSData *)data forService:(NSString *)service account:(NSString *)account;
9394
@end
9495

9596
NS_ASSUME_NONNULL_END

Firebase/InstanceID/FIRInstanceIDAuthKeyChain.m

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,4 +213,16 @@ - (void)setData:(NSData *)data
213213
}
214214
}
215215

216+
- (void)setDataInCache:(NSData *)data forService:(NSString *)service account:(NSString *)account {
217+
if (_cachedKeychainData[service]) {
218+
if (_cachedKeychainData[service][account]) {
219+
_cachedKeychainData[service][account] = @[ data ];
220+
} else {
221+
[_cachedKeychainData[service] setObject:@[ data ] forKey:account];
222+
}
223+
} else {
224+
[_cachedKeychainData setObject:[@{account : @[ data ]} mutableCopy] forKey:service];
225+
}
226+
}
227+
216228
@end

Firebase/InstanceID/FIRInstanceIDConstants.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ FOUNDATION_EXPORT NSString *const kFIRInstanceID_CMD_RST;
3030
FOUNDATION_EXPORT NSString *const kFIRInstanceIDCheckinFetchedNotification;
3131
FOUNDATION_EXPORT NSString *const kFIRInstanceIDAPNSTokenNotification;
3232
FOUNDATION_EXPORT NSString *const kFIRInstanceIDDefaultGCMTokenFailNotification;
33-
33+
FOUNDATION_EXPORT NSString *const kFIRInstanceIDMessagingUpdateTokenNotification;
3434
FOUNDATION_EXPORT NSString *const kFIRInstanceIDIdentityInvalidatedNotification;
3535

3636
#pragma mark - Miscellaneous

Firebase/InstanceID/FIRInstanceIDConstants.m

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
NSString *const kFIRInstanceIDAPNSTokenNotification = @"com.firebase.iid.notif.apns-token";
2525
NSString *const kFIRInstanceIDDefaultGCMTokenFailNotification =
2626
@"com.firebase.iid.notif.fcm-token-fail";
27-
27+
NSString *const kFIRInstanceIDMessagingUpdateTokenNotification =
28+
@"com.firebase.messaging.notif.fcm-token-refreshed";
2829
NSString *const kFIRInstanceIDIdentityInvalidatedNotification = @"com.google.iid.identity-invalid";
2930

3031
// Miscellaneous

Firebase/InstanceID/FIRInstanceIDStore.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ NS_ASSUME_NONNULL_BEGIN
8585
*/
8686
- (void)saveTokenInfo:(FIRInstanceIDTokenInfo *)tokenInfo handler:(void (^)(NSError *))handler;
8787

88+
/*
89+
* Save instanceID token info to cache only.
90+
*/
91+
- (void)saveTokenInfoInCacheOnly:(FIRInstanceIDTokenInfo *)tokenInfo;
92+
8893
#pragma mark - Get
8994

9095
/**

Firebase/InstanceID/FIRInstanceIDStore.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,10 @@ - (void)saveTokenInfo:(FIRInstanceIDTokenInfo *)tokenInfo
202202
[self.tokenStore saveTokenInfo:tokenInfo handler:handler];
203203
}
204204

205+
- (void)saveTokenInfoInCacheOnly:(FIRInstanceIDTokenInfo *)tokenInfo {
206+
[self.tokenStore saveTokenInfoInCacheOnly:tokenInfo];
207+
}
208+
205209
#pragma mark - Delete
206210

207211
- (void)removeCachedTokenWithAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope {

Firebase/InstanceID/FIRInstanceIDTokenManager.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,13 @@ typedef NS_OPTIONS(NSUInteger, FIRInstanceIDInvalidTokenReason) {
146146
- (NSArray<FIRInstanceIDTokenInfo *> *)updateTokensToAPNSDeviceToken:(NSData *)deviceToken
147147
isSandbox:(BOOL)isSandbox;
148148

149+
/*
150+
* This method is only called when Messaging SDK is installed and a new token is triggered
151+
* by Messaging.
152+
* Update default token in cache if the token is updated from a newer versio of Messaging.
153+
* This is used when newer version of Messaging SDK will update the token in storage
154+
* and notify instanceID to update its own cache as well. No need to write to storage again.
155+
*/
156+
- (void)saveDefaultToken:(NSString *)defaultToken withOptions:(NSDictionary *)tokenOptions;
157+
149158
@end

Firebase/InstanceID/FIRInstanceIDTokenManager.m

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#import "FIRInstanceIDTokenFetchOperation.h"
2828
#import "FIRInstanceIDTokenInfo.h"
2929
#import "FIRInstanceIDTokenOperation.h"
30+
#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h"
3031
#import "NSError+FIRInstanceID.h"
3132

3233
@interface FIRInstanceIDTokenManager () <FIRInstanceIDStoreDelegate>
@@ -337,4 +338,17 @@ - (BOOL)checkTokenRefreshPolicyWithIID:(NSString *)IID {
337338
return tokenInfosToDelete;
338339
}
339340

341+
- (void)saveDefaultToken:(NSString *)defaultToken withOptions:(NSDictionary *)tokenOptions {
342+
FIROptions *options = FIRApp.defaultApp.options;
343+
FIRInstanceIDTokenInfo *tokenInfo =
344+
[[FIRInstanceIDTokenInfo alloc] initWithAuthorizedEntity:options.GCMSenderID
345+
scope:@"*"
346+
token:defaultToken
347+
appVersion:FIRInstanceIDCurrentAppVersion()
348+
firebaseAppID:options.googleAppID];
349+
tokenInfo.APNSInfo = [[FIRInstanceIDAPNSInfo alloc] initWithTokenOptionsDictionary:tokenOptions];
350+
351+
[self.instanceIDStore saveTokenInfoInCacheOnly:tokenInfo];
352+
}
353+
340354
@end

0 commit comments

Comments
 (0)