aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Zsika Phillip <protocol86@users.noreply.github.com>2017-11-20 15:56:03 -0800
committerGravatar GitHub <noreply@github.com>2017-11-20 15:56:03 -0800
commit54aef651d82ebcc529498e4eba945a5512af4c95 (patch)
treee82d83503560c6f5dd77156bdf5ff9044071a38d
parent1670f1c5ddf1d9b4fab6b9b6d0e00323af48e967 (diff)
Add Auth Result to createUserWithEmail (#477)
-rw-r--r--Example/Auth/Sample/MainViewController.m44
-rw-r--r--Example/Auth/Tests/FIRAuthTests.m62
-rw-r--r--Firebase/Auth/Source/FIRAuth.m82
-rw-r--r--Firebase/Auth/Source/Public/FIRAuth.h34
4 files changed, 205 insertions, 17 deletions
diff --git a/Example/Auth/Sample/MainViewController.m b/Example/Auth/Sample/MainViewController.m
index 4708b4c..eb45226 100644
--- a/Example/Auth/Sample/MainViewController.m
+++ b/Example/Auth/Sample/MainViewController.m
@@ -384,6 +384,11 @@ static NSString *const kSectionTitleApp = @"APP";
*/
static NSString *const kCreateUserTitle = @"Create User";
+/** @var kCreateUserAuthDataResultTitle
+ @brief The text of the "Create User (AuthDataResult)" button.
+ */
+static NSString *const kCreateUserAuthDataResultTitle = @"Create User (AuthDataResult)";
+
/** @var kDeleteAppTitle
@brief The text of the "Delete App" button.
*/
@@ -694,6 +699,8 @@ typedef enum {
value:nil
action:^{ [weakSelf createUser]; }
accessibilityID:kCreateUserAccessibilityID],
+ [StaticContentTableViewCell cellWithTitle:kCreateUserAuthDataResultTitle
+ action:^{ [weakSelf createUserAuthDataResult]; }],
[StaticContentTableViewCell cellWithTitle:kSignInGoogleButtonText
action:^{ [weakSelf signInGoogle]; }],
[StaticContentTableViewCell cellWithTitle:kSignInGoogleAndRetrieveDataButtonText
@@ -2493,6 +2500,43 @@ static NSDictionary<NSString *, NSString *> *parseURL(NSString *urlString) {
}];
}
+/** @fn createUserAuthDataResult
+ @brief Creates a new user.
+ */
+- (void)createUserAuthDataResult {
+ [self showTextInputPromptWithMessage:@"Email:"
+ 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] createUserAndRetrieveDataWithEmail:email
+ password:password
+ completion:^(FIRAuthDataResult *_Nullable result,
+ NSError *_Nullable error) {
+ if (error) {
+ [self logFailure:@"create user failed" error:error];
+ } else {
+ [self logSuccess:@"create user succeeded."];
+ [self log:result.user.uid];
+ }
+ [self hideSpinner:^{
+ [self showTypicalUIForUserUpdateResultsWithTitle:kCreateUserTitle error:error];
+ }];
+ }];
+ }];
+ }];
+ }];
+}
+
/** @fn signInWithPhoneNumber
@brief Allows sign in with phone number.
*/
diff --git a/Example/Auth/Tests/FIRAuthTests.m b/Example/Auth/Tests/FIRAuthTests.m
index 557f0c7..2842ef3 100644
--- a/Example/Auth/Tests/FIRAuthTests.m
+++ b/Example/Auth/Tests/FIRAuthTests.m
@@ -1243,6 +1243,68 @@ static const NSTimeInterval kWaitInterval = .5;
OCMVerifyAll(_mockBackend);
}
+/** @fn testCreateUserAndRetrieveDataWithEmailPasswordSuccess
+ @brief Tests the flow of a successful @c createUserAndRetrieveDataWithEmail:password:completion:
+ call.
+ */
+- (void)testCreateUserAndRetrieveDataWithEmailPasswordSuccess {
+ OCMExpect([_mockBackend signUpNewUser:[OCMArg any] callback:[OCMArg any]])
+ .andCallBlock2(^(FIRSignUpNewUserRequest *_Nullable request,
+ FIRSignupNewUserCallback callback) {
+ XCTAssertEqualObjects(request.APIKey, kAPIKey);
+ XCTAssertEqualObjects(request.email, kEmail);
+ XCTAssertEqualObjects(request.password, kFakePassword);
+ XCTAssertTrue(request.returnSecureToken);
+ dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
+ id mockSignUpNewUserResponse = OCMClassMock([FIRSignUpNewUserResponse class]);
+ [self stubTokensWithMockResponse:mockSignUpNewUserResponse];
+ callback(mockSignUpNewUserResponse, nil);
+ });
+ });
+ [self expectGetAccountInfo];
+ XCTestExpectation *expectation = [self expectationWithDescription:@"callback"];
+ [[FIRAuth auth] signOut:NULL];
+ [[FIRAuth auth] createUserAndRetrieveDataWithEmail:kEmail
+ password:kFakePassword
+ completion:^(FIRAuthDataResult *_Nullable result,
+ NSError *_Nullable error) {
+ XCTAssertTrue([NSThread isMainThread]);
+ [self assertUser:result.user];
+ XCTAssertTrue(result.additionalUserInfo.isNewUser);
+ XCTAssertNil(error);
+ [expectation fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
+ [self assertUser:[FIRAuth auth].currentUser];
+ OCMVerifyAll(_mockBackend);
+}
+
+/** @fn testCreateUserAndRetrieveDataWithEmailPasswordFailure
+ @brief Tests the flow of a failed @c createUserAndRetrieveDataWithEmail:password:completion:
+ call.
+ */
+- (void)testCreateUserAndRetrieveDataWithEmailPasswordFailure {
+ NSString *reason = @"Password shouldn't be a common word.";
+ OCMExpect([_mockBackend signUpNewUser:[OCMArg any] callback:[OCMArg any]])
+ .andDispatchError2([FIRAuthErrorUtils weakPasswordErrorWithServerResponseReason:reason]);
+ XCTestExpectation *expectation = [self expectationWithDescription:@"callback"];
+ [[FIRAuth auth] signOut:NULL];
+ [[FIRAuth auth] createUserAndRetrieveDataWithEmail:kEmail
+ password:kFakePassword
+ completion:^(FIRAuthDataResult *_Nullable result,
+ NSError *_Nullable error) {
+ XCTAssertTrue([NSThread isMainThread]);
+ XCTAssertNil(result);
+ XCTAssertEqual(error.code, FIRAuthErrorCodeWeakPassword);
+ XCTAssertNotNil(error.userInfo[NSLocalizedDescriptionKey]);
+ XCTAssertEqualObjects(error.userInfo[NSLocalizedFailureReasonErrorKey], reason);
+ [expectation fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
+ XCTAssertNil([FIRAuth auth].currentUser);
+ OCMVerifyAll(_mockBackend);
+}
+
/** @fn testCreateUserEmptyPasswordFailure
@brief Tests the flow of a failed @c createUserWithEmail:password:completion: call due to an
empty password. This error occurs on the client side, so there is no need to fake an RPC
diff --git a/Firebase/Auth/Source/FIRAuth.m b/Firebase/Auth/Source/FIRAuth.m
index fda84fa..9020d3f 100644
--- a/Firebase/Auth/Source/FIRAuth.m
+++ b/Firebase/Auth/Source/FIRAuth.m
@@ -770,23 +770,10 @@ static NSMutableDictionary *gKeychainServiceNameForAppName;
dispatch_async(FIRAuthGlobalWorkQueue(), ^{
FIRAuthResultCallback decoratedCallback =
[self signInFlowAuthResultCallbackByDecoratingCallback:completion];
- FIRSignUpNewUserRequest *request =
- [[FIRSignUpNewUserRequest alloc] initWithEmail:email
- password:password
- displayName:nil
- requestConfiguration:_requestConfiguration];
- if (![request.password length]) {
- decoratedCallback(nil, [FIRAuthErrorUtils
- weakPasswordErrorWithServerResponseReason:kMissingPasswordReason]);
- return;
- }
- if (![request.email length]) {
- decoratedCallback(nil, [FIRAuthErrorUtils missingEmailErrorWithMessage:nil]);
- return;
- }
- [FIRAuthBackend signUpNewUser:request
- callback:^(FIRSignUpNewUserResponse *_Nullable response,
- NSError *_Nullable error) {
+ [self internalCreateUserWithEmail:email
+ password:password
+ completion:^(FIRSignUpNewUserResponse *_Nullable response,
+ NSError *_Nullable error) {
if (error) {
decoratedCallback(nil, error);
return;
@@ -800,6 +787,40 @@ static NSMutableDictionary *gKeychainServiceNameForAppName;
});
}
+- (void)createUserAndRetrieveDataWithEmail:(NSString *)email
+ password:(NSString *)password
+ completion:(FIRAuthDataResultCallback)completion {
+ dispatch_async(FIRAuthGlobalWorkQueue(), ^{
+ FIRAuthDataResultCallback decoratedCallback =
+ [self signInFlowAuthDataResultCallbackByDecoratingCallback:completion];
+ [self internalCreateUserWithEmail:email
+ password:password
+ completion:^(FIRSignUpNewUserResponse *_Nullable response,
+ NSError *_Nullable error) {
+ if (error) {
+ decoratedCallback(nil, error);
+ return;
+ }
+
+ [self completeSignInWithAccessToken:response.IDToken
+ accessTokenExpirationDate:response.approximateExpirationDate
+ refreshToken:response.refreshToken
+ anonymous:NO
+ callback:^(FIRUser *_Nullable user, NSError *_Nullable error) {
+ FIRAdditionalUserInfo *additionalUserInfo =
+ [[FIRAdditionalUserInfo alloc] initWithProviderID:FIREmailAuthProviderID
+ profile:nil
+ username:nil
+ isNewUser:YES];
+ FIRAuthDataResult *authDataResult =
+ [[FIRAuthDataResult alloc] initWithUser:user
+ additionalUserInfo:additionalUserInfo];
+ decoratedCallback(authDataResult, nil);
+ }];
+ }];
+ });
+}
+
- (void)confirmPasswordResetWithCode:(NSString *)code
newPassword:(NSString *)newPassword
completion:(FIRConfirmPasswordResetCallback)completion {
@@ -1130,6 +1151,33 @@ static NSMutableDictionary *gKeychainServiceNameForAppName;
}
#endif
+/** @fn internalCreateUserWithEmail:password:completion:
+ @brief Makes a backend request attempting to create a new Firebase user given an email address
+ and password.
+ @param email The email address used to create the new Firebase user.
+ @param password The password used to create the new Firebase user.
+ @param completion Optionally; a block which is invoked when the request finishes.
+ */
+- (void)internalCreateUserWithEmail:(NSString *)email
+ password:(NSString *)password
+ completion:(nullable FIRSignupNewUserCallback)completion {
+ FIRSignUpNewUserRequest *request =
+ [[FIRSignUpNewUserRequest alloc] initWithEmail:email
+ password:password
+ displayName:nil
+ requestConfiguration:_requestConfiguration];
+ if (![request.password length]) {
+ completion(nil, [FIRAuthErrorUtils
+ weakPasswordErrorWithServerResponseReason:kMissingPasswordReason]);
+ return;
+ }
+ if (![request.email length]) {
+ completion(nil, [FIRAuthErrorUtils missingEmailErrorWithMessage:nil]);
+ return;
+ }
+ [FIRAuthBackend signUpNewUser:request callback:completion];
+}
+
/** @fn internalSignInAnonymouslyWithCompletion:
@param completion A block which is invoked when the anonymous sign in request completes.
*/
diff --git a/Firebase/Auth/Source/Public/FIRAuth.h b/Firebase/Auth/Source/Public/FIRAuth.h
index 2963d7b..1aa4bcf 100644
--- a/Firebase/Auth/Source/Public/FIRAuth.h
+++ b/Firebase/Auth/Source/Public/FIRAuth.h
@@ -484,6 +484,40 @@ FIR_SWIFT_NAME(Auth)
password:(NSString *)password
completion:(nullable FIRAuthResultCallback)completion;
+/** @fn createUserAndRetrieveDataWithEmail:password:completion:
+ @brief Creates and, on success, signs in a user with the given email address and password.
+
+ @param email The user's email address.
+ @param password The user's desired password.
+ @param completion Optionally; a block which is invoked when the sign up flow finishes, or is
+ canceled. Invoked asynchronously on the main thread in the future.
+
+ @remarks Possible error codes:
+ <ul>
+ <li>@c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed.
+ </li>
+ <li>@c FIRAuthErrorCodeEmailAlreadyInUse - Indicates the email used to attempt sign up
+ already exists. Call fetchProvidersForEmail to check which sign-in mechanisms the user
+ used, and prompt the user to sign in with one of those.
+ </li>
+ <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 FIRAuthErrorCodeWeakPassword - Indicates an attempt to set a password that is
+ considered too weak. The NSLocalizedFailureReasonErrorKey field in the NSError.userInfo
+ dictionary object will contain more detailed explanation that can be shown to the user.
+ </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 createUserWithEmail:password:completion: will
+ support the @c FIRAuthDataResultCallback.
+ */
+- (void)createUserAndRetrieveDataWithEmail:(NSString *)email
+ password:(NSString *)password
+ completion:(nullable FIRAuthDataResultCallback)completion;
+
/** @fn confirmPasswordResetWithCode:newPassword:completion:
@brief Resets the password given a code sent to the user outside of the app and a new password
for the user.