-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Fix handler for multiple calls of -[FIRInstanceID instanceIDWithHandler:] (#2445) #2559
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 all commits
103fd65
2eecbd7
c6688d3
ba33d51
9db2c6f
1774829
39743fa
d70610f
88bed81
ccf0701
05bccdb
9b5a04a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ | |
#import <GoogleUtilities/GULAppEnvironmentUtil.h> | ||
#import "FIRInstanceID+Private.h" | ||
#import "FIRInstanceIDAuthService.h" | ||
#import "FIRInstanceIDCombinedHandler.h" | ||
#import "FIRInstanceIDConstants.h" | ||
#import "FIRInstanceIDDefines.h" | ||
#import "FIRInstanceIDKeyPairStore.h" | ||
|
@@ -114,9 +115,9 @@ @interface FIRInstanceID () | |
@property(nonatomic, readwrite, strong) FIRInstanceIDKeyPairStore *keyPairStore; | ||
|
||
// backoff and retry for default token | ||
@property(atomic, readwrite, assign) BOOL isFetchingDefaultToken; | ||
@property(atomic, readwrite, assign) BOOL isDefaultTokenFetchScheduled; | ||
@property(nonatomic, readwrite, assign) NSInteger retryCountForDefaultToken; | ||
@property(atomic, strong, nullable) | ||
FIRInstanceIDCombinedHandler<NSString *> *defaultTokenFetchHandler; | ||
|
||
@end | ||
|
||
|
@@ -831,10 +832,30 @@ - (NSInteger)retryIntervalToFetchDefaultToken { | |
kMaxRetryIntervalForDefaultTokenInSeconds); | ||
} | ||
|
||
- (void)defaultTokenWithHandler:(FIRInstanceIDTokenHandler)handler { | ||
if (self.isFetchingDefaultToken || self.isDefaultTokenFetchScheduled) { | ||
- (void)defaultTokenWithHandler:(nullable FIRInstanceIDTokenHandler)aHandler { | ||
[self defaultTokenWithRetry:NO handler:aHandler]; | ||
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. we can get rid of defaultTokenWithHandler: and use the new one instead every where. 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. I would prefer not to use @chliangGoogle Let me know if you still would prefer to get rid of it, I'll create a separate PR for it then. |
||
} | ||
|
||
/** | ||
* @param retry Indicates if the method is called to perform a retry after a failed attempt. | ||
* If `YES`, then actual token request will be performed even if `self.defaultTokenFetchHandler != | ||
* nil` | ||
*/ | ||
- (void)defaultTokenWithRetry:(BOOL)retry handler:(nullable FIRInstanceIDTokenHandler)aHandler { | ||
BOOL shouldPerformRequest = retry || self.defaultTokenFetchHandler == nil; | ||
|
||
if (!self.defaultTokenFetchHandler) { | ||
self.defaultTokenFetchHandler = [[FIRInstanceIDCombinedHandler<NSString *> alloc] init]; | ||
} | ||
|
||
if (aHandler) { | ||
[self.defaultTokenFetchHandler addHandler:aHandler]; | ||
} | ||
|
||
if (!shouldPerformRequest) { | ||
return; | ||
charlotteliang marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
NSDictionary *instanceIDOptions = @{}; | ||
BOOL hasFirebaseMessaging = NSClassFromString(kFIRInstanceIDFCMSDKClassString) != nil; | ||
if (hasFirebaseMessaging && self.apnsTokenData) { | ||
|
@@ -851,7 +872,6 @@ - (void)defaultTokenWithHandler:(FIRInstanceIDTokenHandler)handler { | |
FIRInstanceID_WEAKIFY(self); | ||
FIRInstanceIDTokenHandler newHandler = ^void(NSString *token, NSError *error) { | ||
FIRInstanceID_STRONGIFY(self); | ||
self.isFetchingDefaultToken = NO; | ||
|
||
if (error) { | ||
FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID009, | ||
|
@@ -871,21 +891,12 @@ - (void)defaultTokenWithHandler:(FIRInstanceIDTokenHandler)handler { | |
// Do not retry beyond the maximum limit. | ||
if (self.retryCountForDefaultToken < [[self class] maxRetryCountForDefaultToken]) { | ||
NSInteger retryInterval = [self retryIntervalToFetchDefaultToken]; | ||
FIRInstanceID_WEAKIFY(self); | ||
self.isDefaultTokenFetchScheduled = YES; | ||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(retryInterval * NSEC_PER_SEC)), | ||
dispatch_get_main_queue(), ^{ | ||
FIRInstanceID_STRONGIFY(self); | ||
self.isDefaultTokenFetchScheduled = NO; | ||
[self defaultTokenWithHandler:handler]; | ||
}); | ||
[self retryGetDefaultTokenAfter:retryInterval]; | ||
} else { | ||
FIRInstanceIDLoggerError(kFIRInstanceIDMessageCodeInstanceID007, | ||
@"Failed to retrieve the default FCM token after %ld retries", | ||
(long)self.retryCountForDefaultToken); | ||
if (handler) { | ||
handler(nil, error); | ||
} | ||
[self performDefaultTokenHandlerWithToken:nil error:error]; | ||
} | ||
} else { | ||
// If somebody updated IID with APNS token while our initial request did not have it | ||
|
@@ -904,13 +915,7 @@ - (void)defaultTokenWithHandler:(FIRInstanceIDTokenHandler)handler { | |
if (!APNSRemainedSameDuringFetch && hasFirebaseMessaging) { | ||
// APNs value did change mid-fetch, so the token should be re-fetched with the current APNs | ||
// value. | ||
self.isDefaultTokenFetchScheduled = YES; | ||
FIRInstanceID_WEAKIFY(self); | ||
dispatch_async(dispatch_get_main_queue(), ^{ | ||
FIRInstanceID_STRONGIFY(self); | ||
self.isDefaultTokenFetchScheduled = NO; | ||
[self defaultTokenWithHandler:handler]; | ||
}); | ||
[self retryGetDefaultTokenAfter:0]; | ||
FIRInstanceIDLoggerDebug(kFIRInstanceIDMessageCodeRefetchingTokenForAPNS, | ||
@"Received APNS token while fetching default token. " | ||
@"Refetching default token."); | ||
|
@@ -934,20 +939,41 @@ - (void)defaultTokenWithHandler:(FIRInstanceIDTokenHandler)handler { | |
object:[self.defaultFCMToken copy]]; | ||
[[NSNotificationQueue defaultQueue] enqueueNotification:tokenRefreshNotification | ||
postingStyle:NSPostASAP]; | ||
} | ||
if (handler) { | ||
handler(token, nil); | ||
|
||
[self performDefaultTokenHandlerWithToken:token error:nil]; | ||
} | ||
} | ||
}; | ||
|
||
self.isFetchingDefaultToken = YES; | ||
[self tokenWithAuthorizedEntity:self.fcmSenderID | ||
scope:kFIRInstanceIDDefaultTokenScope | ||
options:instanceIDOptions | ||
handler:newHandler]; | ||
} | ||
|
||
/** | ||
* | ||
*/ | ||
- (void)performDefaultTokenHandlerWithToken:(NSString *)token error:(NSError *)error { | ||
if (!self.defaultTokenFetchHandler) { | ||
return; | ||
} | ||
|
||
[self.defaultTokenFetchHandler combinedHandler](token, error); | ||
self.defaultTokenFetchHandler = nil; | ||
} | ||
|
||
- (void)retryGetDefaultTokenAfter:(NSTimeInterval)retryInterval { | ||
FIRInstanceID_WEAKIFY(self); | ||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(retryInterval * NSEC_PER_SEC)), | ||
dispatch_get_main_queue(), ^{ | ||
FIRInstanceID_STRONGIFY(self); | ||
// Pass nil: no new handlers to be added, currently existing handlers | ||
// will be called | ||
[self defaultTokenWithRetry:YES handler:nil]; | ||
}); | ||
} | ||
|
||
#pragma mark - APNS Token | ||
// This should only be triggered from FCM. | ||
- (void)notifyAPNSTokenIsSet:(NSNotification *)notification { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/* | ||
* Copyright 2019 Google | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#import <Foundation/Foundation.h> | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
/** | ||
* A generic class to combine several handler blocks into a single block in a thread-safe manner | ||
*/ | ||
@interface FIRInstanceIDCombinedHandler<ResultType> : NSObject | ||
charlotteliang marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- (void)addHandler:(void (^)(ResultType _Nullable result, NSError* _Nullable error))handler; | ||
- (void (^)(ResultType _Nullable result, NSError* _Nullable error))combinedHandler; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
Uh oh!
There was an error while loading. Please reload this page.