|
|
@@ -16,10 +16,10 @@
|
|
|
|
|
|
#import "FirebaseRemoteConfig/Sources/RCNConfigFetch.h"
|
|
|
|
|
|
+#import <FirebaseCore/FIRApp.h>
|
|
|
#import <FirebaseCore/FIRLogger.h>
|
|
|
#import <FirebaseCore/FIROptions.h>
|
|
|
-#import <FirebaseInstanceID/FIRInstanceID+Private.h>
|
|
|
-#import <FirebaseInstanceID/FIRInstanceIDCheckinPreferences.h>
|
|
|
+#import <FirebaseInstallations/FirebaseInstallations.h>
|
|
|
#import <GoogleUtilities/GULNSData+zlib.h>
|
|
|
#import "FirebaseRemoteConfig/Sources/Private/RCNConfigSettings.h"
|
|
|
#import "FirebaseRemoteConfig/Sources/RCNConfigConstants.h"
|
|
|
@@ -40,7 +40,6 @@ static NSString *const kServerURLNamespaces = @"/namespaces/";
|
|
|
static NSString *const kServerURLQuery = @":fetch?";
|
|
|
static NSString *const kServerURLKey = @"key=";
|
|
|
static NSString *const kRequestJSONKeyAppID = @"app_id";
|
|
|
-static NSString *const kRequestJSONKeyAppInstanceID = @"app_instance_id";
|
|
|
|
|
|
static NSString *const kHTTPMethodPost = @"POST"; ///< HTTP request method config fetch using
|
|
|
static NSString *const kContentTypeHeaderName = @"Content-Type"; ///< HTTP Header Field Name
|
|
|
@@ -49,13 +48,13 @@ static NSString *const kContentEncodingHeaderName =
|
|
|
static NSString *const kAcceptEncodingHeaderName = @"Accept-Encoding"; ///< HTTP Header Field Name
|
|
|
static NSString *const kETagHeaderName = @"etag"; ///< HTTP Header Field Name
|
|
|
static NSString *const kIfNoneMatchETagHeaderName = @"if-none-match"; ///< HTTP Header Field Name
|
|
|
+static NSString *const kInstallationsAuthTokenHeaderName = @"x-goog-firebase-installations-auth";
|
|
|
// Sends the bundle ID. Refer to b/130301479 for details.
|
|
|
static NSString *const kiOSBundleIdentifierHeaderName =
|
|
|
@"X-Ios-Bundle-Identifier"; ///< HTTP Header Field Name
|
|
|
|
|
|
/// Config HTTP request content type proto buffer
|
|
|
static NSString *const kContentTypeValueJSON = @"application/json";
|
|
|
-static NSString *const kInstanceIDScopeConfig = @"*"; /// InstanceID scope
|
|
|
|
|
|
/// HTTP status codes. Ref: https://cloud.google.com/apis/design/errors#error_retries
|
|
|
static NSInteger const kRCNFetchResponseHTTPStatusCodeOK = 200;
|
|
|
@@ -192,18 +191,22 @@ static RCNConfigFetcherTestBlock gGlobalTestBlock;
|
|
|
withError:error];
|
|
|
}
|
|
|
strongSelf->_settings.isFetchInProgress = YES;
|
|
|
- [strongSelf refreshInstanceIDTokenAndFetchCheckInInfoWithCompletionHandler:completionHandler];
|
|
|
+ [strongSelf refreshInstallationsTokenWithCompletionHandler:completionHandler];
|
|
|
});
|
|
|
}
|
|
|
|
|
|
#pragma mark - Fetch helpers
|
|
|
|
|
|
-/// Refresh instance ID token before fetching config. Instance ID is now mandatory for fetch
|
|
|
+- (NSString *)FIRAppNameFromFullyQualifiedNamespace {
|
|
|
+ return [[_FIRNamespace componentsSeparatedByString:@":"] lastObject];
|
|
|
+}
|
|
|
+/// Refresh installation ID token before fetching config. installation ID is now mandatory for fetch
|
|
|
/// requests to work.(b/14751422).
|
|
|
-- (void)refreshInstanceIDTokenAndFetchCheckInInfoWithCompletionHandler:
|
|
|
+- (void)refreshInstallationsTokenWithCompletionHandler:
|
|
|
(FIRRemoteConfigFetchCompletion)completionHandler {
|
|
|
- FIRInstanceID *instanceID = [FIRInstanceID instanceID];
|
|
|
- if (!_options.GCMSenderID) {
|
|
|
+ FIRInstallations *installations = [FIRInstallations
|
|
|
+ installationsWithApp:[FIRApp appNamed:[self FIRAppNameFromFullyQualifiedNamespace]]];
|
|
|
+ if (!installations || !_options.GCMSenderID) {
|
|
|
NSString *errorDescription = @"Failed to get GCMSenderID";
|
|
|
FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000074", @"%@",
|
|
|
[NSString stringWithFormat:@"%@", errorDescription]);
|
|
|
@@ -217,10 +220,11 @@ static RCNConfigFetcherTestBlock gGlobalTestBlock;
|
|
|
NSLocalizedDescriptionKey : errorDescription
|
|
|
}]];
|
|
|
}
|
|
|
- FIRInstanceIDTokenHandler instanceIDHandler = ^(NSString *token, NSError *error) {
|
|
|
- if (!token || error) {
|
|
|
+ FIRInstallationsTokenHandler installationsTokenHandler = ^(
|
|
|
+ FIRInstallationsAuthTokenResult *tokenResult, NSError *error) {
|
|
|
+ if (!tokenResult || !tokenResult.authToken || error) {
|
|
|
NSString *errorDescription =
|
|
|
- [NSString stringWithFormat:@"Failed to get InstanceID token. Error : %@.", error];
|
|
|
+ [NSString stringWithFormat:@"Failed to get installations token. Error : %@.", error];
|
|
|
FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000073", @"%@",
|
|
|
[NSString stringWithFormat:@"%@", errorDescription]);
|
|
|
self->_settings.isFetchInProgress = NO;
|
|
|
@@ -234,9 +238,10 @@ static RCNConfigFetcherTestBlock gGlobalTestBlock;
|
|
|
}]];
|
|
|
}
|
|
|
|
|
|
- // If the token is available, try to get the instanceID.
|
|
|
+ // We have a valid token. Get the backing installationID.
|
|
|
__weak RCNConfigFetch *weakSelf = self;
|
|
|
- [instanceID getIDWithHandler:^(NSString *_Nullable identity, NSError *_Nullable error) {
|
|
|
+ [installations installationIDWithCompletion:^(NSString *_Nullable identifier,
|
|
|
+ NSError *_Nullable error) {
|
|
|
RCNConfigFetch *strongSelf = weakSelf;
|
|
|
|
|
|
// Dispatch to the RC serial queue to update settings on the queue.
|
|
|
@@ -244,10 +249,10 @@ static RCNConfigFetcherTestBlock gGlobalTestBlock;
|
|
|
RCNConfigFetch *strongSelfQueue = weakSelf;
|
|
|
|
|
|
// Update config settings with the IID and token.
|
|
|
- strongSelfQueue->_settings.configInstanceIDToken = [token copy];
|
|
|
- strongSelfQueue->_settings.configInstanceID = identity;
|
|
|
+ strongSelfQueue->_settings.configInstallationsToken = tokenResult.authToken;
|
|
|
+ strongSelfQueue->_settings.configInstallationsIdentifier = identifier;
|
|
|
|
|
|
- if (!identity || error) {
|
|
|
+ if (!identifier || error) {
|
|
|
NSString *errorDescription =
|
|
|
[NSString stringWithFormat:@"Error getting iid : %@.", error];
|
|
|
FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000055", @"%@",
|
|
|
@@ -265,56 +270,23 @@ static RCNConfigFetcherTestBlock gGlobalTestBlock;
|
|
|
}
|
|
|
|
|
|
FIRLogInfo(kFIRLoggerRemoteConfig, @"I-RCN000022", @"Success to get iid : %@.",
|
|
|
- strongSelfQueue->_settings.configInstanceID);
|
|
|
-
|
|
|
- // Continue the fetch regardless of whether fetch of instance ID succeeded.
|
|
|
- [strongSelfQueue fetchCheckinInfoWithCompletionHandler:completionHandler];
|
|
|
+ strongSelfQueue->_settings.configInstallationsIdentifier);
|
|
|
+ [strongSelf
|
|
|
+ getAnalyticsUserPropertiesWithCompletionHandler:^(NSDictionary *userProperties) {
|
|
|
+ dispatch_async(strongSelf->_lockQueue, ^{
|
|
|
+ [strongSelf fetchWithUserProperties:userProperties
|
|
|
+ completionHandler:completionHandler];
|
|
|
+ });
|
|
|
+ }];
|
|
|
});
|
|
|
}];
|
|
|
};
|
|
|
- FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000039", @"Starting requesting token.");
|
|
|
- // Note: We expect the GCMSenderID to always be available by the time this request is made.
|
|
|
- [instanceID tokenWithAuthorizedEntity:_options.GCMSenderID
|
|
|
- scope:kInstanceIDScopeConfig
|
|
|
- options:nil
|
|
|
- handler:instanceIDHandler];
|
|
|
-}
|
|
|
|
|
|
-/// Fetch checkin info before fetching config. Checkin info including device authentication ID,
|
|
|
-/// secret token and device data version are optional fields in config request.
|
|
|
-- (void)fetchCheckinInfoWithCompletionHandler:(FIRRemoteConfigFetchCompletion)completionHandler {
|
|
|
- FIRInstanceID *instanceID = [FIRInstanceID instanceID];
|
|
|
- __weak RCNConfigFetch *weakSelf = self;
|
|
|
- [instanceID fetchCheckinInfoWithHandler:^(FIRInstanceIDCheckinPreferences *preferences,
|
|
|
- NSError *error) {
|
|
|
- RCNConfigFetch *fetchCheckinInfoWithHandlerSelf = weakSelf;
|
|
|
- dispatch_async(fetchCheckinInfoWithHandlerSelf->_lockQueue, ^{
|
|
|
- RCNConfigFetch *strongSelf = fetchCheckinInfoWithHandlerSelf;
|
|
|
- if (error) {
|
|
|
- FIRLogError(kFIRLoggerRemoteConfig, @"I-RCN000023", @"Failed to fetch checkin info: %@.",
|
|
|
- error);
|
|
|
- } else {
|
|
|
- strongSelf->_settings.deviceAuthID = preferences.deviceID;
|
|
|
- strongSelf->_settings.secretToken = preferences.secretToken;
|
|
|
- strongSelf->_settings.deviceDataVersion = preferences.deviceDataVersion;
|
|
|
- if (strongSelf->_settings.deviceAuthID.length && strongSelf->_settings.secretToken.length) {
|
|
|
- FIRLogInfo(kFIRLoggerRemoteConfig, @"I-RCN000024",
|
|
|
- @"Success to get device authentication ID: %@, security token: %@.",
|
|
|
- self->_settings.deviceAuthID, self->_settings.secretToken);
|
|
|
- }
|
|
|
- }
|
|
|
- // Checkin info is optional, continue fetch config regardless fetch of checkin info
|
|
|
- // succeeded.
|
|
|
- [strongSelf fetchWithUserPropertiesCompletionHandler:^(NSDictionary *userProperties) {
|
|
|
- dispatch_async(strongSelf->_lockQueue, ^{
|
|
|
- [strongSelf fetchWithUserProperties:userProperties completionHandler:completionHandler];
|
|
|
- });
|
|
|
- }];
|
|
|
- });
|
|
|
- }];
|
|
|
+ FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000039", @"Starting requesting token.");
|
|
|
+ [installations authTokenWithCompletion:installationsTokenHandler];
|
|
|
}
|
|
|
|
|
|
-- (void)fetchWithUserPropertiesCompletionHandler:
|
|
|
+- (void)getAnalyticsUserPropertiesWithCompletionHandler:
|
|
|
(FIRAInteropUserPropertiesCallback)completionHandler {
|
|
|
FIRLogDebug(kFIRLoggerRemoteConfig, @"I-RCN000060", @"Fetch with user properties completed.");
|
|
|
id<FIRAnalyticsInterop> analytics = self->_analytics;
|
|
|
@@ -590,6 +562,8 @@ static RCNConfigFetcherTestBlock gGlobalTestBlock;
|
|
|
timeoutInterval:timeoutInterval];
|
|
|
URLRequest.HTTPMethod = kHTTPMethodPost;
|
|
|
[URLRequest setValue:kContentTypeValueJSON forHTTPHeaderField:kContentTypeHeaderName];
|
|
|
+ [URLRequest setValue:_settings.configInstallationsToken
|
|
|
+ forHTTPHeaderField:kInstallationsAuthTokenHeaderName];
|
|
|
[URLRequest setValue:[[NSBundle mainBundle] bundleIdentifier]
|
|
|
forHTTPHeaderField:kiOSBundleIdentifierHeaderName];
|
|
|
[URLRequest setValue:@"gzip" forHTTPHeaderField:kContentEncodingHeaderName];
|