diff --git a/FirebaseAuthUI/FUIAuth.m b/FirebaseAuthUI/FUIAuth.m index 63245d1e77a..448299fb7b4 100644 --- a/FirebaseAuthUI/FUIAuth.m +++ b/FirebaseAuthUI/FUIAuth.m @@ -191,8 +191,9 @@ - (void)signInWithProviderUI:(id)providerUI }; // Check for the presence of an anonymous user and whether automatic upgrade is enabled. - if (_auth.currentUser.isAnonymous && [FUIAuth defaultAuthUI].shouldAutoUpgradeAnonymousUsers) { - [_auth.currentUser + if (self.auth.currentUser.isAnonymous && + [FUIAuth defaultAuthUI].shouldAutoUpgradeAnonymousUsers) { + [self.auth.currentUser linkAndRetrieveDataWithCredential:credential completion:^(FIRAuthDataResult *_Nullable authResult, NSError * _Nullable error) { @@ -203,7 +204,7 @@ - (void)signInWithProviderUI:(id)providerUI FIRAuthCredential *newCredential = credential; // Check for and handle special case for Phone Auth Provider. if (providerUI.providerID == FIRPhoneAuthProviderID) { - // Obtain temporary Phone Auth provider. + // Obtain temporary Phone Auth credential. newCredential = error.userInfo[FIRAuthUpdatedCredentialKey]; } NSDictionary *userInfo = @{ diff --git a/FirebaseAuthUI/FUIAuthErrorUtils.h b/FirebaseAuthUI/FUIAuthErrorUtils.h index 43395d810bd..58a85d7ad6c 100644 --- a/FirebaseAuthUI/FUIAuthErrorUtils.h +++ b/FirebaseAuthUI/FUIAuthErrorUtils.h @@ -36,6 +36,13 @@ NS_ASSUME_NONNULL_BEGIN */ + (NSError *)userCancelledSignInError; +/** @fn userCancelledSignIn + @brief Constructs an @c NSError with the @c FUIAuthErrorCodeMergeConflict code. + @param userInfo The userInfo dictionary to add to the NSError object. + @return The merge conflict error. + */ ++ (NSError *)mergeConflictErrorWithUserInfo:(NSDictionary *)userInfo; + /** @fn providerErrorWithUnderlyingError:providerID: @brief Constructs an @c NSError with the @c FUIAuthErrorCodeProviderError code and a populated @c NSUnderlyingErrorKey and @c FUIAuthErrorUserInfoProviderIDKey in the diff --git a/FirebaseAuthUI/FUIAuthErrorUtils.m b/FirebaseAuthUI/FUIAuthErrorUtils.m index 180ff2ca9b8..80b17b2f5bf 100644 --- a/FirebaseAuthUI/FUIAuthErrorUtils.m +++ b/FirebaseAuthUI/FUIAuthErrorUtils.m @@ -26,6 +26,10 @@ + (NSError *)userCancelledSignInError { return [self errorWithCode:FUIAuthErrorCodeUserCancelledSignIn userInfo:nil]; } ++ (NSError *)mergeConflictErrorWithUserInfo:(NSDictionary *)userInfo { + return [self errorWithCode:FUIAuthErrorCodeMergeConflict userInfo:userInfo]; +} + + (NSError *)providerErrorWithUnderlyingError:(NSError *)underlyingError providerID:(NSString *)providerID { return [self errorWithCode:FUIAuthErrorCodeProviderError diff --git a/FirebaseAuthUI/FUIPasswordSignInViewController.m b/FirebaseAuthUI/FUIPasswordSignInViewController.m index 162254b7156..12426ad6157 100644 --- a/FirebaseAuthUI/FUIPasswordSignInViewController.m +++ b/FirebaseAuthUI/FUIPasswordSignInViewController.m @@ -18,10 +18,12 @@ #import #import "FUIAuthBaseViewController_Internal.h" +#import "FUIAuthErrorUtils.h" #import "FUIAuthStrings.h" #import "FUIAuthTableViewCell.h" #import "FUIAuthUtils.h" #import "FUIAuth_Internal.h" +#import "FUIAuthErrors.h" #import "FUIPasswordRecoveryViewController.h" /** @var kCellReuseIdentifier @@ -108,35 +110,59 @@ - (void)signInWithDefaultValue:(NSString *)email andPassword:(NSString *)passwor } [self incrementActivity]; - FIRAuthCredential *credential = [FIREmailAuthProvider credentialWithEmail:email password:password]; - [self.auth signInAndRetrieveDataWithCredential:credential - completion:^(FIRAuthDataResult *_Nullable authResult, - NSError *_Nullable error) { - [self decrementActivity]; - - if (error) { - switch (error.code) { - case FIRAuthErrorCodeWrongPassword: - [self showAlertWithMessage:FUILocalizedString(kStr_WrongPasswordError)]; - return; - case FIRAuthErrorCodeUserNotFound: - [self showAlertWithMessage:FUILocalizedString(kStr_UserNotFoundError)]; - return; - case FIRAuthErrorCodeUserDisabled: - [self showAlertWithMessage:FUILocalizedString(kStr_AccountDisabledError)]; - return; - case FIRAuthErrorCodeTooManyRequests: - [self showAlertWithMessage:FUILocalizedString(kStr_SignInTooManyTimesError)]; + + void (^completeSignInBlock)(FIRAuthDataResult *, NSError *) = ^(FIRAuthDataResult *authResult, + NSError *error) { + [self decrementActivity]; + + if (error) { + switch (error.code) { + case FIRAuthErrorCodeWrongPassword: + [self showAlertWithMessage:FUILocalizedString(kStr_WrongPasswordError)]; + return; + case FIRAuthErrorCodeUserNotFound: + [self showAlertWithMessage:FUILocalizedString(kStr_UserNotFoundError)]; + return; + case FIRAuthErrorCodeUserDisabled: + [self showAlertWithMessage:FUILocalizedString(kStr_AccountDisabledError)]; + return; + case FIRAuthErrorCodeTooManyRequests: + [self showAlertWithMessage:FUILocalizedString(kStr_SignInTooManyTimesError)]; + return; + } + } + [self.navigationController dismissViewControllerAnimated:YES completion:^{ + [self.authUI invokeResultCallbackWithAuthDataResult:authResult error:error]; + }]; + }; + + // Check for the presence of an anonymous user and whether automatic upgrade is enabled. + if (self.auth.currentUser.isAnonymous && + [FUIAuth defaultAuthUI].shouldAutoUpgradeAnonymousUsers) { + + [self.auth.currentUser + linkAndRetrieveDataWithCredential:credential + completion:^(FIRAuthDataResult *_Nullable authResult, + NSError *_Nullable error) { + if (error) { + if (error.code == FIRAuthErrorCodeEmailAlreadyInUse) { + NSDictionary *userInfo = @{ FUIAuthCredentialKey : credential }; + NSError *mergeError = [FUIAuthErrorUtils mergeConflictErrorWithUserInfo:userInfo]; + [self.navigationController dismissViewControllerAnimated:YES completion:^{ + [self.authUI invokeResultCallbackWithAuthDataResult:authResult error:mergeError]; + }]; return; + } + completeSignInBlock(nil, error); + return; } - } - - [self.navigationController dismissViewControllerAnimated:YES completion:^{ - [self.authUI invokeResultCallbackWithAuthDataResult:authResult error:error]; + completeSignInBlock(authResult, nil); }]; - }]; + } else { + [self.auth signInAndRetrieveDataWithCredential:credential completion:completeSignInBlock]; + } } - (void)signIn { diff --git a/FirebaseAuthUI/FUIPasswordSignUpViewController.m b/FirebaseAuthUI/FUIPasswordSignUpViewController.m index f2858dd0809..94074a96b33 100644 --- a/FirebaseAuthUI/FUIPasswordSignUpViewController.m +++ b/FirebaseAuthUI/FUIPasswordSignUpViewController.m @@ -180,29 +180,57 @@ - (void)signUpWithEmail:(NSString *)email [self incrementActivity]; - [self.auth createUserAndRetrieveDataWithEmail:email + // Check for the presence of an anonymous user and whether automatic upgrade is enabled. + if (self.auth.currentUser.isAnonymous && + [FUIAuth defaultAuthUI].shouldAutoUpgradeAnonymousUsers) { + FIRAuthCredential *credential = + [FIREmailAuthProvider credentialWithEmail:email password:password]; + [self.auth.currentUser + linkAndRetrieveDataWithCredential:credential + completion:^(FIRAuthDataResult *_Nullable authResult, + NSError * _Nullable error) { + if (error) { + [self decrementActivity]; + [self finishSignUpWithAuthDataResult:nil error:error]; + return; + } + FIRUserProfileChangeRequest *request = [authResult.user profileChangeRequest]; + request.displayName = username; + [request commitChangesWithCompletion:^(NSError *_Nullable error) { + [self decrementActivity]; + + if (error) { + [self finishSignUpWithAuthDataResult:nil error:error]; + return; + } + [self finishSignUpWithAuthDataResult:authResult error:nil]; + }]; + }]; + } else { + [self.auth createUserAndRetrieveDataWithEmail:email password:password completion:^(FIRAuthDataResult *_Nullable authDataResult, NSError *_Nullable error) { - if (error) { - [self decrementActivity]; - - [self finishSignUpWithAuthDataResult:nil error:error]; - return; - } - - FIRUserProfileChangeRequest *request = [authDataResult.user profileChangeRequest]; - request.displayName = username; - [request commitChangesWithCompletion:^(NSError *_Nullable error) { - [self decrementActivity]; - if (error) { + [self decrementActivity]; + [self finishSignUpWithAuthDataResult:nil error:error]; return; } - [self finishSignUpWithAuthDataResult:authDataResult error:nil]; + + FIRUserProfileChangeRequest *request = [authDataResult.user profileChangeRequest]; + request.displayName = username; + [request commitChangesWithCompletion:^(NSError *_Nullable error) { + [self decrementActivity]; + + if (error) { + [self finishSignUpWithAuthDataResult:nil error:error]; + return; + } + [self finishSignUpWithAuthDataResult:authDataResult error:nil]; + }]; }]; - }]; + } } - (void)finishSignUpWithAuthDataResult:(nullable FIRAuthDataResult *)authDataResult diff --git a/samples/objc/FirebaseUI-demo-objc/Samples/Auth/FUIAuthViewController.m b/samples/objc/FirebaseUI-demo-objc/Samples/Auth/FUIAuthViewController.m index 13a05264ee6..c146b84217c 100644 --- a/samples/objc/FirebaseUI-demo-objc/Samples/Auth/FUIAuthViewController.m +++ b/samples/objc/FirebaseUI-demo-objc/Samples/Auth/FUIAuthViewController.m @@ -264,19 +264,21 @@ - (void)authUI:(FUIAuth *)authUI } if (error.code == FUIAuthErrorCodeMergeConflict) { FIRAuthCredential *credential = error.userInfo[FUIAuthCredentialKey]; - NSString *anonymousUserID = authUI.auth.currentUser.uid; - NSString *messsage = [NSString stringWithFormat:@"A merge conflict occurred. The old user ID " - "was: %@. You are now signed in with the following credential type: %@", anonymousUserID, - [credential.provider uppercaseString]]; - [self showAlertWithTitlte:@"Merge Conflict" message:messsage]; - NSLog(@"%@", messsage); [[FUIAuth defaultAuthUI].auth signInAndRetrieveDataWithCredential:credential completion:^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) { if (error) { + [self showAlertWithTitlte:@"Sign-In error" message:error.description]; NSLog(@"%@",error.description); + return; } + NSString *anonymousUserID = authUI.auth.currentUser.uid; + NSString *messsage = [NSString stringWithFormat:@"A merge conflict occurred. The old user" + " ID was: %@. You are now signed in with the following credential type: %@", + anonymousUserID, [credential.provider uppercaseString]]; + [self showAlertWithTitlte:@"Merge Conflict" message:messsage]; + NSLog(@"%@", messsage); }]; return; }