diff --git a/FirebaseAuthUI/FUIAuth.m b/FirebaseAuthUI/FUIAuth.m index 2d9a37e6c67..08970c626c4 100644 --- a/FirebaseAuthUI/FUIAuth.m +++ b/FirebaseAuthUI/FUIAuth.m @@ -28,6 +28,7 @@ #import "FUIAuthStrings.h" #import "FUIGoogleAuth.h" #import "FUIEmailEntryViewController.h" +#import "FUIPasswordSignInViewController_Internal.h" #import "FUIPasswordVerificationViewController.h" /** @var kAppNameCodingKey @@ -154,7 +155,7 @@ - (BOOL)signOutWithError:(NSError *_Nullable *_Nullable)error { } - (void)signInWithProviderUI:(id)providerUI - presentingViewController:(UIViewController *)presentingViewController + presentingViewController:(FUIAuthBaseViewController *)presentingViewController defaultValue:(nullable NSString *)defaultValue { // Sign out first to make sure sign in starts with a clean state. @@ -280,7 +281,7 @@ - (void)signInWithProviderUI:(id)providerUI } - (void)signInWithEmailHint:(NSString *)emailHint - presentingViewController:(UIViewController *)presentingViewController + presentingViewController:(FUIAuthBaseViewController *)presentingViewController completion:(FIRAuthDataResultCallback)completion { NSString *kTempApp = @"tempApp"; FIROptions *options = [FIROptions defaultOptions]; @@ -291,7 +292,7 @@ - (void)signInWithEmailHint:(NSString *)emailHint FIRApp *tempApp = [FIRApp appNamed:kTempApp]; // Create a new auth instance in order to perform a successful sign-in without losing the // currently signed in user on the default auth instance. - FIRAuth *auth = [FIRAuth authWithApp:tempApp]; + FIRAuth *tempAuth = [FIRAuth authWithApp:tempApp]; [self.auth fetchProvidersForEmail:emailHint completion:^(NSArray *_Nullable providers, NSError *_Nullable error) { @@ -299,39 +300,54 @@ - (void)signInWithEmailHint:(NSString *)emailHint completion(nil, error); return; } - NSString *existingFederatedProviderID = [self federatedAuthProviderFromProviders:providers]; - // Set of providers which can be auto-linked + NSString *existingFederatedProviderID = [self authProviderFromProviders:providers]; + // Set of providers which can be auto-linked. NSSet *supportedProviders = - [NSSet setWithObjects:FIRGoogleAuthProviderID, FIRFacebookAuthProviderID, nil]; + [NSSet setWithObjects:FIRGoogleAuthProviderID, + FIRFacebookAuthProviderID, + FIREmailAuthProviderID, + nil]; if ([supportedProviders containsObject:existingFederatedProviderID]) { - id authProviderUI; - // Retrieve the FUIAuthProvider instance from FUIAuth for the existing provider ID. - for (id provider in self.providers) { - if ([provider.providerID isEqualToString:existingFederatedProviderID]) { - authProviderUI = provider; - break; + if ([existingFederatedProviderID isEqualToString:FIREmailAuthProviderID]) { + FUIAuth *authUI = [[FUIAuth alloc]initWithAuth:tempAuth]; + // Email password sign-in + FUIPasswordSignInViewController *controller = + [[FUIPasswordSignInViewController alloc] initWithAuthUI:authUI email:emailHint]; + controller.onDismissCallback = completion; + [presentingViewController pushViewController:controller]; + } else { + id authProviderUI; + // Retrieve the FUIAuthProvider instance from FUIAuth for the existing provider ID. + for (id provider in self.providers) { + if ([provider.providerID isEqualToString:existingFederatedProviderID]) { + authProviderUI = provider; + break; + } } + [authProviderUI signOut]; + [authProviderUI signInWithDefaultValue:emailHint + presentingViewController:presentingViewController + completion:^(FIRAuthCredential *_Nullable credential, + NSError *_Nullable error, + FIRAuthResultCallback _Nullable result) { + if (error) { + if (completion) { + completion(nil, error); + } + return; + } + [tempAuth signInAndRetrieveDataWithCredential:credential completion:completion]; + }]; } - [authProviderUI signOut]; - [authProviderUI signInWithDefaultValue:emailHint - presentingViewController:presentingViewController - completion:^(FIRAuthCredential *_Nullable credential, - NSError *_Nullable error, - FIRAuthResultCallback _Nullable result) { - if (error) { - completion(nil, error); - return; - } - - [auth signInAndRetrieveDataWithCredential:credential completion:completion]; - }]; } }]; } -- (nullable NSString *)federatedAuthProviderFromProviders:(NSArray *) providers { +- (nullable NSString *)authProviderFromProviders:(NSArray *) providers { NSSet *providerSet = - [NSSet setWithArray:@[ FIRFacebookAuthProviderID, FIRGoogleAuthProviderID ]]; + [NSSet setWithArray:@[ FIRFacebookAuthProviderID, + FIRGoogleAuthProviderID, + FIREmailAuthProviderID ]]; for (NSString *provider in providers) { if ( [providerSet containsObject:provider]) { return provider; diff --git a/FirebaseAuthUI/FUIPasswordSignInViewController.m b/FirebaseAuthUI/FUIPasswordSignInViewController.m index 12426ad6157..d90a6398c67 100644 --- a/FirebaseAuthUI/FUIPasswordSignInViewController.m +++ b/FirebaseAuthUI/FUIPasswordSignInViewController.m @@ -14,7 +14,7 @@ // limitations under the License. // -#import "FUIPasswordSignInViewController.h" +#import "FUIPasswordSignInViewController_Internal.h" #import #import "FUIAuthBaseViewController_Internal.h" @@ -80,6 +80,10 @@ - (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil _email = [email copy]; self.title = FUILocalizedString(kStr_SignInTitle); + __weak FUIPasswordSignInViewController *weakself = self; + _onDismissCallback = ^(FIRAuthDataResult *authResult, NSError *error){ + [weakself.authUI invokeResultCallbackWithAuthDataResult:authResult error:error]; + }; } return self; } @@ -134,7 +138,9 @@ - (void)signInWithDefaultValue:(NSString *)email andPassword:(NSString *)passwor } } [self.navigationController dismissViewControllerAnimated:YES completion:^{ - [self.authUI invokeResultCallbackWithAuthDataResult:authResult error:error]; + if (self->_onDismissCallback) { + self->_onDismissCallback(authResult, error); + } }]; }; diff --git a/FirebaseAuthUI/FUIPasswordSignInViewController_Internal.h b/FirebaseAuthUI/FUIPasswordSignInViewController_Internal.h new file mode 100644 index 00000000000..3958533cf87 --- /dev/null +++ b/FirebaseAuthUI/FUIPasswordSignInViewController_Internal.h @@ -0,0 +1,35 @@ +// +// Copyright (c) 2018 Google Inc. +// +// 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 "FUIPasswordSignInViewController.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface FUIPasswordSignInViewController () + +/** @property onDismissCallback: + @brief Sets an optional custom callback for FUIPasswordSigInViewController during dismissal. If + this property is set the default dismissal routine is not triggered and should be included + in this block if necessary. This block is NOT set to nil after use, set to nil after using + if you wish to avoid circular references. + */ +@property(nonatomic, strong, nullable) FIRAuthDataResultCallback onDismissCallback; + +NS_ASSUME_NONNULL_END + + +@end