aboutsummaryrefslogtreecommitdiffhomepage
path: root/Example/Auth
diff options
context:
space:
mode:
Diffstat (limited to 'Example/Auth')
-rw-r--r--Example/Auth/ApiTests/AuthCredentialsTemplate.h4
-rw-r--r--Example/Auth/ApiTests/FirebaseAuthApiTests.m141
-rw-r--r--Example/Auth/App/GoogleService-Info.plist2
-rw-r--r--Example/Auth/App/tvOS/AppDelegate.h21
-rw-r--r--Example/Auth/App/tvOS/AppDelegate.m63
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json11
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json6
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json17
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json11
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json6
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json11
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json6
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json16
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json6
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json17
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json16
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json6
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json16
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json6
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json32
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json16
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json16
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/Contents.json6
-rw-r--r--Example/Auth/App/tvOS/Assets.xcassets/LaunchImage.launchimage/Contents.json22
-rw-r--r--Example/Auth/App/tvOS/Info.plist32
-rw-r--r--Example/Auth/App/tvOS/Main.storyboard28
-rw-r--r--Example/Auth/App/tvOS/ViewController.h19
-rw-r--r--Example/Auth/App/tvOS/ViewController.m33
-rw-r--r--Example/Auth/App/tvOS/main.m22
-rw-r--r--Example/Auth/Sample/MainViewController.m58
-rw-r--r--Example/Auth/Tests/FIRAuthTests.m10
-rw-r--r--Example/Auth/Tests/FIRVerifyPasswordRequestTest.m16
32 files changed, 663 insertions, 29 deletions
diff --git a/Example/Auth/ApiTests/AuthCredentialsTemplate.h b/Example/Auth/ApiTests/AuthCredentialsTemplate.h
index a8bf379..09eb62a 100644
--- a/Example/Auth/ApiTests/AuthCredentialsTemplate.h
+++ b/Example/Auth/ApiTests/AuthCredentialsTemplate.h
@@ -50,6 +50,9 @@ The name of the test user for Facebook Login.
$KCUSTOM_AUTH_TOKEN_URL
A URL to return a Custom Auth token.
+$KCUSTOM_AUTH_TOKEN_EXPIRED_URL
+A URL to return an expired Custom Auth token.
+
$KCUSTOM_AUTH_USER_ID
The ID of the test user in the Custom Auth token.
*/
@@ -61,4 +64,5 @@ The ID of the test user in the Custom Auth token.
#define KFACEBOOK_APP_ACCESS_TOKEN $KFACEBOOK_APP_ACCESS_TOKEN
#define KFACEBOOK_USER_NAME $KFACEBOOK_USER_NAME
#define KCUSTOM_AUTH_TOKEN_URL $KCUSTOM_AUTH_TOKEN_URL
+#define KCUSTOM_AUTH_TOKEN_EXPIRED_URL $KCUSTOM_AUTH_TOKEN_EXPIRED_URL
#define KCUSTOM_AUTH_USER_ID $KCUSTOM_AUTH_USER_ID
diff --git a/Example/Auth/ApiTests/FirebaseAuthApiTests.m b/Example/Auth/ApiTests/FirebaseAuthApiTests.m
index 454d9dd..741814c 100644
--- a/Example/Auth/ApiTests/FirebaseAuthApiTests.m
+++ b/Example/Auth/ApiTests/FirebaseAuthApiTests.m
@@ -36,6 +36,10 @@ static NSString *const kCustomAuthTestingAccountUserID = KCUSTOM_AUTH_USER_ID;
/** The url for obtaining a valid custom token string used to test Custom Auth. */
static NSString *const kCustomTokenUrl = KCUSTOM_AUTH_TOKEN_URL;
+/** The url for obtaining an expired but valid custom token string used to test Custom Auth failure.
+ */
+static NSString *const kExpiredCustomTokenUrl = KCUSTOM_AUTH_TOKEN_EXPIRED_URL;
+
/** Facebook app access token that will be used for Facebook Graph API, which is different from
* account access token.
*/
@@ -59,6 +63,12 @@ static NSString *const kTestingEmailToCreateUser = @"abc@xyz.com";
/** The testing email address for testSignInExistingUserWithEmailAndPassword. */
static NSString *const kExistingTestingEmailToSignIn = @"456@abc.com";
+/** The testing email address for testUpdatingUsersEmail. */
+static NSString *const kNewTestingEmail = @"updatedEmail@abc.com";
+
+/** The testing password for testSignInExistingUserWithModifiedEmailAndPassword. */
+static NSString *const kNewTestingPasswordToSignIn = @"password_new";
+
/** Error message for invalid custom token sign in. */
NSString *kInvalidTokenErrorMessage =
@"The custom token format is incorrect. Please check the documentation.";
@@ -71,7 +81,7 @@ NSString *kGoogleCliendId = KGOOGLE_CLIENT_ID;
*/
NSString *kGoogleTestAccountRefreshToken = KGOOGLE_TEST_ACCOUNT_REFRESH_TOKEN;
-static NSTimeInterval const kExpectationsTimeout = 30;
+static NSTimeInterval const kExpectationsTimeout = 10;
#ifdef NO_NETWORK
#define SKIP_IF_ON_MOBILE_HARNESS \
@@ -141,6 +151,38 @@ static NSTimeInterval const kExpectationsTimeout = 30;
[self deleteCurrentFirebaseUser];
}
+- (void)testUpdatingUsersEmail {
+ SKIP_IF_ON_MOBILE_HARNESS
+ FIRAuth *auth = [FIRAuth auth];
+ if (!auth) {
+ XCTFail(@"Could not obtain auth object.");
+ }
+
+ __block NSError *apiError;
+ XCTestExpectation *expectation =
+ [self expectationWithDescription:@"Created account with email and password."];
+ [auth createUserWithEmail:kTestingEmailToCreateUser
+ password:@"password"
+ completion:^(FIRUser *user, NSError *error) {
+ apiError = error;
+ [expectation fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:kExpectationsTimeout handler:nil];
+ expectation = [self expectationWithDescription:@"Created account with email and password."];
+ XCTAssertEqualObjects(auth.currentUser.email, kTestingEmailToCreateUser);
+ XCTAssertNil(apiError);
+ [auth.currentUser updateEmail:kNewTestingEmail
+ completion:^(NSError *_Nullable error) {
+ apiError = error;
+ [expectation fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:kExpectationsTimeout handler:nil];
+ XCTAssertNil(apiError);
+ XCTAssertEqualObjects(auth.currentUser.email, kNewTestingEmail);
+ // Clean up the created Firebase user for future runs.
+ [self deleteCurrentFirebaseUser];
+}
+
- (void)testLinkAnonymousAccountToFacebookAccount {
FIRAuth *auth = [FIRAuth auth];
if (!auth) {
@@ -253,6 +295,92 @@ static NSTimeInterval const kExpectationsTimeout = 30;
XCTAssertEqualObjects(auth.currentUser.uid, kCustomAuthTestingAccountUserID);
}
+- (void)testSignInWithValidCustomAuthExpiredToken {
+ FIRAuth *auth = [FIRAuth auth];
+ if (!auth) {
+ XCTFail(@"Could not obtain auth object.");
+ }
+
+ NSError *error;
+ NSString *customToken =
+ [NSString stringWithContentsOfURL:[NSURL URLWithString:kExpiredCustomTokenUrl]
+ encoding:NSUTF8StringEncoding
+ error:&error];
+ if (!customToken) {
+ XCTFail(@"There was an error retrieving the custom token: %@", error);
+ }
+ XCTestExpectation *expectation =
+ [self expectationWithDescription:@"CustomAuthToken sign-in finished."];
+
+ __block NSError *apiError;
+ [auth signInWithCustomToken:customToken
+ completion:^(FIRUser *_Nullable user, NSError *_Nullable error) {
+ if (error) {
+ apiError = error;
+ }
+ [expectation fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:kExpectationsTimeout
+ handler:^(NSError *error) {
+ if (error != nil) {
+ XCTFail(@"Failed to wait for expectations "
+ @"in CustomAuthToken sign in. Error: %@",
+ error.localizedDescription);
+ }
+ }];
+
+ XCTAssertNil(auth.currentUser);
+ XCTAssertEqual(apiError.code, FIRAuthErrorCodeInvalidCustomToken);
+}
+
+- (void)testInMemoryUserAfterSignOut {
+ FIRAuth *auth = [FIRAuth auth];
+ if (!auth) {
+ XCTFail(@"Could not obtain auth object.");
+ }
+ NSError *error;
+ NSString *customToken = [NSString stringWithContentsOfURL:[NSURL URLWithString:kCustomTokenUrl]
+ encoding:NSUTF8StringEncoding
+ error:&error];
+ if (!customToken) {
+ XCTFail(@"There was an error retrieving the custom token: %@", error);
+ }
+ XCTestExpectation *expectation =
+ [self expectationWithDescription:@"CustomAuthToken sign-in finished."];
+ __block NSError *rpcError;
+ [auth signInWithCustomToken:customToken
+ completion:^(FIRUser *_Nullable user, NSError *_Nullable error) {
+ if (error) {
+ rpcError = error;
+ }
+ [expectation fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:kExpectationsTimeout
+ handler:^(NSError *error) {
+ if (error != nil) {
+ XCTFail(@"Failed to wait for expectations "
+ @"in CustomAuthToken sign in. Error: %@",
+ error.localizedDescription);
+ }
+ }];
+ XCTAssertEqualObjects(auth.currentUser.uid, kCustomAuthTestingAccountUserID);
+ XCTAssertNil(rpcError);
+ FIRUser *inMemoryUser = auth.currentUser;
+ XCTestExpectation *expectation1 = [self expectationWithDescription:@"Profile data change."];
+ [auth signOut:NULL];
+ rpcError = nil;
+ NSString *newEmailAddress = [self fakeRandomEmail];
+ XCTAssertNotEqualObjects(newEmailAddress, inMemoryUser.email);
+ [inMemoryUser updateEmail:newEmailAddress completion:^(NSError *_Nullable error) {
+ rpcError = error;
+ [expectation1 fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:kExpectationsTimeout handler:nil];
+ XCTAssertEqualObjects(inMemoryUser.email, newEmailAddress);
+ XCTAssertNil(rpcError);
+ XCTAssertNil(auth.currentUser);
+}
+
- (void)testSignInWithInvalidCustomAuthToken {
FIRAuth *auth = [FIRAuth auth];
if (!auth) {
@@ -354,6 +482,17 @@ static NSTimeInterval const kExpectationsTimeout = 30;
#pragma mark - Helpers
+/** Generate fake random email address */
+- (NSString *)fakeRandomEmail {
+ NSMutableString *fakeEmail = [[NSMutableString alloc] init];
+ for (int i=0; i<10; i++) {
+ [fakeEmail appendString:
+ [NSString stringWithFormat:@"%c", 'a' + arc4random_uniform('z' - 'a' + 1)]];
+ }
+ [fakeEmail appendString:@"@gmail.com"];
+ return fakeEmail;
+}
+
/** Sign out current account. */
- (void)signOut {
NSError *signOutError;
diff --git a/Example/Auth/App/GoogleService-Info.plist b/Example/Auth/App/GoogleService-Info.plist
index 89afffe..3f7547f 100644
--- a/Example/Auth/App/GoogleService-Info.plist
+++ b/Example/Auth/App/GoogleService-Info.plist
@@ -10,8 +10,6 @@
<string>correct_client_id</string>
<key>REVERSED_CLIENT_ID</key>
<string>correct_reversed_client_id</string>
- <key>ANDROID_CLIENT_ID</key>
- <string>correct_android_client_id</string>
<key>GOOGLE_APP_ID</key>
<string>1:123:ios:123abc</string>
<key>GCM_SENDER_ID</key>
diff --git a/Example/Auth/App/tvOS/AppDelegate.h b/Example/Auth/App/tvOS/AppDelegate.h
new file mode 100644
index 0000000..013891c
--- /dev/null
+++ b/Example/Auth/App/tvOS/AppDelegate.h
@@ -0,0 +1,21 @@
+// Copyright 2017 Google
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#import <UIKit/UIKit.h>
+
+@interface AppDelegate : UIResponder <UIApplicationDelegate>
+
+@property(strong, nonatomic) UIWindow *window;
+
+@end
diff --git a/Example/Auth/App/tvOS/AppDelegate.m b/Example/Auth/App/tvOS/AppDelegate.m
new file mode 100644
index 0000000..3935032
--- /dev/null
+++ b/Example/Auth/App/tvOS/AppDelegate.m
@@ -0,0 +1,63 @@
+// Copyright 2017 Google
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+@import FirebaseCore;
+@import FirebaseAuth;
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+- (BOOL)application:(UIApplication *)application
+ didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
+ // Override point for customization after application launch.
+ [FIRApp configure];
+ return YES;
+}
+
+- (void)applicationWillResignActive:(UIApplication *)application {
+ // Sent when the application is about to move from active to inactive state. This can occur for
+ // certain types of temporary interruptions (such as an incoming phone call or SMS message) or
+ // when the user quits the application and it begins the transition to the background state. Use
+ // this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates.
+ // Games should use this method to pause the game.
+}
+
+- (void)applicationDidEnterBackground:(UIApplication *)application {
+ // Use this method to release shared resources, save user data, invalidate timers, and store
+ // enough application state information to restore your application to its current state in case
+ // it is terminated later. If your application supports background execution, this method is
+ // called instead of applicationWillTerminate: when the user quits.
+}
+
+- (void)applicationWillEnterForeground:(UIApplication *)application {
+ // Called as part of the transition from the background to the active state; here you can undo
+ // many of the changes made on entering the background.
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive. If
+ // the application was previously in the background, optionally refresh the user interface.
+}
+
+- (void)applicationWillTerminate:(UIApplication *)application {
+ // Called when the application is about to terminate. Save data if appropriate. See also
+ // applicationDidEnterBackground:.
+}
+
+@end
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..7f06667
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json
new file mode 100644
index 0000000..d29f024
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json
@@ -0,0 +1,17 @@
+{
+ "layers" : [
+ {
+ "filename" : "Front.imagestacklayer"
+ },
+ {
+ "filename" : "Middle.imagestacklayer"
+ },
+ {
+ "filename" : "Back.imagestacklayer"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..7f06667
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..7f06667
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..16a370d
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json
new file mode 100644
index 0000000..d29f024
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json
@@ -0,0 +1,17 @@
+{
+ "layers" : [
+ {
+ "filename" : "Front.imagestacklayer"
+ },
+ {
+ "filename" : "Middle.imagestacklayer"
+ },
+ {
+ "filename" : "Back.imagestacklayer"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..16a370d
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
new file mode 100644
index 0000000..16a370d
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json
new file mode 100644
index 0000000..b03ded1
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json
@@ -0,0 +1,32 @@
+{
+ "assets" : [
+ {
+ "size" : "1280x768",
+ "idiom" : "tv",
+ "filename" : "App Icon - App Store.imagestack",
+ "role" : "primary-app-icon"
+ },
+ {
+ "size" : "400x240",
+ "idiom" : "tv",
+ "filename" : "App Icon.imagestack",
+ "role" : "primary-app-icon"
+ },
+ {
+ "size" : "2320x720",
+ "idiom" : "tv",
+ "filename" : "Top Shelf Image Wide.imageset",
+ "role" : "top-shelf-image-wide"
+ },
+ {
+ "size" : "1920x720",
+ "idiom" : "tv",
+ "filename" : "Top Shelf Image.imageset",
+ "role" : "top-shelf-image"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json
new file mode 100644
index 0000000..16a370d
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json
new file mode 100644
index 0000000..16a370d
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "tv",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "tv",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Assets.xcassets/LaunchImage.launchimage/Contents.json b/Example/Auth/App/tvOS/Assets.xcassets/LaunchImage.launchimage/Contents.json
new file mode 100644
index 0000000..d746a60
--- /dev/null
+++ b/Example/Auth/App/tvOS/Assets.xcassets/LaunchImage.launchimage/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "orientation" : "landscape",
+ "idiom" : "tv",
+ "extent" : "full-screen",
+ "minimum-system-version" : "11.0",
+ "scale" : "2x"
+ },
+ {
+ "orientation" : "landscape",
+ "idiom" : "tv",
+ "extent" : "full-screen",
+ "minimum-system-version" : "9.0",
+ "scale" : "1x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/Example/Auth/App/tvOS/Info.plist b/Example/Auth/App/tvOS/Info.plist
new file mode 100644
index 0000000..02942a3
--- /dev/null
+++ b/Example/Auth/App/tvOS/Info.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>UIMainStoryboardFile</key>
+ <string>Main</string>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>arm64</string>
+ </array>
+ <key>UIUserInterfaceStyle</key>
+ <string>Automatic</string>
+</dict>
+</plist>
diff --git a/Example/Auth/App/tvOS/Main.storyboard b/Example/Auth/App/tvOS/Main.storyboard
new file mode 100644
index 0000000..72d5e22
--- /dev/null
+++ b/Example/Auth/App/tvOS/Main.storyboard
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="13122.16" systemVersion="17A278a" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
+ <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="tne-QT-ifu">
+ <objects>
+ <viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
+ <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+ <rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
+ <viewLayoutGuide key="safeArea" id="wu6-TO-1qx"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
+ </objects>
+ </scene>
+ </scenes>
+</document>
diff --git a/Example/Auth/App/tvOS/ViewController.h b/Example/Auth/App/tvOS/ViewController.h
new file mode 100644
index 0000000..b6115b8
--- /dev/null
+++ b/Example/Auth/App/tvOS/ViewController.h
@@ -0,0 +1,19 @@
+// Copyright 2017 Google
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#import <UIKit/UIKit.h>
+
+@interface ViewController : UIViewController
+
+@end
diff --git a/Example/Auth/App/tvOS/ViewController.m b/Example/Auth/App/tvOS/ViewController.m
new file mode 100644
index 0000000..6d4676b
--- /dev/null
+++ b/Example/Auth/App/tvOS/ViewController.m
@@ -0,0 +1,33 @@
+// Copyright 2017 Google
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#import "ViewController.h"
+
+@interface ViewController ()
+
+@end
+
+@implementation ViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+ // Do any additional setup after loading the view, typically from a nib.
+}
+
+- (void)didReceiveMemoryWarning {
+ [super didReceiveMemoryWarning];
+ // Dispose of any resources that can be recreated.
+}
+
+@end
diff --git a/Example/Auth/App/tvOS/main.m b/Example/Auth/App/tvOS/main.m
new file mode 100644
index 0000000..d9e6654
--- /dev/null
+++ b/Example/Auth/App/tvOS/main.m
@@ -0,0 +1,22 @@
+// Copyright 2017 Google
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#import <UIKit/UIKit.h>
+#import "AppDelegate.h"
+
+int main(int argc, char* argv[]) {
+ @autoreleasepool {
+ return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
+ }
+}
diff --git a/Example/Auth/Sample/MainViewController.m b/Example/Auth/Sample/MainViewController.m
index 5326463..31c103a 100644
--- a/Example/Auth/Sample/MainViewController.m
+++ b/Example/Auth/Sample/MainViewController.m
@@ -38,12 +38,18 @@
#import "UserInfoViewController.h"
#import "UserTableViewCell.h"
+NS_ASSUME_NONNULL_BEGIN
-/*! @typedef textInputCompletionBlock
+/** @typedef textInputCompletionBlock
@brief The type of callback used to report text input prompt results.
*/
typedef void (^textInputCompletionBlock)(NSString *_Nullable userInput);
+/** @typedef testAutomationCallback
+ @brief The type of callback used when automatically testing an API.
+ */
+typedef void (^testAutomationCallback)(NSError *_Nullable error);
+
/** @var kTokenGetButtonText
@brief The text of the "Get Token" button.
*/
@@ -2187,18 +2193,20 @@ static NSDictionary<NSString *, NSString *> *parseURL(NSString *urlString) {
@completion A completion block to be executed after the provider is unlinked.
*/
- (void)unlinkFromProvider:(NSString *)provider
- completion:(void(^)(NSError *_Nullable))completion {
+ completion:(nullable testAutomationCallback)completion {
[[self user] unlinkFromProvider:provider
completion:^(FIRUser *_Nullable user,
NSError *_Nullable error) {
if (error) {
[self logFailure:@"unlink auth provider failed" error:error];
- completion(error);
- } else {
- [self logSuccess:@"unlink auth provider succeeded."];
if (completion) {
- completion(nil);
+ completion(error);
}
+ return;
+ }
+ [self logSuccess:@"unlink auth provider succeeded."];
+ if (completion) {
+ completion(nil);
}
[self showTypicalUIForUserUpdateResultsWithTitle:kUnlinkTitle error:error];
}];
@@ -2642,7 +2650,7 @@ static NSDictionary<NSString *, NSString *> *parseURL(NSString *urlString) {
@completion A completion block to be executed after successful phone number sign in.
*/
- (void)signInWithPhoneNumber:(NSString *_Nullable)phoneNumber
- completion:(void(^)(NSError *_Nullable))completion {
+ completion:(nullable testAutomationCallback)completion {
[self showSpinner:^{
[[AppManager phoneAuthProvider] verifyPhoneNumber:phoneNumber
UIDelegate:nil
@@ -2707,15 +2715,23 @@ static NSDictionary<NSString *, NSString *> *parseURL(NSString *urlString) {
FIRAuthCredential *credential =
[[AppManager phoneAuthProvider] credentialWithVerificationID:verificationID
verificationCode:verificationCode];
- [[AppManager auth] signInWithCredential:credential
- completion:^(FIRUser *_Nullable user,
- NSError *_Nullable error) {
+ [[AppManager auth] signInAndRetrieveDataWithCredential:credential
+ completion:^(FIRAuthDataResult *_Nullable result,
+ NSError *_Nullable error) {
[self hideSpinner:^{
if (error) {
[self logFailure:@"failed to verify phone number" error:error];
[self showMessagePrompt:error.localizedDescription];
return;
}
+ if (_isNewUserToggleOn) {
+ NSString *newUserString = result.additionalUserInfo.isNewUser ?
+ @"New user" : @"Existing user";
+ [self showMessagePromptWithTitle:@"New or Existing"
+ message:newUserString
+ showCancelButton:NO
+ completion:nil];
+ }
}];
}];
}];
@@ -2727,7 +2743,7 @@ static NSDictionary<NSString *, NSString *> *parseURL(NSString *urlString) {
@completion A completion block to be executed after phone number is updated.
*/
- (void)updatePhoneNumber:(NSString *_Nullable)phoneNumber
- completion:(void(^)(NSError *_Nullable))completion{
+ completion:(nullable testAutomationCallback)completion {
[self showSpinner:^{
[[AppManager phoneAuthProvider] verifyPhoneNumber:phoneNumber
UIDelegate:nil
@@ -2736,7 +2752,9 @@ static NSDictionary<NSString *, NSString *> *parseURL(NSString *urlString) {
if (error) {
[self logFailure:@"failed to send verification code" error:error];
[self showMessagePrompt:error.localizedDescription];
- completion(error);
+ if (completion) {
+ completion(error);
+ }
return;
}
[self logSuccess:@"Code sent"];
@@ -2757,7 +2775,9 @@ static NSDictionary<NSString *, NSString *> *parseURL(NSString *urlString) {
if (error) {
[self logFailure:@"update phone number failed" error:error];
[self showMessagePrompt:error.localizedDescription];
- completion(error);
+ if (completion) {
+ completion(error);
+ }
} else {
[self logSuccess:@"update phone number succeeded."];
if (completion) {
@@ -2794,7 +2814,7 @@ static NSDictionary<NSString *, NSString *> *parseURL(NSString *urlString) {
@completion A completion block to be executed after linking phone number.
*/
- (void)linkPhoneNumber:(NSString *_Nullable)phoneNumber
- completion:(void(^)(NSError *_Nullable))completion{
+ completion:(nullable testAutomationCallback)completion {
[self showSpinner:^{
[[AppManager phoneAuthProvider] verifyPhoneNumber:phoneNumber
UIDelegate:nil
@@ -2804,7 +2824,9 @@ static NSDictionary<NSString *, NSString *> *parseURL(NSString *urlString) {
if (error) {
[self logFailure:@"failed to send verification code" error:error];
[self showMessagePrompt:error.localizedDescription];
- completion(error);
+ if (completion) {
+ completion(error);
+ }
return;
}
[self logSuccess:@"Code sent"];
@@ -2845,7 +2867,9 @@ static NSDictionary<NSString *, NSString *> *parseURL(NSString *urlString) {
if (error) {
[self logFailure:@"failed to verify phone number" error:error];
[self showMessagePrompt:error.localizedDescription];
- completion(error);
+ if (completion) {
+ completion(error);
+ }
return;
}
}];
@@ -3147,3 +3171,5 @@ static NSDictionary<NSString *, NSString *> *parseURL(NSString *urlString) {
}
@end
+
+NS_ASSUME_NONNULL_END
diff --git a/Example/Auth/Tests/FIRAuthTests.m b/Example/Auth/Tests/FIRAuthTests.m
index 6391b08..b22c600 100644
--- a/Example/Auth/Tests/FIRAuthTests.m
+++ b/Example/Auth/Tests/FIRAuthTests.m
@@ -430,6 +430,8 @@ static const NSTimeInterval kWaitInterval = .5;
dispatch_async(FIRAuthGlobalWorkQueue(), ^() {
id mockVerifyPhoneResponse = OCMClassMock([FIRVerifyPhoneNumberResponse class]);
[self stubTokensWithMockResponse:mockVerifyPhoneResponse];
+ // Stub isNewUser flag in the response.
+ OCMStub([mockVerifyPhoneResponse isNewUser]).andReturn(YES);
callback(mockVerifyPhoneResponse, nil);
});
});
@@ -440,10 +442,12 @@ static const NSTimeInterval kWaitInterval = .5;
[[FIRPhoneAuthProvider provider] credentialWithVerificationID:kVerificationID
verificationCode:kVerificationCode];
- [[FIRAuth auth] signInWithCredential:credential completion:^(FIRUser *_Nullable user,
- NSError *_Nullable error) {
+ [[FIRAuth auth] signInAndRetrieveDataWithCredential:credential
+ completion:^(FIRAuthDataResult *_Nullable authDataResult,
+ NSError *_Nullable error) {
XCTAssertTrue([NSThread isMainThread]);
- [self assertUser:user];
+ [self assertUser:authDataResult.user];
+ XCTAssertTrue(authDataResult.additionalUserInfo.isNewUser);
XCTAssertNil(error);
[expectation fulfill];
}];
diff --git a/Example/Auth/Tests/FIRVerifyPasswordRequestTest.m b/Example/Auth/Tests/FIRVerifyPasswordRequestTest.m
index 54ba7b0..2359c46 100644
--- a/Example/Auth/Tests/FIRVerifyPasswordRequestTest.m
+++ b/Example/Auth/Tests/FIRVerifyPasswordRequestTest.m
@@ -18,9 +18,9 @@
#import "FIRAuthErrors.h"
#import "FIRAuthBackend.h"
+#import "FIRFakeBackendRPCIssuer.h"
#import "FIRVerifyPasswordRequest.h"
#import "FIRVerifyPasswordResponse.h"
-#import "FIRFakeBackendRPCIssuer.h"
/** @var kTestAPIKey
@brief Fake API key used for testing.
@@ -125,9 +125,10 @@ static NSString *const kExpectedAPIURL =
@brief Tests the verify password request.
*/
- (void)testVerifyPasswordRequest {
- FIRVerifyPasswordRequest * request = [[FIRVerifyPasswordRequest alloc] initWithEmail:kTestEmail
- password:kTestPassword
- requestConfiguration:_requestConfiguration];
+ FIRVerifyPasswordRequest * request =
+ [[FIRVerifyPasswordRequest alloc] initWithEmail:kTestEmail
+ password:kTestPassword
+ requestConfiguration:_requestConfiguration];
request.returnSecureToken = NO;
[FIRAuthBackend verifyPassword:request
callback:^(FIRVerifyPasswordResponse *_Nullable response,
@@ -147,9 +148,10 @@ static NSString *const kExpectedAPIURL =
@brief Tests the verify password request with optional fields.
*/
- (void)testVerifyPasswordRequestOptionalFields {
- FIRVerifyPasswordRequest * request = [[FIRVerifyPasswordRequest alloc] initWithEmail:kTestEmail
- password:kTestPassword
- requestConfiguration:_requestConfiguration];
+ FIRVerifyPasswordRequest * request =
+ [[FIRVerifyPasswordRequest alloc] initWithEmail:kTestEmail
+ password:kTestPassword
+ requestConfiguration:_requestConfiguration];
request.pendingIDToken = kTestPendingToken;
request.captchaChallenge = kTestCaptchaChallenge;
request.captchaResponse = kTestCaptchaResponse;