aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--AuthSamples/Sample/MainViewController.m80
-rw-r--r--AuthSamples/Sample/StaticContentTableViewManager.h2
-rw-r--r--AuthSamples/Sample/UIViewController+Alerts.h2
-rw-r--r--AuthSamples/Samples.xcodeproj/project.pbxproj4
-rw-r--r--Firebase/Auth/Source/FIRAuth.m88
-rw-r--r--Firebase/Auth/Source/FIRAuth_Internal.h6
-rw-r--r--Firebase/Auth/Source/FIRUser.m2
7 files changed, 144 insertions, 40 deletions
diff --git a/AuthSamples/Sample/MainViewController.m b/AuthSamples/Sample/MainViewController.m
index 20f76fe..9876195 100644
--- a/AuthSamples/Sample/MainViewController.m
+++ b/AuthSamples/Sample/MainViewController.m
@@ -20,6 +20,7 @@
#import "FIRAdditionalUserInfo.h"
#import "FIRApp.h"
+#import "FIRAppAssociationRegistration.h"
#import "FIROAuthProvider.h"
#import "FIRPhoneAuthCredential.h"
#import "FIRPhoneAuthProvider.h"
@@ -362,6 +363,11 @@ static NSString *const kCreateUserTitle = @"Create User";
*/
static NSString *const kDeleteAppTitle = @"Delete App";
+/** @var kTimeAuthInitTitle
+ @brief The text of the "Time Auth Initialization" button.
+ */
+static NSString *const kTimeAuthInitTitle = @"Time Auth Initialization";
+
/** @var kSectionTitleManualTests
@brief The section title for automated manual tests.
*/
@@ -493,6 +499,30 @@ typedef void (^FIRTokenCallback)(NSString *_Nullable token, NSError *_Nullable e
- (void)getTokenForcingRefresh:(BOOL)forceRefresh withCallback:(nonnull FIRTokenCallback)callback;
@end
+/** @category FIRAppAssociationRegistration(Deregistration)
+ @brief The category for the deregistration method.
+ */
+@interface FIRAppAssociationRegistration (Deregistration)
+/** @fn deregisteredObjectWithHost:key:
+ @brief Removes the object that was registered with a particular host and key, if one exists.
+ @param host The host object.
+ @param key The key to specify the registered object on the host.
+ */
++ (void)deregisterObjectWithHost:(id)host key:(NSString *)key;
+@end
+
+@implementation FIRAppAssociationRegistration (Deregistration)
+
++ (void)deregisterObjectWithHost:(id)host key:(NSString *)key {
+ @synchronized(self) {
+ SEL dictKey = @selector(registeredObjectWithHost:key:creationBlock:);
+ NSMutableDictionary<NSString *, id> *objectsByKey = objc_getAssociatedObject(host, dictKey);
+ [objectsByKey removeObjectForKey:key];
+ }
+}
+
+@end
+
@implementation MainViewController {
NSMutableString *_consoleString;
@@ -681,7 +711,9 @@ typedef void (^FIRTokenCallback)(NSString *_Nullable token, NSError *_Nullable e
[StaticContentTableViewCell cellWithTitle:kTokenGetButtonText
action:^{ [weakSelf getAppTokenWithForce:NO]; }],
[StaticContentTableViewCell cellWithTitle:kTokenRefreshButtonText
- action:^{ [weakSelf getAppTokenWithForce:YES]; }]
+ action:^{ [weakSelf getAppTokenWithForce:YES]; }],
+ [StaticContentTableViewCell cellWithTitle:kTimeAuthInitTitle
+ action:^{ [weakSelf timeAuthInitialization]; }]
]],
[StaticContentTableViewSection sectionWithTitle:kSectionTitleListeners cells:@[
[StaticContentTableViewCell cellWithTitle:kAddAuthStateListenerTitle
@@ -730,8 +762,8 @@ typedef void (^FIRTokenCallback)(NSString *_Nullable token, NSError *_Nullable e
/** @fn signInWithProvider:provider:
@brief Perform sign in with credential operataion, for given auth provider.
- @provider The auth provider.
- @callback The callback to continue the flow which executed this sign-in.
+ @param provider The auth provider.
+ @param callback The callback to continue the flow which executed this sign-in.
*/
- (void)signInWithProvider:(nonnull id<AuthProvider>)provider callback:(void(^)(void))callback {
if (!provider) {
@@ -2382,6 +2414,48 @@ typedef void (^FIRTokenCallback)(NSString *_Nullable token, NSError *_Nullable e
}];
}
+/** @fn timeAuthInitialization
+ @brief Times FIRAuth instance initialization time.
+ */
+- (void)timeAuthInitialization {
+ // Temporarily disable auth state listener to avoid interfering with the result.
+ [[NSNotificationCenter defaultCenter] removeObserver:self
+ name:FIRAuthStateDidChangeNotification
+ object:nil];
+ [self showSpinner:^() {
+ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^() {
+ const int numberOfRuns = 4096;
+ FIRApp *app = [FIRApp defaultApp];
+ NSString *key = NSStringFromClass([FIRAuth class]);
+ NSDate *startTime = [NSDate date];
+ for (int i = 0; i < numberOfRuns; i++) {
+ @autoreleasepool {
+ [FIRAppAssociationRegistration deregisterObjectWithHost:app key:key];
+ [FIRAuth auth];
+ }
+ }
+ NSDate *endTime = [NSDate date];
+ dispatch_async(dispatch_get_main_queue(), ^() {
+ // Re-enable auth state listener.
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(authStateChangedForAuth:)
+ name:FIRAuthStateDidChangeNotification
+ object:nil];
+ [self hideSpinner:^() {
+ NSTimeInterval averageTime = [endTime timeIntervalSinceDate:startTime] / numberOfRuns;
+ NSString *message = [NSString stringWithFormat:
+ @"Each [FIRAuth auth] takes average of %.3f ms for %d runs",
+ averageTime * 1000, numberOfRuns];
+ [self showMessagePromptWithTitle:@"Timing Result"
+ message:message
+ showCancelButton:NO
+ completion:nil];
+ }];
+ });
+ });
+ }];
+}
+
#pragma mark - Helpers
/** @fn user
diff --git a/AuthSamples/Sample/StaticContentTableViewManager.h b/AuthSamples/Sample/StaticContentTableViewManager.h
index cb56391..5a7c123 100644
--- a/AuthSamples/Sample/StaticContentTableViewManager.h
+++ b/AuthSamples/Sample/StaticContentTableViewManager.h
@@ -242,8 +242,6 @@ typedef void(^StaticContentTableViewCellAction)(void);
@param customCell The custom @c UITableViewCell to use for this cell.
@param title If no custom cell is being used, this is the text of the @c titleLabel of the
@c UITableViewCell.
- @param title If no custom cell is being used, this is the text of the @c detailTextLabel of the
- @c UITableViewCell.
@param action A block which is executed when the cell is selected.
@param accessibilityID The accessibility ID to add to the cell.
*/
diff --git a/AuthSamples/Sample/UIViewController+Alerts.h b/AuthSamples/Sample/UIViewController+Alerts.h
index 375a0ed..88686c1 100644
--- a/AuthSamples/Sample/UIViewController+Alerts.h
+++ b/AuthSamples/Sample/UIViewController+Alerts.h
@@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
*/
typedef void (^AlertPromptCompletionBlock)(BOOL userPressedOK, NSString *_Nullable userInput);
-/*! @class Alerts
+/*! @category UIViewController(Alerts)
@brief Wrapper for @c UIAlertController and @c UIAlertView for backwards compatability with
iOS 6+.
*/
diff --git a/AuthSamples/Samples.xcodeproj/project.pbxproj b/AuthSamples/Samples.xcodeproj/project.pbxproj
index dfe1e17..89d78c3 100644
--- a/AuthSamples/Samples.xcodeproj/project.pbxproj
+++ b/AuthSamples/Samples.xcodeproj/project.pbxproj
@@ -1399,7 +1399,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 10.3;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
@@ -1442,7 +1442,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 10.3;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
diff --git a/Firebase/Auth/Source/FIRAuth.m b/Firebase/Auth/Source/FIRAuth.m
index 9363069..7a25919 100644
--- a/Firebase/Auth/Source/FIRAuth.m
+++ b/Firebase/Auth/Source/FIRAuth.m
@@ -199,6 +199,11 @@ static NSMutableDictionary *gKeychainServiceNameForAppName;
@end
@implementation FIRAuth {
+ /** @var _currentUser
+ @brief The current user.
+ */
+ FIRUser *_currentUser;
+
/** @var _firebaseAppName
@brief The Firebase app name.
*/
@@ -315,6 +320,7 @@ static NSMutableDictionary *gKeychainServiceNameForAppName;
app.getTokenImplementation = ^(BOOL forceRefresh, FIRTokenCallback callback) {
dispatch_async(FIRAuthGlobalWorkQueue(), ^{
FIRAuth *strongSelf = weakSelf;
+ // Enable token auto-refresh if not aleady enabled.
if (strongSelf && !strongSelf->_autoRefreshTokens) {
FIRLogInfo(kFIRLoggerAuth, @"I-AUT000002", @"Token auto-refresh enabled.");
strongSelf->_autoRefreshTokens = YES;
@@ -346,15 +352,17 @@ static NSMutableDictionary *gKeychainServiceNameForAppName;
}];
#endif
}
- if (!strongSelf.currentUser) {
+ // Call back with 'nil' if there is no current user.
+ if (!strongSelf || !strongSelf->_currentUser) {
dispatch_async(dispatch_get_main_queue(), ^{
callback(nil, nil);
});
return;
}
- [strongSelf.currentUser internalGetTokenForcingRefresh:forceRefresh
- callback:^(NSString *_Nullable token,
- NSError *_Nullable error) {
+ // Call back with current user token.
+ [strongSelf->_currentUser internalGetTokenForcingRefresh:forceRefresh
+ callback:^(NSString *_Nullable token,
+ NSError *_Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
callback(token, error);
});
@@ -378,33 +386,47 @@ static NSMutableDictionary *gKeychainServiceNameForAppName;
_listenerHandles = [NSMutableArray array];
_APIKey = [APIKey copy];
_firebaseAppName = [appName copy];
- NSString *keychainServiceName = [FIRAuth keychainServiceNameForAppName:appName];
- if (keychainServiceName) {
- _keychain = [[FIRAuthKeychain alloc] initWithService:keychainServiceName];
- }
- // Load current user from keychain.
- FIRUser *user;
- NSError *error;
- if ([self getUser:&user error:&error]) {
- [self updateCurrentUser:user byForce:NO savingToDisk:NO error:&error];
- } else {
- FIRLogError(kFIRLoggerAuth, @"I-AUT000001",
- @"Error loading saved user when starting up: %@", error);
- }
-
#if TARGET_OS_IOS
- // Initialize for phone number auth.
- _tokenManager =
- [[FIRAuthAPNSTokenManager alloc] initWithApplication:[UIApplication sharedApplication]];
+ UIApplication *application = [UIApplication sharedApplication];
+ #endif
+
+ // Continue with the rest of initialization in the work thread.
+ __weak FIRAuth *weakSelf = self;
+ dispatch_async(FIRAuthGlobalWorkQueue(), ^{
+ // Load current user from Keychain.
+ FIRAuth *strongSelf = weakSelf;
+ if (!strongSelf) {
+ return;
+ }
+ NSString *keychainServiceName =
+ [FIRAuth keychainServiceNameForAppName:strongSelf->_firebaseAppName];
+ if (keychainServiceName) {
+ strongSelf->_keychain = [[FIRAuthKeychain alloc] initWithService:keychainServiceName];
+ }
+ FIRUser *user;
+ NSError *error;
+ if ([strongSelf getUser:&user error:&error]) {
+ [strongSelf updateCurrentUser:user byForce:NO savingToDisk:NO error:&error];
+ } else {
+ FIRLogError(kFIRLoggerAuth, @"I-AUT000001",
+ @"Error loading saved user when starting up: %@", error);
+ }
- _appCredentialManager = [[FIRAuthAppCredentialManager alloc] initWithKeychain:_keychain];
+ #if TARGET_OS_IOS
+ // Initialize for phone number auth.
+ strongSelf->_tokenManager =
+ [[FIRAuthAPNSTokenManager alloc] initWithApplication:application];
- _notificationManager =
- [[FIRAuthNotificationManager alloc] initWithApplication:[UIApplication sharedApplication]
- appCredentialManager:_appCredentialManager];
+ strongSelf->_appCredentialManager =
+ [[FIRAuthAppCredentialManager alloc] initWithKeychain:strongSelf->_keychain];
- [[FIRAuthAppDelegateProxy sharedInstance] addHandler:self];
- #endif
+ strongSelf->_notificationManager = [[FIRAuthNotificationManager alloc]
+ initWithApplication:application
+ appCredentialManager:strongSelf->_appCredentialManager];
+
+ [[FIRAuthAppDelegateProxy sharedInstance] addHandler:strongSelf];
+ #endif
+ });
}
return self;
}
@@ -431,6 +453,14 @@ static NSMutableDictionary *gKeychainServiceNameForAppName;
#pragma mark - Public API
+- (FIRUser *)currentUser {
+ __block FIRUser *result;
+ dispatch_sync(FIRAuthGlobalWorkQueue(), ^{
+ result = _currentUser;
+ });
+ return result;
+}
+
- (void)fetchProvidersForEmail:(NSString *)email
completion:(FIRProviderQueryCallback)completion {
dispatch_async(FIRAuthGlobalWorkQueue(), ^{
@@ -1275,10 +1305,6 @@ static NSMutableDictionary *gKeychainServiceNameForAppName;
return YES;
}
-/** @fn getUID
- @brief Gets the identifier of the current user, if any.
- @return The identifier of the current user, or nil if there is no current user.
- */
- (nullable NSString *)getUID {
return _currentUser.uid;
}
diff --git a/Firebase/Auth/Source/FIRAuth_Internal.h b/Firebase/Auth/Source/FIRAuth_Internal.h
index 94363a1..5d1d13f 100644
--- a/Firebase/Auth/Source/FIRAuth_Internal.h
+++ b/Firebase/Auth/Source/FIRAuth_Internal.h
@@ -75,6 +75,12 @@ extern NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey;
- (nullable instancetype)initWithAPIKey:(NSString *)APIKey
appName:(NSString *)appName NS_DESIGNATED_INITIALIZER;
+/** @fn getUID
+ @brief Gets the identifier of the current user, if any.
+ @return The identifier of the current user, or nil if there is no current user.
+ */
+- (nullable NSString *)getUID;
+
/** @fn notifyListenersOfAuthStateChange
@brief Posts the @c FIRAuthStateDidChangeNotification notification.
@remarks Called by @c FIRUser when token changes occur.
diff --git a/Firebase/Auth/Source/FIRUser.m b/Firebase/Auth/Source/FIRUser.m
index 112b870..cd168cf 100644
--- a/Firebase/Auth/Source/FIRUser.m
+++ b/Firebase/Auth/Source/FIRUser.m
@@ -734,7 +734,7 @@ static void callInMainThreadWithAuthDataResultAndError(
callInMainThreadWithAuthDataResultAndError(completion, authResult, error);
return;
}
- if (![authResult.user.uid isEqual:_auth.currentUser.uid]) {
+ if (![authResult.user.uid isEqual:[_auth getUID]]) {
callInMainThreadWithAuthDataResultAndError(completion, authResult,
[FIRAuthErrorUtils userMismatchError]);
return;