Skip to content

Implement additional FUIAuth sign-in call bac #375

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,30 +65,26 @@ - (void)onPasswordRecovery:(NSString *)email {

[self.delegate.auth sendPasswordResetWithEmail:email
completion:^(NSError *_Nullable error) {
// The dispatch is a workaround for a bug in FirebaseAuth 3.0.2, which doesn't call the
// completion block on the main queue.
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate decrementActivity];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're removing this, we should bump the Podfile dependency to 3.1 or higher so this bug doesn't regress for users who haven't updated their pods.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[self.delegate decrementActivity];

if (error) {
[self finishOperationWithError:error];
return;
}
if (error) {
[self finishOperationWithError:error];
return;
}

NSString *message = [NSString stringWithFormat:
FUILocalizedString(kStr_PasswordRecoveryEmailSentMessage), email];
UIAlertController *alertController =
[UIAlertController alertControllerWithTitle:nil
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:FUILocalizedString(kStr_OK)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
[self finishOperationWithError:error];
}];
[alertController addAction:okAction];
[self.delegate presentViewController:alertController];
});
NSString *message = [NSString stringWithFormat:
FUILocalizedString(kStr_PasswordRecoveryEmailSentMessage), email];
UIAlertController *alertController =
[UIAlertController alertControllerWithTitle:nil
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:FUILocalizedString(kStr_OK)
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
[self finishOperationWithError:error];
}];
[alertController addAction:okAction];
[self.delegate presentViewController:alertController];
}];
}

Expand Down
23 changes: 20 additions & 3 deletions FirebaseAuthUI/FUIAuth.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,35 @@ typedef void (^FUIAuthResultCallback)(FIRUser *_Nullable user, NSError *_Nullabl
*/
@protocol FUIAuthDelegate <NSObject>

/** @fn authUI:didSignInWithUser:error:
@optional

/** @fn authUI:didSignInWithAuthDataResult:error:
@brief Message sent after the sign in process has completed to report the signed in user or
error encountered.
@param authUI The @c FUIAuth instance sending the message.
@param authDataResult The data result if the sign in attempt was successful.
@param error The error that occurred during sign in, if any.
*/
- (void)authUI:(FUIAuth *)authUI
didSignInWithAuthDataResult:(nullable FIRAuthDataResult *)authDataResult
error:(nullable NSError *)error;

/** @fn authUI:didSignInWithUser:error:
@brief This is deprecated API and will be removed in a future release.
Use @c authUI:didSignInWithAuthDataResult:error:
Both sign in call backs are called (@c authUI:didSignInWithAuthDataResult:error:
and @c authUI:didSignInWithUser:error:).
This message is sent after the sign in process has completed to report the signed in user or
error encountered.
@param authUI The @c FUIAuth instance sending the message.
@param user The signed in user if the sign in attempt was successful.
@param error The error that occurred during sign in, if any.
*/
- (void)authUI:(FUIAuth *)authUI
didSignInWithUser:(nullable FIRUser *)user
error:(nullable NSError *)error;
error:(nullable NSError *)error
__attribute__((deprecated("Instead use authUI:didSignInWithAuthDataResult:error:")));

@optional

/** @fn authUI:didFinishOperation:error:
@brief Message sent after finishing Account Management operation.
Expand Down
48 changes: 29 additions & 19 deletions FirebaseAuthUI/FUIAuth.m
Original file line number Diff line number Diff line change
Expand Up @@ -166,16 +166,17 @@ - (void)signInWithProviderUI:(id<FUIAuthProvider>)providerUI
[presentingViewController isKindOfClass:[FUIAuthPickerViewController class]];
if (error) {
if (!isAuthPickerShown || error.code != FUIAuthErrorCodeUserCancelledSignIn) {
[self invokeResultCallbackWithUser:nil error:error];
[self invokeResultCallbackWithAuthDataResult:nil error:error];
}
if (result) {
result(nil, error);
}
return;
}

[self.auth signInWithCredential:credential
completion:^(FIRUser *_Nullable user, NSError *_Nullable error) {
[self.auth signInAndRetrieveDataWithCredential:credential
completion:^(FIRAuthDataResult *_Nullable authResult,
NSError *_Nullable error) {
if (error && error.code == FIRAuthErrorCodeAccountExistsWithDifferentCredential) {
NSString *email = error.userInfo[kErrorUserInfoEmailKey];
[self handleAccountLinkingForEmail:email
Expand All @@ -185,20 +186,22 @@ - (void)signInWithProviderUI:(id<FUIAuthProvider>)providerUI
return;
}

if (result) {
result(user, error);
}

if (error) {
[self invokeResultCallbackWithUser:user error:error];
if (result) {
result(nil, error);
}
[self invokeResultCallbackWithAuthDataResult:nil error:error];
} else {
if (result) {
result(authResult.user, nil);
}
// Hide Auth Picker Controller which was presented modally.
if (isAuthPickerShown && presentingViewController.presentingViewController) {
[presentingViewController dismissViewControllerAnimated:YES completion:^{
[self invokeResultCallbackWithUser:user error:error];
[self invokeResultCallbackWithAuthDataResult:authResult error:nil];
}];
} else {
[self invokeResultCallbackWithUser:user error:error];
[self invokeResultCallbackWithAuthDataResult:authResult error:nil];
}
}
}];
Expand All @@ -224,7 +227,7 @@ - (void)handleAccountLinkingForEmail:(NSString *)email
presentingViewController:presentingViewController];
} else {
[presentingViewController dismissViewControllerAnimated:YES completion:^{
[self invokeResultCallbackWithUser:nil error:error];
[self invokeResultCallbackWithAuthDataResult:nil error:error];
}];
}
return;
Expand Down Expand Up @@ -287,29 +290,30 @@ - (void)handleAccountLinkingForEmail:(NSString *)email
}
return;
}
[self invokeResultCallbackWithUser:nil error:error];
[self invokeResultCallbackWithAuthDataResult:nil error:error];
return;
}

[self.auth signInWithCredential:credential completion:^(FIRUser *_Nullable user,
NSError *_Nullable error) {
if (error) {
[self invokeResultCallbackWithUser:nil error:error];
[self invokeResultCallbackWithAuthDataResult:nil error:error];
if (result) {
result(nil, error);
}
return;
}

[user linkWithCredential:newCredential completion:^(FIRUser *_Nullable user,
NSError *_Nullable error) {
[user linkAndRetrieveDataWithCredential:newCredential
completion:^(FIRAuthDataResult *_Nullable authResult,
NSError *_Nullable error) {
if (result) {
result(user, error);
result(authResult.user, error);
}
// Ignore any error (most likely caused by email mismatch) and treat the user as
// successfully signed in.
[presentingViewController dismissViewControllerAnimated:YES completion:^{
[self invokeResultCallbackWithUser:user error:nil];
[self invokeResultCallbackWithAuthDataResult:authResult error:nil];
}];
}];
}];
Expand All @@ -322,9 +326,15 @@ - (void)handleAccountLinkingForEmail:(NSString *)email

#pragma mark - Internal Methods

- (void)invokeResultCallbackWithUser:(FIRUser *_Nullable)user error:(NSError *_Nullable)error {
- (void)invokeResultCallbackWithAuthDataResult:(nullable FIRAuthDataResult *)authDataResult
error:(nullable NSError *)error {
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate authUI:self didSignInWithUser:user error:error];
if ([self.delegate respondsToSelector:@selector(authUI:didSignInWithAuthDataResult:error:)]) {
[self.delegate authUI:self didSignInWithAuthDataResult:authDataResult error:error];
}
if ([self.delegate respondsToSelector:@selector(authUI:didSignInWithUser:error:)]) {
[self.delegate authUI:self didSignInWithUser:authDataResult.user error:error];
}
});
}

Expand Down
2 changes: 1 addition & 1 deletion FirebaseAuthUI/FUIAuthBaseViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ - (void)decrementActivity {
- (void)cancelAuthorization {
[self.navigationController dismissViewControllerAnimated:YES completion:^{
NSError *error = [FUIAuthErrorUtils userCancelledSignInError];
[self.authUI invokeResultCallbackWithUser:nil error:error];
[self.authUI invokeResultCallbackWithAuthDataResult:nil error:error];
}];
}

Expand Down
11 changes: 6 additions & 5 deletions FirebaseAuthUI/FUIAuth_Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ NS_ASSUME_NONNULL_BEGIN

@interface FUIAuth ()

/** @fn invokeResultCallbackWithUser:error:
/** @fn invokeResultCallbackWithAuthDataResult:error:
@brief Invokes the auth UI result callback.
@param user The user signed in, if any.
@param authDataResult The sign in data result, if any.
@param error The error which occurred, if any.
*/
- (void)invokeResultCallbackWithUser:(FIRUser *_Nullable)user error:(NSError *_Nullable)error;
- (void)invokeResultCallbackWithAuthDataResult:(nullable FIRAuthDataResult *)authDataResult
error:(nullable NSError *)error;

/** @fn invokeOperationCallback:error:
@brief Invokes the auth UI operation callback.
Expand All @@ -43,8 +44,8 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable id<FUIAuthProvider>)providerWithID:(NSString *)providerID;

/** @fn signInWithProviderUI:presentingViewController:defaultValue:
@brief Signs in with specified provider. @see FUIAuthDelegate.authUI:didSignInWithUser:error:
for method callback.
@brief Signs in with specified provider.
@see FUIAuthDelegate.authUI:didSignInWithAuthDataResult:error: for method callback.
@param providerUI The authentication provider used for signing in.
@param presentingViewController The view controller used to present the UI.
@param defaultValue The provider default initialization value (e g email or phone number)
Expand Down
23 changes: 12 additions & 11 deletions FirebaseAuthUI/FUIEmailEntryViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ - (void)onNext:(NSString *)emailText {
[self showAlertWithMessage:FUILocalizedString(kStr_InvalidEmailError)];
} else {
[self.navigationController dismissViewControllerAnimated:YES completion:^{
[self.authUI invokeResultCallbackWithUser:nil error:error];
[self.authUI invokeResultCallbackWithAuthDataResult:nil error:error];
}];
}
return;
Expand Down Expand Up @@ -261,34 +261,35 @@ - (void)signInWithProvider:(id<FUIAuthProvider>)provider email:(NSString *)email
// Sign out first to make sure sign in starts with a clean state.
[provider signOut];
[provider signInWithDefaultValue:email
presentingViewController:self
completion:^(FIRAuthCredential *_Nullable credential,
NSError *_Nullable error,
_Nullable FIRAuthResultCallback result) {
presentingViewController:self
completion:^(FIRAuthCredential *_Nullable credential,
NSError *_Nullable error,
_Nullable FIRAuthResultCallback result) {
if (error) {
[self decrementActivity];
if (result) {
result(nil, error);
}

[self.navigationController dismissViewControllerAnimated:YES completion:^{
[self.authUI invokeResultCallbackWithUser:nil error:error];
[self.authUI invokeResultCallbackWithAuthDataResult:nil error:error];
}];
return;
}

[self.auth signInWithCredential:credential
completion:^(FIRUser *_Nullable user, NSError *_Nullable error) {
[self.auth signInAndRetrieveDataWithCredential:credential
completion:^(FIRAuthDataResult *_Nullable authResult,
NSError *_Nullable error) {
[self decrementActivity];
if (result) {
result(user, error);
result(authResult.user, error);
}

if (error) {
[self.authUI invokeResultCallbackWithUser:nil error:error];
[self.authUI invokeResultCallbackWithAuthDataResult:nil error:error];
} else {
[self.navigationController dismissViewControllerAnimated:YES completion:^{
[self.authUI invokeResultCallbackWithUser:user error:error];
[self.authUI invokeResultCallbackWithAuthDataResult:authResult error:error];
}];
}
}];
Expand Down
40 changes: 18 additions & 22 deletions FirebaseAuthUI/FUIPasswordRecoveryViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -121,28 +121,24 @@ - (void)recoverEmail:(NSString *)email {

[self.auth sendPasswordResetWithEmail:email
completion:^(NSError *_Nullable error) {
// The dispatch is a workaround for a bug in FirebaseAuth 3.0.2, which doesn't call the
// completion block on the main queue.
dispatch_async(dispatch_get_main_queue(), ^{
[self decrementActivity];

if (error) {
if (error.code == FIRAuthErrorCodeUserNotFound) {
[self showAlertWithMessage:FUILocalizedString(kStr_UserNotFoundError)];
return;
}

[self.navigationController dismissViewControllerAnimated:YES completion:^{
[self.authUI invokeResultCallbackWithUser:nil error:error];
}];
return;
}

NSString *message =
[NSString stringWithFormat:FUILocalizedString(kStr_PasswordRecoveryEmailSentMessage), email];
[self showAlertWithMessage:message];
});
}];
[self decrementActivity];

if (error) {
if (error.code == FIRAuthErrorCodeUserNotFound) {
[self showAlertWithMessage:FUILocalizedString(kStr_UserNotFoundError)];
return;
}

[self.navigationController dismissViewControllerAnimated:YES completion:^{
[self.authUI invokeResultCallbackWithAuthDataResult:nil error:error];
}];
return;
}

NSString *message = [NSString stringWithFormat:
FUILocalizedString(kStr_PasswordRecoveryEmailSentMessage), email];
[self showAlertWithMessage:message];
}];
}

- (void)textFieldDidChange {
Expand Down
Loading