aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Example/Auth/Sample/MainViewController.m45
-rw-r--r--Example/Auth/Tests/FIRAuthTests.m60
-rw-r--r--Firebase/Auth/Source/FIRAuth.m57
-rw-r--r--Firebase/Auth/Source/Public/FIRAuth.h33
4 files changed, 187 insertions, 8 deletions
diff --git a/Example/Auth/Sample/MainViewController.m b/Example/Auth/Sample/MainViewController.m
index 5831d34..42f0a8e 100644
--- a/Example/Auth/Sample/MainViewController.m
+++ b/Example/Auth/Sample/MainViewController.m
@@ -106,6 +106,12 @@ static NSString *const kSignInFacebookAndRetrieveDataButtonText =
*/
static NSString *const kSignInEmailPasswordButtonText = @"Sign in with Email/Password";
+/** @var kSignInEmailPasswordAuthDataResultButtonText
+ @brief The text of the "Email/Password SignIn (AuthDataResult)" button.
+ */
+static NSString *const kSignInEmailPasswordAuthDataResultButtonText =
+ @"Sign in with Email/Password (AuthDataReult)";
+
/** @var kSignInWithCustomTokenButtonText
@brief The text of the "Sign In (BYOAuth)" button.
*/
@@ -711,6 +717,8 @@ typedef enum {
action:^{ [weakSelf signInFacebookAndRetrieveData]; }],
[StaticContentTableViewCell cellWithTitle:kSignInEmailPasswordButtonText
action:^{ [weakSelf signInEmailPassword]; }],
+ [StaticContentTableViewCell cellWithTitle:kSignInEmailPasswordAuthDataResultButtonText
+ action:^{ [weakSelf signInEmailPasswordAuthDataResult]; }],
[StaticContentTableViewCell cellWithTitle:kSignInWithCustomTokenButtonText
action:^{ [weakSelf signInWithCustomToken]; }],
[StaticContentTableViewCell cellWithTitle:kSignInAnonymouslyButtonText
@@ -1650,15 +1658,48 @@ static NSDictionary<NSString *, NSString *> *parseURL(NSString *urlString) {
}
FIRAuthCredential *credential =
[FIREmailAuthProvider credentialWithEmail:email
- password:password];
+ password:password];
[self showSpinner:^{
[[AppManager auth] signInWithCredential:credential
- completion:^(FIRUser *_Nullable user, NSError *_Nullable error) {
+ completion:^(FIRUser *_Nullable user,
+ NSError *_Nullable error) {
+ [self hideSpinner:^{
+ if (error) {
+ [self logFailure:@"sign-in with Email/Password failed" error:error];
+ } else {
+ [self logSuccess:@"sign-in with Email/Password succeeded."];
+ }
+ [self showTypicalUIForUserUpdateResultsWithTitle:@"Sign-In Error" error:error];
+ }];
+ }];
+ }];
+ }];
+ }];
+}
+
+- (void)signInEmailPasswordAuthDataResult {
+ [self showTextInputPromptWithMessage:@"Email Address:"
+ keyboardType:UIKeyboardTypeEmailAddress
+ completionBlock:^(BOOL userPressedOK, NSString *_Nullable email) {
+ if (!userPressedOK || !email.length) {
+ return;
+ }
+ [self showTextInputPromptWithMessage:@"Password:"
+ completionBlock:^(BOOL userPressedOK, NSString *_Nullable password) {
+ if (!userPressedOK) {
+ return;
+ }
+ [self showSpinner:^{
+ [[AppManager auth] signInAndRetrieveDataWithEmail:email
+ password:password
+ completion:^(FIRAuthDataResult *_Nullable authResult,
+ NSError *_Nullable error) {
[self hideSpinner:^{
if (error) {
[self logFailure:@"sign-in with Email/Password failed" error:error];
} else {
[self logSuccess:@"sign-in with Email/Password succeeded."];
+ [self log:[NSString stringWithFormat:@"UID: %@",authResult.user.uid]];
}
[self showTypicalUIForUserUpdateResultsWithTitle:@"Sign-In Error" error:error];
}];
diff --git a/Example/Auth/Tests/FIRAuthTests.m b/Example/Auth/Tests/FIRAuthTests.m
index 35c8362..770f2c7 100644
--- a/Example/Auth/Tests/FIRAuthTests.m
+++ b/Example/Auth/Tests/FIRAuthTests.m
@@ -548,6 +548,66 @@ static const NSTimeInterval kWaitInterval = .5;
OCMVerifyAll(_mockBackend);
}
+/** @fn testSignInAndRetrieveDataWithEmailPasswordSuccess
+ @brief Tests the flow of a successful @c signInAndRetrieveDataWithEmail:password:completion:
+ call.
+ */
+- (void)testSignInAndRetrieveDataWithEmailPasswordSuccess {
+ OCMExpect([_mockBackend verifyPassword:[OCMArg any] callback:[OCMArg any]])
+ .andCallBlock2(^(FIRVerifyPasswordRequest *_Nullable request,
+ FIRVerifyPasswordResponseCallback callback) {
+ XCTAssertEqualObjects(request.APIKey, kAPIKey);
+ XCTAssertEqualObjects(request.email, kEmail);
+ XCTAssertEqualObjects(request.password, kFakePassword);
+ XCTAssertTrue(request.returnSecureToken);
+ dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
+ id mockVerifyPasswordResponse = OCMClassMock([FIRVerifyPasswordResponse class]);
+ [self stubTokensWithMockResponse:mockVerifyPasswordResponse];
+ callback(mockVerifyPasswordResponse, nil);
+ });
+ });
+ [self expectGetAccountInfo];
+ XCTestExpectation *expectation = [self expectationWithDescription:@"callback"];
+ [[FIRAuth auth] signOut:NULL];
+ [[FIRAuth auth] signInAndRetrieveDataWithEmail:kEmail
+ password:kFakePassword
+ completion:^(FIRAuthDataResult *_Nullable result,
+ NSError *_Nullable error) {
+ XCTAssertTrue([NSThread isMainThread]);
+ [self assertUser:result.user];
+ XCTAssertFalse(result.additionalUserInfo.isNewUser);
+ XCTAssertEqualObjects(result.additionalUserInfo.providerID, FIREmailAuthProviderID);
+ XCTAssertNil(error);
+ [expectation fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
+ [self assertUser:[FIRAuth auth].currentUser];
+ OCMVerifyAll(_mockBackend);
+}
+
+/** @fn testSignInAndRetrieveDataWithEmailPasswordFailure
+ @brief Tests the flow of a failed @c signInAndRetrieveDataWithEmail:password:completion: call.
+ */
+- (void)testSignInAndRetrieveDataWithEmailPasswordFailure {
+ OCMExpect([_mockBackend verifyPassword:[OCMArg any] callback:[OCMArg any]])
+ .andDispatchError2([FIRAuthErrorUtils wrongPasswordErrorWithMessage:nil]);
+ XCTestExpectation *expectation = [self expectationWithDescription:@"callback"];
+ [[FIRAuth auth] signOut:NULL];
+ [[FIRAuth auth] signInAndRetrieveDataWithEmail:kEmail
+ password:kFakePassword
+ completion:^(FIRAuthDataResult *_Nullable result,
+ NSError *_Nullable error) {
+ XCTAssertTrue([NSThread isMainThread]);
+ XCTAssertNil(result);
+ XCTAssertEqual(error.code, FIRAuthErrorCodeWrongPassword);
+ XCTAssertNotNil(error.userInfo[NSLocalizedDescriptionKey]);
+ [expectation fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
+ XCTAssertNil([FIRAuth auth].currentUser);
+ OCMVerifyAll(_mockBackend);
+}
+
/** @fn testResetPasswordSuccess
@brief Tests the flow of a successful @c confirmPasswordResetWithCode:newPassword:completion:
call.
diff --git a/Firebase/Auth/Source/FIRAuth.m b/Firebase/Auth/Source/FIRAuth.m
index 9020d3f..a104ad8 100644
--- a/Firebase/Auth/Source/FIRAuth.m
+++ b/Firebase/Auth/Source/FIRAuth.m
@@ -512,9 +512,14 @@ static NSMutableDictionary *gKeychainServiceNameForAppName;
password:(NSString *)password
completion:(FIRAuthResultCallback)completion {
dispatch_async(FIRAuthGlobalWorkQueue(), ^{
- [self signInWithEmail:email
- password:password
- callback:[self signInFlowAuthResultCallbackByDecoratingCallback:completion]];
+ FIRAuthResultCallback decoratedCallback =
+ [self signInFlowAuthResultCallbackByDecoratingCallback:completion];
+ [self internalSignInAndRetrieveDataWithEmail:email
+ password:password
+ completion:^(FIRAuthDataResult *_Nullable authResult,
+ NSError *_Nullable error) {
+ decoratedCallback(authResult.user, error);
+ }];
});
}
@@ -554,6 +559,37 @@ static NSMutableDictionary *gKeychainServiceNameForAppName;
}];
}
+- (void)signInAndRetrieveDataWithEmail:(NSString *)email
+ password:(NSString *)password
+ completion:(FIRAuthDataResultCallback)completion {
+ dispatch_async(FIRAuthGlobalWorkQueue(), ^{
+ FIRAuthDataResultCallback decoratedCallback =
+ [self signInFlowAuthDataResultCallbackByDecoratingCallback:completion];
+ [self internalSignInAndRetrieveDataWithEmail:email
+ password:password
+ completion:decoratedCallback];
+ });
+}
+
+/** @fn internalSignInAndRetrieveDataWithEmail:password:callback:
+ @brief Signs in using an email address and password.
+ @param email The user's email address.
+ @param password The user's password.
+ @param completion A block which is invoked when the sign in finishes (or is cancelled.) Invoked
+ asynchronously on the global auth work queue in the future.
+ @remarks This is the internal counterpart of this method, which uses a callback that does not
+ update the current user.
+ */
+- (void)internalSignInAndRetrieveDataWithEmail:(NSString *)email
+ password:(NSString *)password
+ completion:(FIRAuthDataResultCallback)completion {
+ FIREmailPasswordAuthCredential *credentail =
+ [[FIREmailPasswordAuthCredential alloc] initWithEmail:email password:password];
+ [self internalSignInAndRetrieveDataWithCredential:credentail
+ isReauthentication:NO
+ callback:completion];
+}
+
- (void)signInWithCredential:(FIRAuthCredential *)credential
completion:(FIRAuthResultCallback)completion {
dispatch_async(FIRAuthGlobalWorkQueue(), ^{
@@ -595,9 +631,18 @@ static NSMutableDictionary *gKeychainServiceNameForAppName;
password:emailPasswordCredential.password
callback:^(FIRUser *_Nullable user, NSError *_Nullable error) {
if (callback) {
- FIRAuthDataResult *result = user ?
- [[FIRAuthDataResult alloc] initWithUser:user additionalUserInfo:nil] : nil;
- callback(result, error);
+ if (error) {
+ callback(nil, error);
+ return;
+ }
+ FIRAdditionalUserInfo *additionalUserInfo =
+ [[FIRAdditionalUserInfo alloc] initWithProviderID:FIREmailAuthProviderID
+ profile:nil
+ username:nil
+ isNewUser:NO];
+ FIRAuthDataResult *result = [[FIRAuthDataResult alloc] initWithUser:user
+ additionalUserInfo:additionalUserInfo];
+ callback(result, nil);
}
}];
return;
diff --git a/Firebase/Auth/Source/Public/FIRAuth.h b/Firebase/Auth/Source/Public/FIRAuth.h
index 1aa4bcf..9a115ee 100644
--- a/Firebase/Auth/Source/Public/FIRAuth.h
+++ b/Firebase/Auth/Source/Public/FIRAuth.h
@@ -329,6 +329,39 @@ FIR_SWIFT_NAME(Auth)
password:(NSString *)password
completion:(nullable FIRAuthResultCallback)completion;
+/** @fn signInAndRetrieveDataWithEmail:password:completion:
+ @brief Signs in using an email address and password.
+
+ @param email The user's email address.
+ @param password The user's password.
+ @param completion Optionally; a block which is invoked when the sign in flow finishes, or is
+ canceled. Invoked asynchronously on the main thread in the future.
+
+ @remarks Possible error codes:
+
+ <ul>
+ <li>@c FIRAuthErrorCodeOperationNotAllowed - Indicates that email and password
+ accounts are not enabled. Enable them in the Auth section of the
+ Firebase console.
+ </li>
+ <li>@c FIRAuthErrorCodeUserDisabled - Indicates the user's account is disabled.
+ </li>
+ <li>@c FIRAuthErrorCodeWrongPassword - Indicates the user attempted
+ sign in with an incorrect password.
+ </li>
+ <li>@c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed.
+ </li>
+ </ul>
+
+ @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods.
+ @remarks This method will only exist until the next major Firebase release following 4.x.x.
+ After the next major release the method @c signInWithEmail:password:completion: will support
+ the @c FIRAuthDataResultCallback.
+ */
+- (void)signInAndRetrieveDataWithEmail:(NSString *)email
+ password:(NSString *)password
+ completion:(nullable FIRAuthDataResultCallback)completion;
+
/** @fn signInWithCredential:completion:
@brief Convenience method for @c signInAndRetrieveDataWithCredential:completion: This method
doesn't return additional identity provider data.