Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Firebase/InstanceID/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 2020-08 -- 4.6.0
- [added] Added a new notification listening token refresh from Messaging and update the token cache in InstanceID. (#6286)
- [fixed] Fixed an issue that token refresh notification is not triggered when use `tokenWithAuthorizedEntity:scope:options:handler` to get token. (#6286)

# 2020-07 -- 4.5.1
- [changed] Remove FIRInstanceIDURLQueryItem in favor of NSURLQueryItem. (#5835)

Expand Down
60 changes: 49 additions & 11 deletions Firebase/InstanceID/FIRInstanceID.m
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,10 @@ - (void)tokenWithAuthorizedEntity:(NSString *)authorizedEntity
}

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

FIRInstanceIDDeleteTokenHandler newHandler = ^(NSError *error) {
// If a default token is deleted successfully, reset the defaultFCMToken too.
if (!error && [authorizedEntity isEqualToString:self.fcmSenderID] &&
[scope isEqualToString:kFIRInstanceIDDefaultTokenScope]) {
if (!error && [self isDefaultTokenWithAuthorizedEntity:authorizedEntity scope:scope]) {
self.defaultFCMToken = nil;
}
dispatch_async(dispatch_get_main_queue(), ^{
Expand Down Expand Up @@ -707,6 +710,7 @@ - (void)setupNotificationListeners {
name:kFIRInstanceIDAPNSTokenNotification
object:nil];
[self observeFirebaseInstallationIDChanges];
[self observeFirebaseMessagingTokenChanges];
}

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

NSDictionary *instanceIDOptions = @{};
BOOL hasFirebaseMessaging = NSClassFromString(kFIRInstanceIDFCMSDKClassString) != nil;
if (hasFirebaseMessaging && self.apnsTokenData) {
BOOL isSandboxApp = (self.apnsTokenType == FIRInstanceIDAPNSTokenTypeSandbox);
if (self.apnsTokenType == FIRInstanceIDAPNSTokenTypeUnknown) {
isSandboxApp = [self isSandboxApp];
}
instanceIDOptions = @{
kFIRInstanceIDTokenOptionsAPNSKey : self.apnsTokenData,
kFIRInstanceIDTokenOptionsAPNSIsSandboxKey : @(isSandboxApp),
};
if (hasFirebaseMessaging) {
instanceIDOptions = [self defaultTokenOptions];
}

FIRInstanceID_WEAKIFY(self);
Expand Down Expand Up @@ -871,6 +868,11 @@ - (void)retryGetDefaultTokenAfter:(NSTimeInterval)retryInterval {
});
}

- (BOOL)isDefaultTokenWithAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope {
return [authorizedEntity isEqualToString:self.fcmSenderID] &&
[scope isEqualToString:kFIRInstanceIDDefaultTokenScope];
}

#pragma mark - APNS Token
// This should only be triggered from FCM.
- (void)notifyAPNSTokenIsSet:(NSNotification *)notification {
Expand Down Expand Up @@ -1117,4 +1119,40 @@ - (void)observeFirebaseInstallationIDChanges {
object:nil];
}

- (void)observeFirebaseMessagingTokenChanges {
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:kFIRInstanceIDMessagingUpdateTokenNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(messagingTokenDidChangeNotificationReceived:)
name:kFIRInstanceIDMessagingUpdateTokenNotification
object:nil];
}

- (void)messagingTokenDidChangeNotificationReceived:(NSNotification *)notification {
NSString *tokenUpdatedFromMessaging = notification.object;
if (!tokenUpdatedFromMessaging || [tokenUpdatedFromMessaging isKindOfClass:[NSString class]]) {
self.defaultFCMToken = tokenUpdatedFromMessaging;
[self.tokenManager saveDefaultToken:tokenUpdatedFromMessaging
withOptions:[self defaultTokenOptions]];
}
}

- (NSDictionary *)defaultTokenOptions {
NSDictionary *tokenOptions = @{};
if (self.apnsTokenData) {
BOOL isSandboxApp = (self.apnsTokenType == FIRInstanceIDAPNSTokenTypeSandbox);
if (self.apnsTokenType == FIRInstanceIDAPNSTokenTypeUnknown) {
isSandboxApp = [self isSandboxApp];
}
tokenOptions = @{
kFIRInstanceIDTokenOptionsAPNSKey : self.apnsTokenData,
kFIRInstanceIDTokenOptionsAPNSIsSandboxKey : @(isSandboxApp),
};
}
return tokenOptions;
}

@end
1 change: 1 addition & 0 deletions Firebase/InstanceID/FIRInstanceIDAuthKeyChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ NS_ASSUME_NONNULL_BEGIN
account:(NSString *)account
handler:(nullable void (^)(NSError *))handler;

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

NS_ASSUME_NONNULL_END
12 changes: 12 additions & 0 deletions Firebase/InstanceID/FIRInstanceIDAuthKeyChain.m
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,16 @@ - (void)setData:(NSData *)data
}
}

- (void)setDataInCache:(NSData *)data forService:(NSString *)service account:(NSString *)account {
if (_cachedKeychainData[service]) {
if (_cachedKeychainData[service][account]) {
_cachedKeychainData[service][account] = @[ data ];
} else {
[_cachedKeychainData[service] setObject:@[ data ] forKey:account];
}
} else {
[_cachedKeychainData setObject:[@{account : @[ data ]} mutableCopy] forKey:service];
}
}

@end
2 changes: 1 addition & 1 deletion Firebase/InstanceID/FIRInstanceIDConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ FOUNDATION_EXPORT NSString *const kFIRInstanceID_CMD_RST;
FOUNDATION_EXPORT NSString *const kFIRInstanceIDCheckinFetchedNotification;
FOUNDATION_EXPORT NSString *const kFIRInstanceIDAPNSTokenNotification;
FOUNDATION_EXPORT NSString *const kFIRInstanceIDDefaultGCMTokenFailNotification;

FOUNDATION_EXPORT NSString *const kFIRInstanceIDMessagingUpdateTokenNotification;
FOUNDATION_EXPORT NSString *const kFIRInstanceIDIdentityInvalidatedNotification;

#pragma mark - Miscellaneous
Expand Down
3 changes: 2 additions & 1 deletion Firebase/InstanceID/FIRInstanceIDConstants.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
NSString *const kFIRInstanceIDAPNSTokenNotification = @"com.firebase.iid.notif.apns-token";
NSString *const kFIRInstanceIDDefaultGCMTokenFailNotification =
@"com.firebase.iid.notif.fcm-token-fail";

NSString *const kFIRInstanceIDMessagingUpdateTokenNotification =
@"com.firebase.messaging.notif.fcm-token-refreshed";
NSString *const kFIRInstanceIDIdentityInvalidatedNotification = @"com.google.iid.identity-invalid";

// Miscellaneous
Expand Down
5 changes: 5 additions & 0 deletions Firebase/InstanceID/FIRInstanceIDStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)saveTokenInfo:(FIRInstanceIDTokenInfo *)tokenInfo handler:(void (^)(NSError *))handler;

/*
* Save instanceID token info to cache only.
*/
- (void)saveTokenInfoInCacheOnly:(FIRInstanceIDTokenInfo *)tokenInfo;

#pragma mark - Get

/**
Expand Down
4 changes: 4 additions & 0 deletions Firebase/InstanceID/FIRInstanceIDStore.m
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,10 @@ - (void)saveTokenInfo:(FIRInstanceIDTokenInfo *)tokenInfo
[self.tokenStore saveTokenInfo:tokenInfo handler:handler];
}

- (void)saveTokenInfoInCacheOnly:(FIRInstanceIDTokenInfo *)tokenInfo {
[self.tokenStore saveTokenInfoInCacheOnly:tokenInfo];
}

#pragma mark - Delete

- (void)removeCachedTokenWithAuthorizedEntity:(NSString *)authorizedEntity scope:(NSString *)scope {
Expand Down
9 changes: 9 additions & 0 deletions Firebase/InstanceID/FIRInstanceIDTokenManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,13 @@ typedef NS_OPTIONS(NSUInteger, FIRInstanceIDInvalidTokenReason) {
- (NSArray<FIRInstanceIDTokenInfo *> *)updateTokensToAPNSDeviceToken:(NSData *)deviceToken
isSandbox:(BOOL)isSandbox;

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

@end
14 changes: 14 additions & 0 deletions Firebase/InstanceID/FIRInstanceIDTokenManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#import "FIRInstanceIDTokenFetchOperation.h"
#import "FIRInstanceIDTokenInfo.h"
#import "FIRInstanceIDTokenOperation.h"
#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h"
#import "NSError+FIRInstanceID.h"

@interface FIRInstanceIDTokenManager () <FIRInstanceIDStoreDelegate>
Expand Down Expand Up @@ -337,4 +338,17 @@ - (BOOL)checkTokenRefreshPolicyWithIID:(NSString *)IID {
return tokenInfosToDelete;
}

- (void)saveDefaultToken:(NSString *)defaultToken withOptions:(NSDictionary *)tokenOptions {
FIROptions *options = FIRApp.defaultApp.options;
FIRInstanceIDTokenInfo *tokenInfo =
[[FIRInstanceIDTokenInfo alloc] initWithAuthorizedEntity:options.GCMSenderID
scope:@"*"
token:defaultToken
appVersion:FIRInstanceIDCurrentAppVersion()
firebaseAppID:options.googleAppID];
tokenInfo.APNSInfo = [[FIRInstanceIDAPNSInfo alloc] initWithTokenOptionsDictionary:tokenOptions];

[self.instanceIDStore saveTokenInfoInCacheOnly:tokenInfo];
}

@end
5 changes: 5 additions & 0 deletions Firebase/InstanceID/FIRInstanceIDTokenStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ NS_ASSUME_NONNULL_BEGIN
- (void)saveTokenInfo:(FIRInstanceIDTokenInfo *)tokenInfo
handler:(nullable void (^)(NSError *))handler;

/*
* Save the instanceID token info to the cache only.
*/
- (void)saveTokenInfoInCacheOnly:(FIRInstanceIDTokenInfo *)tokenInfo;

#pragma mark - Delete

/**
Expand Down
14 changes: 14 additions & 0 deletions Firebase/InstanceID/FIRInstanceIDTokenStore.m
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,20 @@ - (void)saveTokenInfo:(FIRInstanceIDTokenInfo *)tokenInfo
[self.keychain setData:tokenInfoData forService:service account:account handler:handler];
}

- (void)saveTokenInfoInCacheOnly:(FIRInstanceIDTokenInfo *)tokenInfo {
tokenInfo.cacheTime = [NSDate date];
// Always write to the Keychain, so that the cacheTime is up-to-date.
NSData *tokenInfoData;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
tokenInfoData = [NSKeyedArchiver archivedDataWithRootObject:tokenInfo];
#pragma clang diagnostic pop
NSString *account = FIRInstanceIDAppIdentifier();
NSString *service = [[self class] serviceKeyForAuthorizedEntity:tokenInfo.authorizedEntity
scope:tokenInfo.scope];
[self.keychain setDataInCache:tokenInfoData forService:service account:account];
}

#pragma mark - Delete

- (void)removeTokenWithAuthorizedEntity:(nonnull NSString *)authorizedEntity
Expand Down
2 changes: 1 addition & 1 deletion FirebaseInstanceID.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'FirebaseInstanceID'
s.version = '4.5.1'
s.version = '4.6.0'
s.summary = 'Firebase InstanceID'

s.description = <<-DESC
Expand Down
4 changes: 2 additions & 2 deletions FirebaseMessaging.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'FirebaseMessaging'
s.version = '4.6.1'
s.version = '4.6.2'
s.summary = 'Firebase Messaging'

s.description = <<-DESC
Expand Down Expand Up @@ -55,7 +55,7 @@ device, and it is completely free.
s.osx.framework = 'SystemConfiguration'
s.weak_framework = 'UserNotifications'
s.dependency 'FirebaseCore', '~> 6.10'
s.dependency 'FirebaseInstanceID', '~> 4.3'
s.dependency 'FirebaseInstanceID', '~> 4.6'
s.dependency 'GoogleUtilities/AppDelegateSwizzler', '~> 6.7'
s.dependency 'GoogleUtilities/Reachability', '~> 6.7'
s.dependency 'GoogleUtilities/Environment', '~> 6.7'
Expand Down
2 changes: 1 addition & 1 deletion FirebaseMessaging/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# unreleased
# 2020-08 -- v.4.6.2
- [fixed] Fixed an issue that topic doesn't work in watchOS. (#6160)

# 2020-07 -- v4.6.1
Expand Down