Skip to content

Commit bc2d784

Browse files
authored
Adds AuthDataResult to signInWithEmailPassword Method (#484)
* Adds AuthDataResult to signInWithEmail:Password * Addresses comments * Addresses comments * addresses more comments * Fixes broken tests
1 parent 3e59252 commit bc2d784

File tree

4 files changed

+187
-8
lines changed

4 files changed

+187
-8
lines changed

Example/Auth/Sample/MainViewController.m

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@
106106
*/
107107
static NSString *const kSignInEmailPasswordButtonText = @"Sign in with Email/Password";
108108

109+
/** @var kSignInEmailPasswordAuthDataResultButtonText
110+
@brief The text of the "Email/Password SignIn (AuthDataResult)" button.
111+
*/
112+
static NSString *const kSignInEmailPasswordAuthDataResultButtonText =
113+
@"Sign in with Email/Password (AuthDataReult)";
114+
109115
/** @var kSignInWithCustomTokenButtonText
110116
@brief The text of the "Sign In (BYOAuth)" button.
111117
*/
@@ -711,6 +717,8 @@ - (void)updateTable {
711717
action:^{ [weakSelf signInFacebookAndRetrieveData]; }],
712718
[StaticContentTableViewCell cellWithTitle:kSignInEmailPasswordButtonText
713719
action:^{ [weakSelf signInEmailPassword]; }],
720+
[StaticContentTableViewCell cellWithTitle:kSignInEmailPasswordAuthDataResultButtonText
721+
action:^{ [weakSelf signInEmailPasswordAuthDataResult]; }],
714722
[StaticContentTableViewCell cellWithTitle:kSignInWithCustomTokenButtonText
715723
action:^{ [weakSelf signInWithCustomToken]; }],
716724
[StaticContentTableViewCell cellWithTitle:kSignInAnonymouslyButtonText
@@ -1650,15 +1658,48 @@ - (void)signInEmailPassword {
16501658
}
16511659
FIRAuthCredential *credential =
16521660
[FIREmailAuthProvider credentialWithEmail:email
1653-
password:password];
1661+
password:password];
16541662
[self showSpinner:^{
16551663
[[AppManager auth] signInWithCredential:credential
1656-
completion:^(FIRUser *_Nullable user, NSError *_Nullable error) {
1664+
completion:^(FIRUser *_Nullable user,
1665+
NSError *_Nullable error) {
1666+
[self hideSpinner:^{
1667+
if (error) {
1668+
[self logFailure:@"sign-in with Email/Password failed" error:error];
1669+
} else {
1670+
[self logSuccess:@"sign-in with Email/Password succeeded."];
1671+
}
1672+
[self showTypicalUIForUserUpdateResultsWithTitle:@"Sign-In Error" error:error];
1673+
}];
1674+
}];
1675+
}];
1676+
}];
1677+
}];
1678+
}
1679+
1680+
- (void)signInEmailPasswordAuthDataResult {
1681+
[self showTextInputPromptWithMessage:@"Email Address:"
1682+
keyboardType:UIKeyboardTypeEmailAddress
1683+
completionBlock:^(BOOL userPressedOK, NSString *_Nullable email) {
1684+
if (!userPressedOK || !email.length) {
1685+
return;
1686+
}
1687+
[self showTextInputPromptWithMessage:@"Password:"
1688+
completionBlock:^(BOOL userPressedOK, NSString *_Nullable password) {
1689+
if (!userPressedOK) {
1690+
return;
1691+
}
1692+
[self showSpinner:^{
1693+
[[AppManager auth] signInAndRetrieveDataWithEmail:email
1694+
password:password
1695+
completion:^(FIRAuthDataResult *_Nullable authResult,
1696+
NSError *_Nullable error) {
16571697
[self hideSpinner:^{
16581698
if (error) {
16591699
[self logFailure:@"sign-in with Email/Password failed" error:error];
16601700
} else {
16611701
[self logSuccess:@"sign-in with Email/Password succeeded."];
1702+
[self log:[NSString stringWithFormat:@"UID: %@",authResult.user.uid]];
16621703
}
16631704
[self showTypicalUIForUserUpdateResultsWithTitle:@"Sign-In Error" error:error];
16641705
}];

Example/Auth/Tests/FIRAuthTests.m

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,66 @@ - (void)testSignInWithEmailPasswordFailure {
548548
OCMVerifyAll(_mockBackend);
549549
}
550550

551+
/** @fn testSignInAndRetrieveDataWithEmailPasswordSuccess
552+
@brief Tests the flow of a successful @c signInAndRetrieveDataWithEmail:password:completion:
553+
call.
554+
*/
555+
- (void)testSignInAndRetrieveDataWithEmailPasswordSuccess {
556+
OCMExpect([_mockBackend verifyPassword:[OCMArg any] callback:[OCMArg any]])
557+
.andCallBlock2(^(FIRVerifyPasswordRequest *_Nullable request,
558+
FIRVerifyPasswordResponseCallback callback) {
559+
XCTAssertEqualObjects(request.APIKey, kAPIKey);
560+
XCTAssertEqualObjects(request.email, kEmail);
561+
XCTAssertEqualObjects(request.password, kFakePassword);
562+
XCTAssertTrue(request.returnSecureToken);
563+
dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
564+
id mockVerifyPasswordResponse = OCMClassMock([FIRVerifyPasswordResponse class]);
565+
[self stubTokensWithMockResponse:mockVerifyPasswordResponse];
566+
callback(mockVerifyPasswordResponse, nil);
567+
});
568+
});
569+
[self expectGetAccountInfo];
570+
XCTestExpectation *expectation = [self expectationWithDescription:@"callback"];
571+
[[FIRAuth auth] signOut:NULL];
572+
[[FIRAuth auth] signInAndRetrieveDataWithEmail:kEmail
573+
password:kFakePassword
574+
completion:^(FIRAuthDataResult *_Nullable result,
575+
NSError *_Nullable error) {
576+
XCTAssertTrue([NSThread isMainThread]);
577+
[self assertUser:result.user];
578+
XCTAssertFalse(result.additionalUserInfo.isNewUser);
579+
XCTAssertEqualObjects(result.additionalUserInfo.providerID, FIREmailAuthProviderID);
580+
XCTAssertNil(error);
581+
[expectation fulfill];
582+
}];
583+
[self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
584+
[self assertUser:[FIRAuth auth].currentUser];
585+
OCMVerifyAll(_mockBackend);
586+
}
587+
588+
/** @fn testSignInAndRetrieveDataWithEmailPasswordFailure
589+
@brief Tests the flow of a failed @c signInAndRetrieveDataWithEmail:password:completion: call.
590+
*/
591+
- (void)testSignInAndRetrieveDataWithEmailPasswordFailure {
592+
OCMExpect([_mockBackend verifyPassword:[OCMArg any] callback:[OCMArg any]])
593+
.andDispatchError2([FIRAuthErrorUtils wrongPasswordErrorWithMessage:nil]);
594+
XCTestExpectation *expectation = [self expectationWithDescription:@"callback"];
595+
[[FIRAuth auth] signOut:NULL];
596+
[[FIRAuth auth] signInAndRetrieveDataWithEmail:kEmail
597+
password:kFakePassword
598+
completion:^(FIRAuthDataResult *_Nullable result,
599+
NSError *_Nullable error) {
600+
XCTAssertTrue([NSThread isMainThread]);
601+
XCTAssertNil(result);
602+
XCTAssertEqual(error.code, FIRAuthErrorCodeWrongPassword);
603+
XCTAssertNotNil(error.userInfo[NSLocalizedDescriptionKey]);
604+
[expectation fulfill];
605+
}];
606+
[self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
607+
XCTAssertNil([FIRAuth auth].currentUser);
608+
OCMVerifyAll(_mockBackend);
609+
}
610+
551611
/** @fn testResetPasswordSuccess
552612
@brief Tests the flow of a successful @c confirmPasswordResetWithCode:newPassword:completion:
553613
call.

Firebase/Auth/Source/FIRAuth.m

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -512,9 +512,14 @@ - (void)signInWithEmail:(NSString *)email
512512
password:(NSString *)password
513513
completion:(FIRAuthResultCallback)completion {
514514
dispatch_async(FIRAuthGlobalWorkQueue(), ^{
515-
[self signInWithEmail:email
516-
password:password
517-
callback:[self signInFlowAuthResultCallbackByDecoratingCallback:completion]];
515+
FIRAuthResultCallback decoratedCallback =
516+
[self signInFlowAuthResultCallbackByDecoratingCallback:completion];
517+
[self internalSignInAndRetrieveDataWithEmail:email
518+
password:password
519+
completion:^(FIRAuthDataResult *_Nullable authResult,
520+
NSError *_Nullable error) {
521+
decoratedCallback(authResult.user, error);
522+
}];
518523
});
519524
}
520525

@@ -554,6 +559,37 @@ - (void)signInWithEmail:(NSString *)email
554559
}];
555560
}
556561

562+
- (void)signInAndRetrieveDataWithEmail:(NSString *)email
563+
password:(NSString *)password
564+
completion:(FIRAuthDataResultCallback)completion {
565+
dispatch_async(FIRAuthGlobalWorkQueue(), ^{
566+
FIRAuthDataResultCallback decoratedCallback =
567+
[self signInFlowAuthDataResultCallbackByDecoratingCallback:completion];
568+
[self internalSignInAndRetrieveDataWithEmail:email
569+
password:password
570+
completion:decoratedCallback];
571+
});
572+
}
573+
574+
/** @fn internalSignInAndRetrieveDataWithEmail:password:callback:
575+
@brief Signs in using an email address and password.
576+
@param email The user's email address.
577+
@param password The user's password.
578+
@param completion A block which is invoked when the sign in finishes (or is cancelled.) Invoked
579+
asynchronously on the global auth work queue in the future.
580+
@remarks This is the internal counterpart of this method, which uses a callback that does not
581+
update the current user.
582+
*/
583+
- (void)internalSignInAndRetrieveDataWithEmail:(NSString *)email
584+
password:(NSString *)password
585+
completion:(FIRAuthDataResultCallback)completion {
586+
FIREmailPasswordAuthCredential *credentail =
587+
[[FIREmailPasswordAuthCredential alloc] initWithEmail:email password:password];
588+
[self internalSignInAndRetrieveDataWithCredential:credentail
589+
isReauthentication:NO
590+
callback:completion];
591+
}
592+
557593
- (void)signInWithCredential:(FIRAuthCredential *)credential
558594
completion:(FIRAuthResultCallback)completion {
559595
dispatch_async(FIRAuthGlobalWorkQueue(), ^{
@@ -595,9 +631,18 @@ - (void)internalSignInAndRetrieveDataWithCredential:(FIRAuthCredential *)credent
595631
password:emailPasswordCredential.password
596632
callback:^(FIRUser *_Nullable user, NSError *_Nullable error) {
597633
if (callback) {
598-
FIRAuthDataResult *result = user ?
599-
[[FIRAuthDataResult alloc] initWithUser:user additionalUserInfo:nil] : nil;
600-
callback(result, error);
634+
if (error) {
635+
callback(nil, error);
636+
return;
637+
}
638+
FIRAdditionalUserInfo *additionalUserInfo =
639+
[[FIRAdditionalUserInfo alloc] initWithProviderID:FIREmailAuthProviderID
640+
profile:nil
641+
username:nil
642+
isNewUser:NO];
643+
FIRAuthDataResult *result = [[FIRAuthDataResult alloc] initWithUser:user
644+
additionalUserInfo:additionalUserInfo];
645+
callback(result, nil);
601646
}
602647
}];
603648
return;

Firebase/Auth/Source/Public/FIRAuth.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,39 @@ FIR_SWIFT_NAME(Auth)
329329
password:(NSString *)password
330330
completion:(nullable FIRAuthResultCallback)completion;
331331

332+
/** @fn signInAndRetrieveDataWithEmail:password:completion:
333+
@brief Signs in using an email address and password.
334+
335+
@param email The user's email address.
336+
@param password The user's password.
337+
@param completion Optionally; a block which is invoked when the sign in flow finishes, or is
338+
canceled. Invoked asynchronously on the main thread in the future.
339+
340+
@remarks Possible error codes:
341+
342+
<ul>
343+
<li>@c FIRAuthErrorCodeOperationNotAllowed - Indicates that email and password
344+
accounts are not enabled. Enable them in the Auth section of the
345+
Firebase console.
346+
</li>
347+
<li>@c FIRAuthErrorCodeUserDisabled - Indicates the user's account is disabled.
348+
</li>
349+
<li>@c FIRAuthErrorCodeWrongPassword - Indicates the user attempted
350+
sign in with an incorrect password.
351+
</li>
352+
<li>@c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed.
353+
</li>
354+
</ul>
355+
356+
@remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods.
357+
@remarks This method will only exist until the next major Firebase release following 4.x.x.
358+
After the next major release the method @c signInWithEmail:password:completion: will support
359+
the @c FIRAuthDataResultCallback.
360+
*/
361+
- (void)signInAndRetrieveDataWithEmail:(NSString *)email
362+
password:(NSString *)password
363+
completion:(nullable FIRAuthDataResultCallback)completion;
364+
332365
/** @fn signInWithCredential:completion:
333366
@brief Convenience method for @c signInAndRetrieveDataWithCredential:completion: This method
334367
doesn't return additional identity provider data.

0 commit comments

Comments
 (0)