Skip to content

Commit 81573c7

Browse files
authored
anonymous upgrade for email password accounts (firebase#405)
* anonymous upgrade for email password accounts * addresses comments
1 parent 3fa49f5 commit 81573c7

File tree

6 files changed

+116
-48
lines changed

6 files changed

+116
-48
lines changed

FirebaseAuthUI/FUIAuth.m

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,9 @@ - (void)signInWithProviderUI:(id<FUIAuthProvider>)providerUI
191191
};
192192

193193
// Check for the presence of an anonymous user and whether automatic upgrade is enabled.
194-
if (_auth.currentUser.isAnonymous && [FUIAuth defaultAuthUI].shouldAutoUpgradeAnonymousUsers) {
195-
[_auth.currentUser
194+
if (self.auth.currentUser.isAnonymous &&
195+
[FUIAuth defaultAuthUI].shouldAutoUpgradeAnonymousUsers) {
196+
[self.auth.currentUser
196197
linkAndRetrieveDataWithCredential:credential
197198
completion:^(FIRAuthDataResult *_Nullable authResult,
198199
NSError * _Nullable error) {
@@ -203,7 +204,7 @@ - (void)signInWithProviderUI:(id<FUIAuthProvider>)providerUI
203204
FIRAuthCredential *newCredential = credential;
204205
// Check for and handle special case for Phone Auth Provider.
205206
if (providerUI.providerID == FIRPhoneAuthProviderID) {
206-
// Obtain temporary Phone Auth provider.
207+
// Obtain temporary Phone Auth credential.
207208
newCredential = error.userInfo[FIRAuthUpdatedCredentialKey];
208209
}
209210
NSDictionary *userInfo = @{

FirebaseAuthUI/FUIAuthErrorUtils.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ NS_ASSUME_NONNULL_BEGIN
3636
*/
3737
+ (NSError *)userCancelledSignInError;
3838

39+
/** @fn userCancelledSignIn
40+
@brief Constructs an @c NSError with the @c FUIAuthErrorCodeMergeConflict code.
41+
@param userInfo The userInfo dictionary to add to the NSError object.
42+
@return The merge conflict error.
43+
*/
44+
+ (NSError *)mergeConflictErrorWithUserInfo:(NSDictionary *)userInfo;
45+
3946
/** @fn providerErrorWithUnderlyingError:providerID:
4047
@brief Constructs an @c NSError with the @c FUIAuthErrorCodeProviderError code and a populated
4148
@c NSUnderlyingErrorKey and @c FUIAuthErrorUserInfoProviderIDKey in the

FirebaseAuthUI/FUIAuthErrorUtils.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ + (NSError *)userCancelledSignInError {
2626
return [self errorWithCode:FUIAuthErrorCodeUserCancelledSignIn userInfo:nil];
2727
}
2828

29+
+ (NSError *)mergeConflictErrorWithUserInfo:(NSDictionary *)userInfo {
30+
return [self errorWithCode:FUIAuthErrorCodeMergeConflict userInfo:userInfo];
31+
}
32+
2933
+ (NSError *)providerErrorWithUnderlyingError:(NSError *)underlyingError
3034
providerID:(NSString *)providerID {
3135
return [self errorWithCode:FUIAuthErrorCodeProviderError

FirebaseAuthUI/FUIPasswordSignInViewController.m

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818

1919
#import <FirebaseAuth/FirebaseAuth.h>
2020
#import "FUIAuthBaseViewController_Internal.h"
21+
#import "FUIAuthErrorUtils.h"
2122
#import "FUIAuthStrings.h"
2223
#import "FUIAuthTableViewCell.h"
2324
#import "FUIAuthUtils.h"
2425
#import "FUIAuth_Internal.h"
26+
#import "FUIAuthErrors.h"
2527
#import "FUIPasswordRecoveryViewController.h"
2628

2729
/** @var kCellReuseIdentifier
@@ -108,35 +110,59 @@ - (void)signInWithDefaultValue:(NSString *)email andPassword:(NSString *)passwor
108110
}
109111

110112
[self incrementActivity];
111-
112113
FIRAuthCredential *credential =
113114
[FIREmailAuthProvider credentialWithEmail:email password:password];
114-
[self.auth signInAndRetrieveDataWithCredential:credential
115-
completion:^(FIRAuthDataResult *_Nullable authResult,
116-
NSError *_Nullable error) {
117-
[self decrementActivity];
118-
119-
if (error) {
120-
switch (error.code) {
121-
case FIRAuthErrorCodeWrongPassword:
122-
[self showAlertWithMessage:FUILocalizedString(kStr_WrongPasswordError)];
123-
return;
124-
case FIRAuthErrorCodeUserNotFound:
125-
[self showAlertWithMessage:FUILocalizedString(kStr_UserNotFoundError)];
126-
return;
127-
case FIRAuthErrorCodeUserDisabled:
128-
[self showAlertWithMessage:FUILocalizedString(kStr_AccountDisabledError)];
129-
return;
130-
case FIRAuthErrorCodeTooManyRequests:
131-
[self showAlertWithMessage:FUILocalizedString(kStr_SignInTooManyTimesError)];
115+
116+
void (^completeSignInBlock)(FIRAuthDataResult *, NSError *) = ^(FIRAuthDataResult *authResult,
117+
NSError *error) {
118+
[self decrementActivity];
119+
120+
if (error) {
121+
switch (error.code) {
122+
case FIRAuthErrorCodeWrongPassword:
123+
[self showAlertWithMessage:FUILocalizedString(kStr_WrongPasswordError)];
124+
return;
125+
case FIRAuthErrorCodeUserNotFound:
126+
[self showAlertWithMessage:FUILocalizedString(kStr_UserNotFoundError)];
127+
return;
128+
case FIRAuthErrorCodeUserDisabled:
129+
[self showAlertWithMessage:FUILocalizedString(kStr_AccountDisabledError)];
130+
return;
131+
case FIRAuthErrorCodeTooManyRequests:
132+
[self showAlertWithMessage:FUILocalizedString(kStr_SignInTooManyTimesError)];
133+
return;
134+
}
135+
}
136+
[self.navigationController dismissViewControllerAnimated:YES completion:^{
137+
[self.authUI invokeResultCallbackWithAuthDataResult:authResult error:error];
138+
}];
139+
};
140+
141+
// Check for the presence of an anonymous user and whether automatic upgrade is enabled.
142+
if (self.auth.currentUser.isAnonymous &&
143+
[FUIAuth defaultAuthUI].shouldAutoUpgradeAnonymousUsers) {
144+
145+
[self.auth.currentUser
146+
linkAndRetrieveDataWithCredential:credential
147+
completion:^(FIRAuthDataResult *_Nullable authResult,
148+
NSError *_Nullable error) {
149+
if (error) {
150+
if (error.code == FIRAuthErrorCodeEmailAlreadyInUse) {
151+
NSDictionary *userInfo = @{ FUIAuthCredentialKey : credential };
152+
NSError *mergeError = [FUIAuthErrorUtils mergeConflictErrorWithUserInfo:userInfo];
153+
[self.navigationController dismissViewControllerAnimated:YES completion:^{
154+
[self.authUI invokeResultCallbackWithAuthDataResult:authResult error:mergeError];
155+
}];
132156
return;
157+
}
158+
completeSignInBlock(nil, error);
159+
return;
133160
}
134-
}
135-
136-
[self.navigationController dismissViewControllerAnimated:YES completion:^{
137-
[self.authUI invokeResultCallbackWithAuthDataResult:authResult error:error];
161+
completeSignInBlock(authResult, nil);
138162
}];
139-
}];
163+
} else {
164+
[self.auth signInAndRetrieveDataWithCredential:credential completion:completeSignInBlock];
165+
}
140166
}
141167

142168
- (void)signIn {

FirebaseAuthUI/FUIPasswordSignUpViewController.m

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -180,29 +180,57 @@ - (void)signUpWithEmail:(NSString *)email
180180

181181
[self incrementActivity];
182182

183-
[self.auth createUserAndRetrieveDataWithEmail:email
183+
// Check for the presence of an anonymous user and whether automatic upgrade is enabled.
184+
if (self.auth.currentUser.isAnonymous &&
185+
[FUIAuth defaultAuthUI].shouldAutoUpgradeAnonymousUsers) {
186+
FIRAuthCredential *credential =
187+
[FIREmailAuthProvider credentialWithEmail:email password:password];
188+
[self.auth.currentUser
189+
linkAndRetrieveDataWithCredential:credential
190+
completion:^(FIRAuthDataResult *_Nullable authResult,
191+
NSError * _Nullable error) {
192+
if (error) {
193+
[self decrementActivity];
194+
[self finishSignUpWithAuthDataResult:nil error:error];
195+
return;
196+
}
197+
FIRUserProfileChangeRequest *request = [authResult.user profileChangeRequest];
198+
request.displayName = username;
199+
[request commitChangesWithCompletion:^(NSError *_Nullable error) {
200+
[self decrementActivity];
201+
202+
if (error) {
203+
[self finishSignUpWithAuthDataResult:nil error:error];
204+
return;
205+
}
206+
[self finishSignUpWithAuthDataResult:authResult error:nil];
207+
}];
208+
}];
209+
} else {
210+
[self.auth createUserAndRetrieveDataWithEmail:email
184211
password:password
185212
completion:^(FIRAuthDataResult *_Nullable authDataResult,
186213
NSError *_Nullable error) {
187-
if (error) {
188-
[self decrementActivity];
189-
190-
[self finishSignUpWithAuthDataResult:nil error:error];
191-
return;
192-
}
193-
194-
FIRUserProfileChangeRequest *request = [authDataResult.user profileChangeRequest];
195-
request.displayName = username;
196-
[request commitChangesWithCompletion:^(NSError *_Nullable error) {
197-
[self decrementActivity];
198-
199214
if (error) {
215+
[self decrementActivity];
216+
200217
[self finishSignUpWithAuthDataResult:nil error:error];
201218
return;
202219
}
203-
[self finishSignUpWithAuthDataResult:authDataResult error:nil];
220+
221+
FIRUserProfileChangeRequest *request = [authDataResult.user profileChangeRequest];
222+
request.displayName = username;
223+
[request commitChangesWithCompletion:^(NSError *_Nullable error) {
224+
[self decrementActivity];
225+
226+
if (error) {
227+
[self finishSignUpWithAuthDataResult:nil error:error];
228+
return;
229+
}
230+
[self finishSignUpWithAuthDataResult:authDataResult error:nil];
231+
}];
204232
}];
205-
}];
233+
}
206234
}
207235

208236
- (void)finishSignUpWithAuthDataResult:(nullable FIRAuthDataResult *)authDataResult

samples/objc/FirebaseUI-demo-objc/Samples/Auth/FUIAuthViewController.m

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,19 +264,21 @@ - (void)authUI:(FUIAuth *)authUI
264264
}
265265
if (error.code == FUIAuthErrorCodeMergeConflict) {
266266
FIRAuthCredential *credential = error.userInfo[FUIAuthCredentialKey];
267-
NSString *anonymousUserID = authUI.auth.currentUser.uid;
268-
NSString *messsage = [NSString stringWithFormat:@"A merge conflict occurred. The old user ID "
269-
"was: %@. You are now signed in with the following credential type: %@", anonymousUserID,
270-
[credential.provider uppercaseString]];
271-
[self showAlertWithTitlte:@"Merge Conflict" message:messsage];
272-
NSLog(@"%@", messsage);
273267
[[FUIAuth defaultAuthUI].auth
274268
signInAndRetrieveDataWithCredential:credential
275269
completion:^(FIRAuthDataResult *_Nullable authResult,
276270
NSError *_Nullable error) {
277271
if (error) {
272+
[self showAlertWithTitlte:@"Sign-In error" message:error.description];
278273
NSLog(@"%@",error.description);
274+
return;
279275
}
276+
NSString *anonymousUserID = authUI.auth.currentUser.uid;
277+
NSString *messsage = [NSString stringWithFormat:@"A merge conflict occurred. The old user"
278+
" ID was: %@. You are now signed in with the following credential type: %@",
279+
anonymousUserID, [credential.provider uppercaseString]];
280+
[self showAlertWithTitlte:@"Merge Conflict" message:messsage];
281+
NSLog(@"%@", messsage);
280282
}];
281283
return;
282284
}

0 commit comments

Comments
 (0)