[google_sign_in_ios] Upgrade GoogleSignIn iOS SDK to 7.0 (#5240)
Fixes https://github.com/flutter/flutter/issues/137140.
See https://developers.google.com/identity/sign-in/ios/quick-migration-guide and https://developers.google.com/identity/sign-in/ios/release for info about changes made to the SDK.
diff --git a/packages/google_sign_in/google_sign_in/CHANGELOG.md b/packages/google_sign_in/google_sign_in/CHANGELOG.md
index 9668392..7e5b866 100644
--- a/packages/google_sign_in/google_sign_in/CHANGELOG.md
+++ b/packages/google_sign_in/google_sign_in/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 6.1.6
+
+* Updates README to direct to google_sign_in_ios README for iOS integration instructions.
+
## 6.1.5
* Adds pub topics to package metadata.
diff --git a/packages/google_sign_in/google_sign_in/README.md b/packages/google_sign_in/google_sign_in/README.md
index 154e683..87f2857 100644
--- a/packages/google_sign_in/google_sign_in/README.md
+++ b/packages/google_sign_in/google_sign_in/README.md
@@ -27,59 +27,7 @@
### iOS integration
-1. [First register your application](https://firebase.google.com/docs/ios/setup).
-2. Make sure the file you download in step 1 is named
- `GoogleService-Info.plist`.
-3. Move or copy `GoogleService-Info.plist` into the `[my_project]/ios/Runner`
- directory.
-4. Open Xcode, then right-click on `Runner` directory and select
- `Add Files to "Runner"`.
-5. Select `GoogleService-Info.plist` from the file manager.
-6. A dialog will show up and ask you to select the targets, select the `Runner`
- target.
-7. If you need to authenticate to a backend server you can add a
- `SERVER_CLIENT_ID` key value pair in your `GoogleService-Info.plist`.
- ```xml
- <key>SERVER_CLIENT_ID</key>
- <string>[YOUR SERVER CLIENT ID]</string>
- ```
-8. Then add the `CFBundleURLTypes` attributes below into the
- `[my_project]/ios/Runner/Info.plist` file.
-
-```xml
-<!-- Put me in the [my_project]/ios/Runner/Info.plist file -->
-<!-- Google Sign-in Section -->
-<key>CFBundleURLTypes</key>
-<array>
- <dict>
- <key>CFBundleTypeRole</key>
- <string>Editor</string>
- <key>CFBundleURLSchemes</key>
- <array>
- <!-- TODO Replace this value: -->
- <!-- Copied from GoogleService-Info.plist key REVERSED_CLIENT_ID -->
- <string>com.googleusercontent.apps.861823949799-vc35cprkp249096uujjn0vvnmcvjppkn</string>
- </array>
- </dict>
-</array>
-<!-- End of the Google Sign-in Section -->
-```
-
-As an alternative to adding `GoogleService-Info.plist` to your Xcode project,
-you can instead configure your app in Dart code. In this case, skip steps 3 to 7
- and pass `clientId` and `serverClientId` to the `GoogleSignIn` constructor:
-
-```dart
-GoogleSignIn _googleSignIn = GoogleSignIn(
- ...
- // The OAuth client id of your app. This is required.
- clientId: ...,
- // If you need to authenticate to a backend server, specify its OAuth client. This is optional.
- serverClientId: ...,
-);
-```
-
-Note that step 8 is still required.
+Please see [instructions on integrating Google Sign-In for iOS](https://pub.dev/packages/google_sign_in_ios#ios-integration).
#### iOS additional requirement
@@ -212,12 +160,12 @@
### Does an app always need to check `canAccessScopes`?
-The new web SDK implicitly grant access to the `email`, `profile` and `openid`
+The new web SDK implicitly grant access to the `email`, `profile` and `openid`
scopes when users complete the sign-in process (either via the One Tap UX or the
Google Sign In button).
If an app only needs an `idToken`, or only requests permissions to any/all of
-the three scopes mentioned above
+the three scopes mentioned above
([OpenID Connect scopes](https://developers.google.com/identity/protocols/oauth2/scopes#openid-connect)),
it won't need to implement any additional scope handling.
diff --git a/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/project.pbxproj b/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/project.pbxproj
index 45b4e80..5af6f7c 100644
--- a/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/project.pbxproj
@@ -8,7 +8,6 @@
/* Begin PBXBuildFile section */
5C6F5A6E1EC3B4CB008D64B5 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C6F5A6D1EC3B4CB008D64B5 /* GeneratedPluginRegistrant.m */; };
- 7A303C2E1E89D76400B1F19E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7A303C2D1E89D76400B1F19E /* GoogleService-Info.plist */; };
7ACDFB0E1E8944C400BE2D00 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7ACDFB0D1E8944C400BE2D00 /* AppFrameworkInfo.plist */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
@@ -39,7 +38,6 @@
5A76713E622F06379AEDEBFA /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
5C6F5A6C1EC3B4CB008D64B5 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
5C6F5A6D1EC3B4CB008D64B5 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
- 7A303C2D1E89D76400B1F19E /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
7ACDFB0D1E8944C400BE2D00 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
@@ -118,7 +116,6 @@
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
- 7A303C2D1E89D76400B1F19E /* GoogleService-Info.plist */,
97C147021CF9000F007C117D /* Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
);
@@ -173,7 +170,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 1300;
+ LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "The Flutter Authors";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
@@ -204,7 +201,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 7A303C2E1E89D76400B1F19E /* GoogleService-Info.plist in Resources */,
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
7ACDFB0E1E8944C400BE2D00 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
diff --git a/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
index f4569c4..8e83ef7 100644
--- a/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/packages/google_sign_in/google_sign_in/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
- LastUpgradeVersion = "1300"
+ LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
diff --git a/packages/google_sign_in/google_sign_in/example/ios/Runner/GoogleService-Info.plist b/packages/google_sign_in/google_sign_in/example/ios/Runner/GoogleService-Info.plist
deleted file mode 100644
index 6042aab..0000000
--- a/packages/google_sign_in/google_sign_in/example/ios/Runner/GoogleService-Info.plist
+++ /dev/null
@@ -1,44 +0,0 @@
-<?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>AD_UNIT_ID_FOR_BANNER_TEST</key>
- <string>ca-app-pub-3940256099942544/2934735716</string>
- <key>AD_UNIT_ID_FOR_INTERSTITIAL_TEST</key>
- <string>ca-app-pub-3940256099942544/4411468910</string>
- <key>CLIENT_ID</key>
- <string>479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u.apps.googleusercontent.com</string>
- <key>REVERSED_CLIENT_ID</key>
- <string>com.googleusercontent.apps.479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u</string>
- <key>ANDROID_CLIENT_ID</key>
- <string>479882132969-jie8r1me6dsra60pal6ejaj8dgme3tg0.apps.googleusercontent.com</string>
- <key>API_KEY</key>
- <string>AIzaSyBECOwLTAN6PU4Aet1b2QLGIb3kRK8Xjew</string>
- <key>GCM_SENDER_ID</key>
- <string>479882132969</string>
- <key>PLIST_VERSION</key>
- <string>1</string>
- <key>BUNDLE_ID</key>
- <string>io.flutter.plugins.googleSignInExample</string>
- <key>PROJECT_ID</key>
- <string>my-flutter-proj</string>
- <key>STORAGE_BUCKET</key>
- <string>my-flutter-proj.appspot.com</string>
- <key>IS_ADS_ENABLED</key>
- <true></true>
- <key>IS_ANALYTICS_ENABLED</key>
- <false></false>
- <key>IS_APPINVITE_ENABLED</key>
- <true></true>
- <key>IS_GCM_ENABLED</key>
- <true></true>
- <key>IS_SIGNIN_ENABLED</key>
- <true></true>
- <key>GOOGLE_APP_ID</key>
- <string>1:479882132969:ios:2643f950e0a0da08</string>
- <key>DATABASE_URL</key>
- <string>https://my-flutter-proj.firebaseio.com</string>
- <key>SERVER_CLIENT_ID</key>
- <string>YOUR_SERVER_CLIENT_ID</string>
-</dict>
-</plist>
\ No newline at end of file
diff --git a/packages/google_sign_in/google_sign_in/example/ios/Runner/Info.plist b/packages/google_sign_in/google_sign_in/example/ios/Runner/Info.plist
index 08fef9a..5c3953a 100644
--- a/packages/google_sign_in/google_sign_in/example/ios/Runner/Info.plist
+++ b/packages/google_sign_in/google_sign_in/example/ios/Runner/Info.plist
@@ -60,5 +60,9 @@
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
+ <key>GIDClientID</key>
+ <string>479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u.apps.googleusercontent.com</string>
+ <key>GIDServerClientID</key>
+ <string>YOUR_SERVER_CLIENT_ID</string>
</dict>
</plist>
diff --git a/packages/google_sign_in/google_sign_in/pubspec.yaml b/packages/google_sign_in/google_sign_in/pubspec.yaml
index 2f3767f..05d8bfb 100644
--- a/packages/google_sign_in/google_sign_in/pubspec.yaml
+++ b/packages/google_sign_in/google_sign_in/pubspec.yaml
@@ -3,7 +3,7 @@
for signing in with a Google account on Android and iOS.
repository: https://github.com/flutter/packages/tree/main/packages/google_sign_in/google_sign_in
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22
-version: 6.1.5
+version: 6.1.6
environment:
sdk: ">=2.19.0 <4.0.0"
@@ -43,5 +43,6 @@
# The example deliberately includes limited-use secrets.
false_secrets:
- /example/android/app/google-services.json
- - /example/ios/Runner/GoogleService-Info.plist
+ - /example/ios/Runner/Info.plist
+ - /example/ios/RunnerTests/GoogleService-Info.plist
- /example/ios/RunnerTests/GoogleSignInTests.m
diff --git a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart
index 86b83cf..94fabc5 100644
--- a/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart
+++ b/packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart
@@ -81,6 +81,28 @@
verify(mockPlatform.signIn());
});
+ test(
+ 'clientId and serverClientId parameters is forwarded to implementation',
+ () async {
+ // #docregion GoogleSignIn
+ final GoogleSignIn googleSignIn = GoogleSignIn(
+ // The OAuth client id of your app. This is required.
+ clientId: 'Your Client ID',
+ // If you need to authenticate to a backend server, specify its OAuth client. This is optional.
+ serverClientId: 'Your Server ID',
+ );
+ // #enddocregion GoogleSignIn
+
+ await googleSignIn.signIn();
+
+ _verifyInit(
+ mockPlatform,
+ clientId: 'Your Client ID',
+ serverClientId: 'Your Server ID',
+ );
+ verify(mockPlatform.signIn());
+ });
+
test('forceCodeForRefreshToken sent with init method call', () async {
final GoogleSignIn googleSignIn =
GoogleSignIn(forceCodeForRefreshToken: true);
diff --git a/packages/google_sign_in/google_sign_in_ios/CHANGELOG.md b/packages/google_sign_in/google_sign_in_ios/CHANGELOG.md
index 4f67a64..2864132 100644
--- a/packages/google_sign_in/google_sign_in_ios/CHANGELOG.md
+++ b/packages/google_sign_in/google_sign_in_ios/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 5.6.5
+
+* Upgrades GoogleSignIn iOS SDK to 7.0.
+
## 5.6.4
* Converts platform communication to Pigeon.
diff --git a/packages/google_sign_in/google_sign_in_ios/README.md b/packages/google_sign_in/google_sign_in_ios/README.md
index 6a5d862..29bcc25 100644
--- a/packages/google_sign_in/google_sign_in_ios/README.md
+++ b/packages/google_sign_in/google_sign_in_ios/README.md
@@ -13,3 +13,62 @@
[1]: https://pub.dev/packages/google_sign_in
[2]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin
+
+### iOS integration
+
+1. [Create a Firebase project](https://firebase.google.com/docs/ios/setup#create-firebase-project)
+ and [register your application](https://firebase.google.com/docs/ios/setup#register-app).
+2. [Enable Google Sign-In for your Firebase project](https://firebase.google.com/docs/auth/ios/google-signin#enable_google_sign-in_for_your_firebase_project).
+3. Make sure to download a new copy of your project's
+ `GoogleService-Info.plist` from step 2. Do not put this file in your project.
+4. Add the client ID from the `GoogleService-Info.plist` into your app's
+ `[my_project]/ios/Runner/Info.plist` file.
+ ```xml
+ <key>GIDClientID</key>
+ <!-- TODO Replace this value: -->
+ <!-- Copied from GoogleService-Info.plist key CLIENT_ID -->
+ <string>[YOUR IOS CLIENT ID]</string>
+ ```
+5. If you need to authenticate to a backend server you can add a
+ `GIDServerClientID` key value pair in your `[my_project]/ios/Runner/Info.plist` file.
+ ```xml
+ <key>GIDServerClientID</key>
+ <string>[YOUR SERVER CLIENT ID]</string>
+ ```
+6. Then add the `CFBundleURLTypes` attributes below into the
+ `[my_project]/ios/Runner/Info.plist` file.
+
+```xml
+<!-- Put me in the [my_project]/ios/Runner/Info.plist file -->
+<!-- Google Sign-in Section -->
+<key>CFBundleURLTypes</key>
+<array>
+ <dict>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>CFBundleURLSchemes</key>
+ <array>
+ <!-- TODO Replace this value: -->
+ <!-- Copied from GoogleService-Info.plist key REVERSED_CLIENT_ID -->
+ <string>com.googleusercontent.apps.861823949799-vc35cprkp249096uujjn0vvnmcvjppkn</string>
+ </array>
+ </dict>
+</array>
+<!-- End of the Google Sign-in Section -->
+```
+
+As an alternative to editing the `Info.plist` in your Xcode project,
+you can instead configure your app in Dart code. In this case, skip steps 4 to 5
+ and pass `clientId` and `serverClientId` to the `GoogleSignIn` constructor:
+
+<?code-excerpt "../google_sign_in/test/google_sign_in_test.dart (GoogleSignIn)"?>
+```dart
+final GoogleSignIn googleSignIn = GoogleSignIn(
+ // The OAuth client id of your app. This is required.
+ clientId: 'Your Client ID',
+ // If you need to authenticate to a backend server, specify its OAuth client. This is optional.
+ serverClientId: 'Your Server ID',
+);
+```
+
+Note that step 6 is still required.
diff --git a/packages/google_sign_in/google_sign_in_ios/example/ios/Runner.xcodeproj/project.pbxproj b/packages/google_sign_in/google_sign_in_ios/example/ios/Runner.xcodeproj/project.pbxproj
index abbb5ef..ca1508e 100644
--- a/packages/google_sign_in/google_sign_in_ios/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/packages/google_sign_in/google_sign_in_ios/example/ios/Runner.xcodeproj/project.pbxproj
@@ -8,7 +8,7 @@
/* Begin PBXBuildFile section */
5C6F5A6E1EC3B4CB008D64B5 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C6F5A6D1EC3B4CB008D64B5 /* GeneratedPluginRegistrant.m */; };
- 7A303C2E1E89D76400B1F19E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7A303C2D1E89D76400B1F19E /* GoogleService-Info.plist */; };
+ 78A36DA12AF5761E00CBFD43 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7A303C2D1E89D76400B1F19E /* GoogleService-Info.plist */; };
7ACDFB0E1E8944C400BE2D00 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 7ACDFB0D1E8944C400BE2D00 /* AppFrameworkInfo.plist */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
@@ -163,7 +163,6 @@
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
- 7A303C2D1E89D76400B1F19E /* GoogleService-Info.plist */,
97C147021CF9000F007C117D /* Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
);
@@ -191,6 +190,7 @@
isa = PBXGroup;
children = (
F76AC1A42666D0540040C8BC /* GoogleSignInTests.m */,
+ 7A303C2D1E89D76400B1F19E /* GoogleService-Info.plist */,
F76AC1A62666D0540040C8BC /* Info.plist */,
);
path = RunnerTests;
@@ -316,7 +316,6 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 7A303C2E1E89D76400B1F19E /* GoogleService-Info.plist in Resources */,
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
7ACDFB0E1E8944C400BE2D00 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
@@ -328,6 +327,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 78A36DA12AF5761E00CBFD43 /* GoogleService-Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/packages/google_sign_in/google_sign_in_ios/example/ios/Runner/Info.plist b/packages/google_sign_in/google_sign_in_ios/example/ios/Runner/Info.plist
index 08fef9a..5c3953a 100644
--- a/packages/google_sign_in/google_sign_in_ios/example/ios/Runner/Info.plist
+++ b/packages/google_sign_in/google_sign_in_ios/example/ios/Runner/Info.plist
@@ -60,5 +60,9 @@
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
+ <key>GIDClientID</key>
+ <string>479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u.apps.googleusercontent.com</string>
+ <key>GIDServerClientID</key>
+ <string>YOUR_SERVER_CLIENT_ID</string>
</dict>
</plist>
diff --git a/packages/google_sign_in/google_sign_in_ios/example/ios/Runner/GoogleService-Info.plist b/packages/google_sign_in/google_sign_in_ios/example/ios/RunnerTests/GoogleService-Info.plist
similarity index 100%
rename from packages/google_sign_in/google_sign_in_ios/example/ios/Runner/GoogleService-Info.plist
rename to packages/google_sign_in/google_sign_in_ios/example/ios/RunnerTests/GoogleService-Info.plist
diff --git a/packages/google_sign_in/google_sign_in_ios/example/ios/RunnerTests/GoogleSignInTests.m b/packages/google_sign_in/google_sign_in_ios/example/ios/RunnerTests/GoogleSignInTests.m
index 8e27c39..de50463 100644
--- a/packages/google_sign_in/google_sign_in_ios/example/ios/RunnerTests/GoogleSignInTests.m
+++ b/packages/google_sign_in/google_sign_in_ios/example/ios/RunnerTests/GoogleSignInTests.m
@@ -18,6 +18,7 @@
@property(strong, nonatomic) NSObject<FlutterPluginRegistrar> *mockPluginRegistrar;
@property(strong, nonatomic) FLTGoogleSignInPlugin *plugin;
@property(strong, nonatomic) id mockSignIn;
+@property(strong, nonatomic) NSDictionary<NSString *, id> *googleServiceInfo;
@end
@@ -34,6 +35,13 @@
OCMStub(self.mockPluginRegistrar.messenger).andReturn(self.mockBinaryMessenger);
self.plugin = [[FLTGoogleSignInPlugin alloc] initWithSignIn:mockSignIn];
[FLTGoogleSignInPlugin registerWithRegistrar:self.mockPluginRegistrar];
+
+ NSString *plistPath =
+ [[NSBundle bundleForClass:[self class]] pathForResource:@"GoogleService-Info"
+ ofType:@"plist"];
+ if (plistPath) {
+ self.googleServiceInfo = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
+ }
}
- (void)testSignOut {
@@ -44,7 +52,7 @@
}
- (void)testDisconnect {
- [[self.mockSignIn stub] disconnectWithCallback:[OCMArg invokeBlockWithArgs:[NSNull null], nil]];
+ [[self.mockSignIn stub] disconnectWithCompletion:[OCMArg invokeBlockWithArgs:[NSNull null], nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"];
[self.plugin disconnectWithCompletion:^(FlutterError *error) {
@@ -58,7 +66,7 @@
NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain
code:kGIDSignInErrorCodeHasNoAuthInKeychain
userInfo:nil];
- [[self.mockSignIn stub] disconnectWithCallback:[OCMArg invokeBlockWithArgs:error, nil]];
+ [[self.mockSignIn stub] disconnectWithCompletion:[OCMArg invokeBlockWithArgs:error, nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"expect result returns true"];
[self.plugin disconnectWithCompletion:^(FlutterError *error) {
@@ -70,7 +78,7 @@
#pragma mark - Init
-- (void)testInitNoClientIdError {
+- (void)testInitNoClientIdNoError {
// Init plugin without GoogleService-Info.plist.
self.plugin = [[FLTGoogleSignInPlugin alloc] initWithSignIn:self.mockSignIn
withGoogleServiceProperties:nil];
@@ -83,10 +91,12 @@
FlutterError *error;
[self.plugin initializeSignInWithParameters:params error:&error];
- XCTAssertEqualObjects(error.code, @"missing-config");
+ XCTAssertNil(error);
}
- (void)testInitGoogleServiceInfoPlist {
+ self.plugin = [[FLTGoogleSignInPlugin alloc] initWithSignIn:self.mockSignIn
+ withGoogleServiceProperties:self.googleServiceInfo];
FSIInitParams *params = [FSIInitParams makeWithScopes:@[]
hostedDomain:@"example.com"
clientId:nil
@@ -100,19 +110,17 @@
[self.plugin signInWithCompletion:^(FSIUserData *user, FlutterError *error){
}];
OCMVerify([self.mockSignIn
- signInWithConfiguration:[OCMArg checkWithBlock:^BOOL(GIDConfiguration *configuration) {
- // Set in example app GoogleService-Info.plist.
- return
- [configuration.hostedDomain isEqualToString:@"example.com"] &&
- [configuration.clientID
- isEqualToString:
- @"479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u.apps.googleusercontent.com"] &&
- [configuration.serverClientID isEqualToString:@"YOUR_SERVER_CLIENT_ID"];
- }]
- presentingViewController:[OCMArg isKindOfClass:[FlutterViewController class]]
- hint:nil
- additionalScopes:OCMOCK_ANY
- callback:OCMOCK_ANY]);
+ signInWithPresentingViewController:[OCMArg isKindOfClass:[FlutterViewController class]]
+ hint:nil
+ additionalScopes:OCMOCK_ANY
+ completion:OCMOCK_ANY]);
+
+ XCTAssertEqualObjects(self.plugin.configuration.hostedDomain, @"example.com");
+ // Set in example app GoogleService-Info.plist.
+ XCTAssertEqualObjects(
+ self.plugin.configuration.clientID,
+ @"479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u.apps.googleusercontent.com");
+ XCTAssertEqualObjects(self.plugin.configuration.serverClientID, @"YOUR_SERVER_CLIENT_ID");
}
- (void)testInitDynamicClientIdNullDomain {
@@ -133,17 +141,19 @@
[self.plugin signInWithCompletion:^(FSIUserData *user, FlutterError *error){
}];
OCMVerify([self.mockSignIn
- signInWithConfiguration:[OCMArg checkWithBlock:^BOOL(GIDConfiguration *configuration) {
- return configuration.hostedDomain == nil &&
- [configuration.clientID isEqualToString:@"mockClientId"];
- }]
- presentingViewController:[OCMArg isKindOfClass:[FlutterViewController class]]
- hint:nil
- additionalScopes:OCMOCK_ANY
- callback:OCMOCK_ANY]);
+ signInWithPresentingViewController:[OCMArg isKindOfClass:[FlutterViewController class]]
+ hint:nil
+ additionalScopes:OCMOCK_ANY
+ completion:OCMOCK_ANY]);
+
+ XCTAssertEqualObjects(self.plugin.configuration.hostedDomain, nil);
+ XCTAssertEqualObjects(self.plugin.configuration.clientID, @"mockClientId");
+ XCTAssertEqualObjects(self.plugin.configuration.serverClientID, nil);
}
- (void)testInitDynamicServerClientIdNullDomain {
+ self.plugin = [[FLTGoogleSignInPlugin alloc] initWithSignIn:self.mockSignIn
+ withGoogleServiceProperties:self.googleServiceInfo];
FSIInitParams *params = [FSIInitParams makeWithScopes:@[]
hostedDomain:nil
clientId:nil
@@ -156,14 +166,36 @@
[self.plugin signInWithCompletion:^(FSIUserData *user, FlutterError *error){
}];
OCMVerify([self.mockSignIn
- signInWithConfiguration:[OCMArg checkWithBlock:^BOOL(GIDConfiguration *configuration) {
- return configuration.hostedDomain == nil &&
- [configuration.serverClientID isEqualToString:@"mockServerClientId"];
- }]
- presentingViewController:[OCMArg isKindOfClass:[FlutterViewController class]]
- hint:nil
- additionalScopes:OCMOCK_ANY
- callback:OCMOCK_ANY]);
+ signInWithPresentingViewController:[OCMArg isKindOfClass:[FlutterViewController class]]
+ hint:nil
+ additionalScopes:OCMOCK_ANY
+ completion:OCMOCK_ANY]);
+
+ XCTAssertEqualObjects(self.plugin.configuration.hostedDomain, nil);
+ // Set in example app GoogleService-Info.plist.
+ XCTAssertEqualObjects(
+ self.plugin.configuration.clientID,
+ @"479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u.apps.googleusercontent.com");
+ XCTAssertEqualObjects(self.plugin.configuration.serverClientID, @"mockServerClientId");
+}
+
+- (void)testInitInfoPlist {
+ FSIInitParams *params = [FSIInitParams makeWithScopes:@[ @"scope1" ]
+ hostedDomain:@"example.com"
+ clientId:nil
+ serverClientId:nil];
+
+ FlutterError *error;
+ self.plugin = [[FLTGoogleSignInPlugin alloc] init];
+ [self.plugin initializeSignInWithParameters:params error:&error];
+ XCTAssertNil(error);
+ XCTAssertNil(self.plugin.configuration);
+ XCTAssertNotNil(self.plugin.requestedScopes);
+ // Set in example app Info.plist.
+ XCTAssertEqualObjects(
+ self.plugin.signIn.configuration.clientID,
+ @"479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u.apps.googleusercontent.com");
+ XCTAssertEqualObjects(self.plugin.signIn.configuration.serverClientID, @"YOUR_SERVER_CLIENT_ID");
}
#pragma mark - Is signed in
@@ -193,7 +225,8 @@
OCMStub([mockUser userID]).andReturn(@"mockID");
[[self.mockSignIn stub]
- restorePreviousSignInWithCallback:[OCMArg invokeBlockWithArgs:mockUser, [NSNull null], nil]];
+ restorePreviousSignInWithCompletion:[OCMArg
+ invokeBlockWithArgs:mockUser, [NSNull null], nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin signInSilentlyWithCompletion:^(FSIUserData *user, FlutterError *error) {
@@ -215,7 +248,7 @@
userInfo:nil];
[[self.mockSignIn stub]
- restorePreviousSignInWithCallback:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
+ restorePreviousSignInWithCompletion:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin signInSilentlyWithCompletion:^(FSIUserData *user, FlutterError *error) {
@@ -229,6 +262,8 @@
#pragma mark - Sign in
- (void)testSignIn {
+ self.plugin = [[FLTGoogleSignInPlugin alloc] initWithSignIn:self.mockSignIn
+ withGoogleServiceProperties:self.googleServiceInfo];
id mockUser = OCMClassMock([GIDGoogleUser class]);
id mockUserProfile = OCMClassMock([GIDProfileData class]);
OCMStub([mockUserProfile name]).andReturn(@"mockDisplay");
@@ -239,18 +274,17 @@
OCMStub([mockUser profile]).andReturn(mockUserProfile);
OCMStub([mockUser userID]).andReturn(@"mockID");
- OCMStub([mockUser serverAuthCode]).andReturn(@"mockAuthCode");
+
+ id mockSignInResult = OCMClassMock([GIDSignInResult class]);
+ OCMStub([mockSignInResult user]).andReturn(mockUser);
+ OCMStub([mockSignInResult serverAuthCode]).andReturn(@"mockAuthCode");
[[self.mockSignIn expect]
- signInWithConfiguration:[OCMArg checkWithBlock:^BOOL(GIDConfiguration *configuration) {
- return [configuration.clientID
- isEqualToString:
- @"479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u.apps.googleusercontent.com"];
- }]
- presentingViewController:[OCMArg isKindOfClass:[FlutterViewController class]]
- hint:nil
- additionalScopes:@[]
- callback:[OCMArg invokeBlockWithArgs:mockUser, [NSNull null], nil]];
+ signInWithPresentingViewController:[OCMArg isKindOfClass:[FlutterViewController class]]
+ hint:nil
+ additionalScopes:@[]
+ completion:[OCMArg invokeBlockWithArgs:mockSignInResult,
+ [NSNull null], nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin signInWithCompletion:^(FSIUserData *user, FlutterError *error) {
@@ -264,6 +298,11 @@
}];
[self waitForExpectationsWithTimeout:5.0 handler:nil];
+ // Set in example app GoogleService-Info.plist.
+ XCTAssertEqualObjects(
+ self.plugin.configuration.clientID,
+ @"479882132969-9i9aqik3jfjd7qhci1nqf0bm2g71rm1u.apps.googleusercontent.com");
+
OCMVerifyAll(self.mockSignIn);
}
@@ -278,16 +317,18 @@
id mockUser = OCMClassMock([GIDGoogleUser class]);
OCMStub([mockUser userID]).andReturn(@"mockID");
+ id mockSignInResult = OCMClassMock([GIDSignInResult class]);
+ OCMStub([mockSignInResult user]).andReturn(mockUser);
[[self.mockSignIn expect]
- signInWithConfiguration:OCMOCK_ANY
- presentingViewController:OCMOCK_ANY
- hint:nil
- additionalScopes:[OCMArg checkWithBlock:^BOOL(NSArray<NSString *> *scopes) {
- return [[NSSet setWithArray:scopes]
- isEqualToSet:[NSSet setWithObjects:@"initial1", @"initial2", nil]];
- }]
- callback:[OCMArg invokeBlockWithArgs:mockUser, [NSNull null], nil]];
+ signInWithPresentingViewController:OCMOCK_ANY
+ hint:nil
+ additionalScopes:[OCMArg checkWithBlock:^BOOL(NSArray<NSString *> *scopes) {
+ return [[NSSet setWithArray:scopes]
+ isEqualToSet:[NSSet setWithObjects:@"initial1", @"initial2", nil]];
+ }]
+ completion:[OCMArg invokeBlockWithArgs:mockSignInResult,
+ [NSNull null], nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin signInWithCompletion:^(FSIUserData *user, FlutterError *error) {
@@ -303,20 +344,22 @@
- (void)testSignInAlreadyGranted {
id mockUser = OCMClassMock([GIDGoogleUser class]);
OCMStub([mockUser userID]).andReturn(@"mockID");
+ id mockSignInResult = OCMClassMock([GIDSignInResult class]);
+ OCMStub([mockSignInResult user]).andReturn(mockUser);
[[self.mockSignIn stub]
- signInWithConfiguration:OCMOCK_ANY
- presentingViewController:OCMOCK_ANY
- hint:nil
- additionalScopes:OCMOCK_ANY
- callback:[OCMArg invokeBlockWithArgs:mockUser, [NSNull null], nil]];
+ signInWithPresentingViewController:OCMOCK_ANY
+ hint:nil
+ additionalScopes:OCMOCK_ANY
+ completion:[OCMArg invokeBlockWithArgs:mockSignInResult,
+ [NSNull null], nil]];
NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain
code:kGIDSignInErrorCodeScopesAlreadyGranted
userInfo:nil];
- [[self.mockSignIn stub] addScopes:OCMOCK_ANY
- presentingViewController:OCMOCK_ANY
- callback:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
+ [[self.mockSignIn currentUser] addScopes:OCMOCK_ANY
+ presentingViewController:OCMOCK_ANY
+ completion:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin signInWithCompletion:^(FSIUserData *user, FlutterError *error) {
@@ -332,11 +375,10 @@
code:kGIDSignInErrorCodeCanceled
userInfo:nil];
[[self.mockSignIn stub]
- signInWithConfiguration:OCMOCK_ANY
- presentingViewController:OCMOCK_ANY
- hint:nil
- additionalScopes:OCMOCK_ANY
- callback:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
+ signInWithPresentingViewController:OCMOCK_ANY
+ hint:nil
+ additionalScopes:OCMOCK_ANY
+ completion:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin signInWithCompletion:^(FSIUserData *user, FlutterError *error) {
@@ -348,11 +390,10 @@
}
- (void)testSignInException {
- OCMExpect([self.mockSignIn signInWithConfiguration:OCMOCK_ANY
- presentingViewController:OCMOCK_ANY
- hint:OCMOCK_ANY
- additionalScopes:OCMOCK_ANY
- callback:OCMOCK_ANY])
+ OCMExpect([self.mockSignIn signInWithPresentingViewController:OCMOCK_ANY
+ hint:OCMOCK_ANY
+ additionalScopes:OCMOCK_ANY
+ completion:OCMOCK_ANY])
.andThrow([NSException exceptionWithName:@"MockName" reason:@"MockReason" userInfo:nil]);
__block FlutterError *error;
@@ -371,14 +412,20 @@
- (void)testGetTokens {
id mockUser = OCMClassMock([GIDGoogleUser class]);
- OCMStub([self.mockSignIn currentUser]).andReturn(mockUser);
+ id mockUserResponse = OCMClassMock([GIDGoogleUser class]);
- id mockAuthentication = OCMClassMock([GIDAuthentication class]);
- OCMStub([mockAuthentication idToken]).andReturn(@"mockIdToken");
- OCMStub([mockAuthentication accessToken]).andReturn(@"mockAccessToken");
- [[mockAuthentication stub]
- doWithFreshTokens:[OCMArg invokeBlockWithArgs:mockAuthentication, [NSNull null], nil]];
- OCMStub([mockUser authentication]).andReturn(mockAuthentication);
+ id mockIdToken = OCMClassMock([GIDToken class]);
+ OCMStub([mockIdToken tokenString]).andReturn(@"mockIdToken");
+ OCMStub([mockUserResponse idToken]).andReturn(mockIdToken);
+
+ id mockAccessToken = OCMClassMock([GIDToken class]);
+ OCMStub([mockAccessToken tokenString]).andReturn(@"mockAccessToken");
+ OCMStub([mockUserResponse accessToken]).andReturn(mockAccessToken);
+
+ [[mockUser stub]
+ refreshTokensIfNeededWithCompletion:[OCMArg invokeBlockWithArgs:mockUserResponse,
+ [NSNull null], nil]];
+ OCMStub([self.mockSignIn currentUser]).andReturn(mockUser);
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin getAccessTokenWithCompletion:^(FSITokenData *token, FlutterError *error) {
@@ -394,13 +441,11 @@
id mockUser = OCMClassMock([GIDGoogleUser class]);
OCMStub([self.mockSignIn currentUser]).andReturn(mockUser);
- id mockAuthentication = OCMClassMock([GIDAuthentication class]);
NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain
code:kGIDSignInErrorCodeHasNoAuthInKeychain
userInfo:nil];
- [[mockAuthentication stub]
- doWithFreshTokens:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
- OCMStub([mockUser authentication]).andReturn(mockAuthentication);
+ [[mockUser stub]
+ refreshTokensIfNeededWithCompletion:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin getAccessTokenWithCompletion:^(FSITokenData *token, FlutterError *error) {
@@ -416,13 +461,11 @@
id mockUser = OCMClassMock([GIDGoogleUser class]);
OCMStub([self.mockSignIn currentUser]).andReturn(mockUser);
- id mockAuthentication = OCMClassMock([GIDAuthentication class]);
NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain
code:kGIDSignInErrorCodeCanceled
userInfo:nil];
- [[mockAuthentication stub]
- doWithFreshTokens:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
- OCMStub([mockUser authentication]).andReturn(mockAuthentication);
+ [[mockUser stub]
+ refreshTokensIfNeededWithCompletion:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin getAccessTokenWithCompletion:^(FSITokenData *token, FlutterError *error) {
@@ -438,11 +481,9 @@
id mockUser = OCMClassMock([GIDGoogleUser class]);
OCMStub([self.mockSignIn currentUser]).andReturn(mockUser);
- id mockAuthentication = OCMClassMock([GIDAuthentication class]);
NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorTimedOut userInfo:nil];
- [[mockAuthentication stub]
- doWithFreshTokens:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
- OCMStub([mockUser authentication]).andReturn(mockAuthentication);
+ [[mockUser stub]
+ refreshTokensIfNeededWithCompletion:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin getAccessTokenWithCompletion:^(FSITokenData *token, FlutterError *error) {
@@ -458,11 +499,9 @@
id mockUser = OCMClassMock([GIDGoogleUser class]);
OCMStub([self.mockSignIn currentUser]).andReturn(mockUser);
- id mockAuthentication = OCMClassMock([GIDAuthentication class]);
NSError *error = [NSError errorWithDomain:@"BogusDomain" code:42 userInfo:nil];
- [[mockAuthentication stub]
- doWithFreshTokens:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
- OCMStub([mockUser authentication]).andReturn(mockAuthentication);
+ [[mockUser stub]
+ refreshTokensIfNeededWithCompletion:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin getAccessTokenWithCompletion:^(FSITokenData *token, FlutterError *error) {
@@ -477,13 +516,6 @@
#pragma mark - Request scopes
- (void)testRequestScopesResultErrorIfNotSignedIn {
- NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain
- code:kGIDSignInErrorCodeNoCurrentUser
- userInfo:nil];
- [[self.mockSignIn stub] addScopes:@[ @"mockScope1" ]
- presentingViewController:OCMOCK_ANY
- callback:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
-
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin requestScopes:@[ @"mockScope1" ]
completion:^(NSNumber *success, FlutterError *error) {
@@ -495,12 +527,15 @@
}
- (void)testRequestScopesIfNoMissingScope {
+ id mockUser = OCMClassMock([GIDGoogleUser class]);
+ OCMStub([self.mockSignIn currentUser]).andReturn(mockUser);
+
NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain
code:kGIDSignInErrorCodeScopesAlreadyGranted
userInfo:nil];
- [[self.mockSignIn stub] addScopes:@[ @"mockScope1" ]
- presentingViewController:OCMOCK_ANY
- callback:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
+ [[mockUser stub] addScopes:@[ @"mockScope1" ]
+ presentingViewController:OCMOCK_ANY
+ completion:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin requestScopes:@[ @"mockScope1" ]
@@ -512,11 +547,35 @@
[self waitForExpectationsWithTimeout:5.0 handler:nil];
}
+- (void)testRequestScopesResultErrorIfMismatchingUser {
+ id mockUser = OCMClassMock([GIDGoogleUser class]);
+ OCMStub([self.mockSignIn currentUser]).andReturn(mockUser);
+
+ NSError *error = [NSError errorWithDomain:kGIDSignInErrorDomain
+ code:kGIDSignInErrorCodeMismatchWithCurrentUser
+ userInfo:nil];
+ [[mockUser stub] addScopes:@[ @"mockScope1" ]
+ presentingViewController:OCMOCK_ANY
+ completion:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
+
+ XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
+ [self.plugin requestScopes:@[ @"mockScope1" ]
+ completion:^(NSNumber *success, FlutterError *error) {
+ XCTAssertNil(success);
+ XCTAssertEqualObjects(error.code, @"mismatch_user");
+ [expectation fulfill];
+ }];
+ [self waitForExpectationsWithTimeout:5.0 handler:nil];
+}
+
- (void)testRequestScopesWithUnknownError {
+ id mockUser = OCMClassMock([GIDGoogleUser class]);
+ OCMStub([self.mockSignIn currentUser]).andReturn(mockUser);
+
NSError *error = [NSError errorWithDomain:@"BogusDomain" code:42 userInfo:nil];
- [[self.mockSignIn stub] addScopes:@[ @"mockScope1" ]
- presentingViewController:OCMOCK_ANY
- callback:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
+ [[mockUser stub] addScopes:@[ @"mockScope1" ]
+ presentingViewController:OCMOCK_ANY
+ completion:[OCMArg invokeBlockWithArgs:[NSNull null], error, nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin requestScopes:@[ @"mockScope1" ]
@@ -529,7 +588,10 @@
}
- (void)testRequestScopesException {
- OCMExpect([self.mockSignIn addScopes:@[] presentingViewController:OCMOCK_ANY callback:OCMOCK_ANY])
+ id mockUser = OCMClassMock([GIDGoogleUser class]);
+ OCMStub([self.mockSignIn currentUser]).andReturn(mockUser);
+
+ OCMExpect([mockUser addScopes:@[] presentingViewController:OCMOCK_ANY completion:OCMOCK_ANY])
.andThrow([NSException exceptionWithName:@"MockName" reason:@"MockReason" userInfo:nil]);
[self.plugin requestScopes:@[]
@@ -542,16 +604,18 @@
}
- (void)testRequestScopesReturnsFalseIfOnlySubsetGranted {
- GIDGoogleUser *mockUser = OCMClassMock([GIDGoogleUser class]);
+ id mockUser = OCMClassMock([GIDGoogleUser class]);
OCMStub([self.mockSignIn currentUser]).andReturn(mockUser);
NSArray<NSString *> *requestedScopes = @[ @"mockScope1", @"mockScope2" ];
// Only grant one of the two requested scopes.
- OCMStub(mockUser.grantedScopes).andReturn(@[ @"mockScope1" ]);
+ id mockSignInResult = OCMClassMock([GIDSignInResult class]);
+ OCMStub([mockUser grantedScopes]).andReturn(@[ @"mockScope1" ]);
+ OCMStub([mockSignInResult user]).andReturn(mockUser);
- [[self.mockSignIn stub] addScopes:requestedScopes
- presentingViewController:OCMOCK_ANY
- callback:[OCMArg invokeBlockWithArgs:mockUser, [NSNull null], nil]];
+ [[mockUser stub] addScopes:requestedScopes
+ presentingViewController:OCMOCK_ANY
+ completion:[OCMArg invokeBlockWithArgs:mockSignInResult, [NSNull null], nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin requestScopes:requestedScopes
@@ -564,6 +628,9 @@
}
- (void)testRequestsInitializedScopes {
+ id mockUser = OCMClassMock([GIDGoogleUser class]);
+ OCMStub([self.mockSignIn currentUser]).andReturn(mockUser);
+
FSIInitParams *params = [FSIInitParams makeWithScopes:@[ @"initial1", @"initial2" ]
hostedDomain:nil
clientId:nil
@@ -580,27 +647,28 @@
}];
// All four scopes are requested.
- [[self.mockSignIn verify]
- addScopes:[OCMArg checkWithBlock:^BOOL(NSArray<NSString *> *scopes) {
+ [[mockUser verify] addScopes:[OCMArg checkWithBlock:^BOOL(NSArray<NSString *> *scopes) {
return [[NSSet setWithArray:scopes]
isEqualToSet:[NSSet setWithObjects:@"initial1", @"initial2",
@"addScope1", @"addScope2", nil]];
}]
presentingViewController:OCMOCK_ANY
- callback:OCMOCK_ANY];
+ completion:OCMOCK_ANY];
}
- (void)testRequestScopesReturnsTrueIfGranted {
- GIDGoogleUser *mockUser = OCMClassMock([GIDGoogleUser class]);
+ id mockUser = OCMClassMock([GIDGoogleUser class]);
OCMStub([self.mockSignIn currentUser]).andReturn(mockUser);
NSArray<NSString *> *requestedScopes = @[ @"mockScope1", @"mockScope2" ];
// Grant both of the requested scopes.
- OCMStub(mockUser.grantedScopes).andReturn(requestedScopes);
+ id mockSignInResult = OCMClassMock([GIDSignInResult class]);
+ OCMStub([mockUser grantedScopes]).andReturn(requestedScopes);
+ OCMStub([mockSignInResult user]).andReturn(mockUser);
- [[self.mockSignIn stub] addScopes:requestedScopes
- presentingViewController:OCMOCK_ANY
- callback:[OCMArg invokeBlockWithArgs:mockUser, [NSNull null], nil]];
+ [[mockUser stub] addScopes:requestedScopes
+ presentingViewController:OCMOCK_ANY
+ completion:[OCMArg invokeBlockWithArgs:mockSignInResult, [NSNull null], nil]];
XCTestExpectation *expectation = [self expectationWithDescription:@"completion called"];
[self.plugin requestScopes:requestedScopes
diff --git a/packages/google_sign_in/google_sign_in_ios/ios/Classes/FLTGoogleSignInPlugin.h b/packages/google_sign_in/google_sign_in_ios/ios/Classes/FLTGoogleSignInPlugin.h
index ec5403f..503b6a4 100644
--- a/packages/google_sign_in/google_sign_in_ios/ios/Classes/FLTGoogleSignInPlugin.h
+++ b/packages/google_sign_in/google_sign_in_ios/ios/Classes/FLTGoogleSignInPlugin.h
@@ -7,4 +7,5 @@
#import "messages.g.h"
@interface FLTGoogleSignInPlugin : NSObject <FlutterPlugin, FSIGoogleSignInApi>
+
@end
diff --git a/packages/google_sign_in/google_sign_in_ios/ios/Classes/FLTGoogleSignInPlugin.m b/packages/google_sign_in/google_sign_in_ios/ios/Classes/FLTGoogleSignInPlugin.m
index 91e0a23..5b79511 100644
--- a/packages/google_sign_in/google_sign_in_ios/ios/Classes/FLTGoogleSignInPlugin.m
+++ b/packages/google_sign_in/google_sign_in_ios/ios/Classes/FLTGoogleSignInPlugin.m
@@ -47,20 +47,6 @@
@interface FLTGoogleSignInPlugin ()
-// Configuration wrapping Google Cloud Console, Google Apps, OpenID,
-// and other initialization metadata.
-@property(strong) GIDConfiguration *configuration;
-
-// Permissions requested during at sign in "init" method call
-// unioned with scopes requested later with incremental authorization
-// "requestScopes" method call.
-// The "email" and "profile" base scopes are always implicitly requested.
-@property(copy) NSSet<NSString *> *requestedScopes;
-
-// Instance used to manage Google Sign In authentication including
-// sign in, sign out, and requesting additional scopes.
-@property(strong, readonly) GIDSignIn *signIn;
-
// The contents of GoogleService-Info.plist, if it exists.
@property(strong, nullable) NSDictionary<NSString *, id> *googleServiceProperties;
@@ -113,21 +99,17 @@
GIDConfiguration *configuration = [self configurationWithClientIdArgument:params.clientId
serverClientIdArgument:params.serverClientId
hostedDomainArgument:params.hostedDomain];
+ self.requestedScopes = [NSSet setWithArray:params.scopes];
if (configuration != nil) {
- self.requestedScopes = [NSSet setWithArray:params.scopes];
self.configuration = configuration;
- } else {
- *error = [FlutterError errorWithCode:@"missing-config"
- message:@"GoogleService-Info.plist file not found and clientId "
- @"was not provided programmatically."
- details:nil];
}
}
- (void)signInSilentlyWithCompletion:(nonnull void (^)(FSIUserData *_Nullable,
FlutterError *_Nullable))completion {
- [self.signIn restorePreviousSignInWithCallback:^(GIDGoogleUser *user, NSError *error) {
- [self didSignInForUser:user withCompletion:completion error:error];
+ [self.signIn restorePreviousSignInWithCompletion:^(GIDGoogleUser *_Nullable user,
+ NSError *_Nullable error) {
+ [self didSignInForUser:user withServerAuthCode:nil completion:completion error:error];
}];
}
@@ -139,19 +121,36 @@
- (void)signInWithCompletion:(nonnull void (^)(FSIUserData *_Nullable,
FlutterError *_Nullable))completion {
@try {
- GIDConfiguration *configuration = self.configuration
- ?: [self configurationWithClientIdArgument:nil
- serverClientIdArgument:nil
- hostedDomainArgument:nil];
- [self.signIn signInWithConfiguration:configuration
- presentingViewController:[self topViewController]
- hint:nil
- additionalScopes:self.requestedScopes.allObjects
- callback:^(GIDGoogleUser *user, NSError *error) {
- [self didSignInForUser:user
- withCompletion:completion
- error:error];
- }];
+ // If the configuration settings are passed from the Dart API, use those.
+ // Otherwise, use settings from the GoogleService-Info.plist if available.
+ // If neither are available, do not set the configuration - GIDSignIn will automatically use
+ // settings from the Info.plist (which is the recommended method).
+ if (!self.configuration && self.googleServiceProperties) {
+ self.configuration = [self configurationWithClientIdArgument:nil
+ serverClientIdArgument:nil
+ hostedDomainArgument:nil];
+ }
+ if (self.configuration) {
+ self.signIn.configuration = self.configuration;
+ }
+
+ [self.signIn signInWithPresentingViewController:[self topViewController]
+ hint:nil
+ additionalScopes:self.requestedScopes.allObjects
+ completion:^(GIDSignInResult *_Nullable signInResult,
+ NSError *_Nullable error) {
+ GIDGoogleUser *user;
+ NSString *serverAuthCode;
+ if (signInResult) {
+ user = signInResult.user;
+ serverAuthCode = signInResult.serverAuthCode;
+ }
+
+ [self didSignInForUser:user
+ withServerAuthCode:serverAuthCode
+ completion:completion
+ error:error];
+ }];
} @catch (NSException *e) {
completion(nil, [FlutterError errorWithCode:@"google_sign_in" message:e.reason details:e.name]);
[e raise];
@@ -161,13 +160,13 @@
- (void)getAccessTokenWithCompletion:(nonnull void (^)(FSITokenData *_Nullable,
FlutterError *_Nullable))completion {
GIDGoogleUser *currentUser = self.signIn.currentUser;
- GIDAuthentication *auth = currentUser.authentication;
- [auth doWithFreshTokens:^void(GIDAuthentication *authentication, NSError *error) {
+ [currentUser refreshTokensIfNeededWithCompletion:^(GIDGoogleUser *_Nullable user,
+ NSError *_Nullable error) {
if (error) {
completion(nil, getFlutterError(error));
} else {
- completion([FSITokenData makeWithIdToken:authentication.idToken
- accessToken:authentication.accessToken],
+ completion([FSITokenData makeWithIdToken:user.idToken.tokenString
+ accessToken:user.accessToken.tokenString],
nil);
}
}];
@@ -178,7 +177,7 @@
}
- (void)disconnectWithCompletion:(nonnull void (^)(FlutterError *_Nullable))completion {
- [self.signIn disconnectWithCallback:^(NSError *error) {
+ [self.signIn disconnectWithCompletion:^(NSError *_Nullable error) {
// TODO(stuartmorgan): This preserves the pre-Pigeon-migration behavior, but it's unclear why
// 'error' is being ignored here.
completion(nil);
@@ -191,31 +190,38 @@
NSSet<NSString *> *requestedScopes = self.requestedScopes;
@try {
- [self.signIn addScopes:requestedScopes.allObjects
+ GIDGoogleUser *currentUser = self.signIn.currentUser;
+ if (currentUser == nil) {
+ completion(nil, [FlutterError errorWithCode:@"sign_in_required"
+ message:@"No account to grant scopes."
+ details:nil]);
+ }
+ [currentUser addScopes:requestedScopes.allObjects
presentingViewController:[self topViewController]
- callback:^(GIDGoogleUser *addedScopeUser, NSError *addedScopeError) {
- BOOL granted = NO;
- FlutterError *error = nil;
- if ([addedScopeError.domain isEqualToString:kGIDSignInErrorDomain] &&
- addedScopeError.code == kGIDSignInErrorCodeNoCurrentUser) {
- error = [FlutterError errorWithCode:@"sign_in_required"
- message:@"No account to grant scopes."
- details:nil];
- } else if ([addedScopeError.domain
- isEqualToString:kGIDSignInErrorDomain] &&
- addedScopeError.code ==
- kGIDSignInErrorCodeScopesAlreadyGranted) {
- // Scopes already granted, report success.
- granted = YES;
- } else if (addedScopeUser == nil) {
- granted = NO;
- } else {
- NSSet<NSString *> *grantedScopes =
- [NSSet setWithArray:addedScopeUser.grantedScopes];
- granted = [requestedScopes isSubsetOfSet:grantedScopes];
- }
- completion(error == nil ? @(granted) : nil, error);
- }];
+ completion:^(GIDSignInResult *_Nullable signInResult,
+ NSError *_Nullable addedScopeError) {
+ BOOL granted = NO;
+ FlutterError *error = nil;
+
+ if ([addedScopeError.domain isEqualToString:kGIDSignInErrorDomain] &&
+ addedScopeError.code == kGIDSignInErrorCodeMismatchWithCurrentUser) {
+ error =
+ [FlutterError errorWithCode:@"mismatch_user"
+ message:@"There is an operation on a previous "
+ @"user. Try signing in again."
+ details:nil];
+ } else if ([addedScopeError.domain isEqualToString:kGIDSignInErrorDomain] &&
+ addedScopeError.code ==
+ kGIDSignInErrorCodeScopesAlreadyGranted) {
+ // Scopes already granted, report success.
+ granted = YES;
+ } else if (signInResult.user) {
+ NSSet<NSString *> *grantedScopes =
+ [NSSet setWithArray:signInResult.user.grantedScopes];
+ granted = [requestedScopes isSubsetOfSet:grantedScopes];
+ }
+ completion(error == nil ? @(granted) : nil, error);
+ }];
} @catch (NSException *e) {
completion(nil, [FlutterError errorWithCode:@"request_scopes" message:e.reason details:e.name]);
}
@@ -266,7 +272,8 @@
}
- (void)didSignInForUser:(GIDGoogleUser *)user
- withCompletion:(nonnull void (^)(FSIUserData *_Nullable,
+ withServerAuthCode:(NSString *_Nullable)serverAuthCode
+ completion:(nonnull void (^)(FSIUserData *_Nullable,
FlutterError *_Nullable))completion
error:(NSError *)error {
if (error != nil) {
@@ -278,11 +285,16 @@
// Placeholder that will be replaced by on the Dart side based on screen size.
photoUrl = [user.profile imageURLWithDimension:1337];
}
+ NSString *idToken;
+ if (user.idToken) {
+ idToken = user.idToken.tokenString;
+ }
completion([FSIUserData makeWithDisplayName:user.profile.name
email:user.profile.email
userId:user.userID
photoUrl:[photoUrl absoluteString]
- serverAuthCode:user.serverAuthCode],
+ serverAuthCode:serverAuthCode
+ idToken:idToken],
nil);
}
}
diff --git a/packages/google_sign_in/google_sign_in_ios/ios/Classes/FLTGoogleSignInPlugin_Test.h b/packages/google_sign_in/google_sign_in_ios/ios/Classes/FLTGoogleSignInPlugin_Test.h
index 17ddb7f..fc18c9b 100644
--- a/packages/google_sign_in/google_sign_in_ios/ios/Classes/FLTGoogleSignInPlugin_Test.h
+++ b/packages/google_sign_in/google_sign_in_ios/ios/Classes/FLTGoogleSignInPlugin_Test.h
@@ -6,6 +6,8 @@
#import <google_sign_in_ios/FLTGoogleSignInPlugin.h>
+#import <GoogleSignIn/GoogleSignIn.h>
+
NS_ASSUME_NONNULL_BEGIN
@class GIDSignIn;
@@ -13,6 +15,20 @@
/// Methods exposed for unit testing.
@interface FLTGoogleSignInPlugin ()
+// Configuration wrapping Google Cloud Console, Google Apps, OpenID,
+// and other initialization metadata.
+@property(strong) GIDConfiguration *configuration;
+
+// Permissions requested during at sign in "init" method call
+// unioned with scopes requested later with incremental authorization
+// "requestScopes" method call.
+// The "email" and "profile" base scopes are always implicitly requested.
+@property(copy) NSSet<NSString *> *requestedScopes;
+
+// Instance used to manage Google Sign In authentication including
+// sign in, sign out, and requesting additional scopes.
+@property(strong, readonly) GIDSignIn *signIn;
+
/// Inject @c GIDSignIn for testing.
- (instancetype)initWithSignIn:(GIDSignIn *)signIn;
diff --git a/packages/google_sign_in/google_sign_in_ios/ios/Classes/messages.g.h b/packages/google_sign_in/google_sign_in_ios/ios/Classes/messages.g.h
index 37493aa..745c1ec 100644
--- a/packages/google_sign_in/google_sign_in_ios/ios/Classes/messages.g.h
+++ b/packages/google_sign_in/google_sign_in_ios/ios/Classes/messages.g.h
@@ -43,12 +43,14 @@
email:(NSString *)email
userId:(NSString *)userId
photoUrl:(nullable NSString *)photoUrl
- serverAuthCode:(nullable NSString *)serverAuthCode;
+ serverAuthCode:(nullable NSString *)serverAuthCode
+ idToken:(nullable NSString *)idToken;
@property(nonatomic, copy, nullable) NSString *displayName;
@property(nonatomic, copy) NSString *email;
@property(nonatomic, copy) NSString *userId;
@property(nonatomic, copy, nullable) NSString *photoUrl;
@property(nonatomic, copy, nullable) NSString *serverAuthCode;
+@property(nonatomic, copy, nullable) NSString *idToken;
@end
/// Pigeon version of GoogleSignInTokenData.
diff --git a/packages/google_sign_in/google_sign_in_ios/ios/Classes/messages.g.m b/packages/google_sign_in/google_sign_in_ios/ios/Classes/messages.g.m
index 4d617ca..96d6b54 100644
--- a/packages/google_sign_in/google_sign_in_ios/ios/Classes/messages.g.m
+++ b/packages/google_sign_in/google_sign_in_ios/ios/Classes/messages.g.m
@@ -86,13 +86,15 @@
email:(NSString *)email
userId:(NSString *)userId
photoUrl:(nullable NSString *)photoUrl
- serverAuthCode:(nullable NSString *)serverAuthCode {
+ serverAuthCode:(nullable NSString *)serverAuthCode
+ idToken:(nullable NSString *)idToken {
FSIUserData *pigeonResult = [[FSIUserData alloc] init];
pigeonResult.displayName = displayName;
pigeonResult.email = email;
pigeonResult.userId = userId;
pigeonResult.photoUrl = photoUrl;
pigeonResult.serverAuthCode = serverAuthCode;
+ pigeonResult.idToken = idToken;
return pigeonResult;
}
+ (FSIUserData *)fromList:(NSArray *)list {
@@ -104,6 +106,7 @@
NSAssert(pigeonResult.userId != nil, @"");
pigeonResult.photoUrl = GetNullableObjectAtIndex(list, 3);
pigeonResult.serverAuthCode = GetNullableObjectAtIndex(list, 4);
+ pigeonResult.idToken = GetNullableObjectAtIndex(list, 5);
return pigeonResult;
}
+ (nullable FSIUserData *)nullableFromList:(NSArray *)list {
@@ -116,6 +119,7 @@
(self.userId ?: [NSNull null]),
(self.photoUrl ?: [NSNull null]),
(self.serverAuthCode ?: [NSNull null]),
+ (self.idToken ?: [NSNull null]),
];
}
@end
diff --git a/packages/google_sign_in/google_sign_in_ios/ios/google_sign_in_ios.podspec b/packages/google_sign_in/google_sign_in_ios/ios/google_sign_in_ios.podspec
index 7739005..9658184 100644
--- a/packages/google_sign_in/google_sign_in_ios/ios/google_sign_in_ios.podspec
+++ b/packages/google_sign_in/google_sign_in_ios/ios/google_sign_in_ios.podspec
@@ -16,7 +16,7 @@
s.public_header_files = 'Classes/**/*.h'
s.module_map = 'Classes/FLTGoogleSignInPlugin.modulemap'
s.dependency 'Flutter'
- s.dependency 'GoogleSignIn', '~> 6.2'
+ s.dependency 'GoogleSignIn', '~> 7.0'
s.static_framework = true
s.platform = :ios, '11.0'
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' }
diff --git a/packages/google_sign_in/google_sign_in_ios/lib/google_sign_in_ios.dart b/packages/google_sign_in/google_sign_in_ios/lib/google_sign_in_ios.dart
index 73113ab..9c58950 100644
--- a/packages/google_sign_in/google_sign_in_ios/lib/google_sign_in_ios.dart
+++ b/packages/google_sign_in/google_sign_in_ios/lib/google_sign_in_ios.dart
@@ -103,6 +103,7 @@
displayName: data.displayName,
photoUrl: data.photoUrl,
serverAuthCode: data.serverAuthCode,
+ idToken: data.idToken,
);
}
diff --git a/packages/google_sign_in/google_sign_in_ios/lib/src/messages.g.dart b/packages/google_sign_in/google_sign_in_ios/lib/src/messages.g.dart
index 78fa372..21dd2eb 100644
--- a/packages/google_sign_in/google_sign_in_ios/lib/src/messages.g.dart
+++ b/packages/google_sign_in/google_sign_in_ios/lib/src/messages.g.dart
@@ -60,6 +60,7 @@
required this.userId,
this.photoUrl,
this.serverAuthCode,
+ this.idToken,
});
String? displayName;
@@ -72,6 +73,8 @@
String? serverAuthCode;
+ String? idToken;
+
Object encode() {
return <Object?>[
displayName,
@@ -79,6 +82,7 @@
userId,
photoUrl,
serverAuthCode,
+ idToken,
];
}
@@ -90,6 +94,7 @@
userId: result[2]! as String,
photoUrl: result[3] as String?,
serverAuthCode: result[4] as String?,
+ idToken: result[5] as String?,
);
}
}
diff --git a/packages/google_sign_in/google_sign_in_ios/pigeons/messages.dart b/packages/google_sign_in/google_sign_in_ios/pigeons/messages.dart
index f92f1d0..2baf9af 100644
--- a/packages/google_sign_in/google_sign_in_ios/pigeons/messages.dart
+++ b/packages/google_sign_in/google_sign_in_ios/pigeons/messages.dart
@@ -43,6 +43,7 @@
this.displayName,
this.photoUrl,
this.serverAuthCode,
+ this.idToken,
});
final String? displayName;
@@ -50,6 +51,7 @@
final String userId;
final String? photoUrl;
final String? serverAuthCode;
+ final String? idToken;
}
/// Pigeon version of GoogleSignInTokenData.
diff --git a/packages/google_sign_in/google_sign_in_ios/pubspec.yaml b/packages/google_sign_in/google_sign_in_ios/pubspec.yaml
index c2e780e..d6a9e97 100644
--- a/packages/google_sign_in/google_sign_in_ios/pubspec.yaml
+++ b/packages/google_sign_in/google_sign_in_ios/pubspec.yaml
@@ -2,7 +2,7 @@
description: iOS implementation of the google_sign_in plugin.
repository: https://github.com/flutter/packages/tree/main/packages/google_sign_in/google_sign_in_ios
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22
-version: 5.6.4
+version: 5.6.5
environment:
sdk: ">=2.19.0 <4.0.0"
@@ -36,6 +36,7 @@
# The example deliberately includes limited-use secrets.
false_secrets:
- - /example/ios/Runner/GoogleService-Info.plist
+ - /example/ios/Runner/Info.plist
+ - /example/ios/RunnerTests/GoogleService-Info.plist
- /example/ios/RunnerTests/GoogleSignInTests.m
- /example/lib/main.dart
diff --git a/packages/google_sign_in/google_sign_in_ios/test/google_sign_in_ios_test.dart b/packages/google_sign_in/google_sign_in_ios/test/google_sign_in_ios_test.dart
index ace1a0f..d76bc97 100644
--- a/packages/google_sign_in/google_sign_in_ios/test/google_sign_in_ios_test.dart
+++ b/packages/google_sign_in/google_sign_in_ios/test/google_sign_in_ios_test.dart
@@ -13,12 +13,12 @@
import 'google_sign_in_ios_test.mocks.dart';
final GoogleSignInUserData _user = GoogleSignInUserData(
- email: 'john.doe@gmail.com',
- id: '8162538176523816253123',
- photoUrl: 'https://lh5.googleusercontent.com/photo.jpg',
- displayName: 'John Doe',
- serverAuthCode: '789',
-);
+ email: 'john.doe@gmail.com',
+ id: '8162538176523816253123',
+ photoUrl: 'https://lh5.googleusercontent.com/photo.jpg',
+ displayName: 'John Doe',
+ serverAuthCode: '789',
+ idToken: '123');
final GoogleSignInTokenData _token = GoogleSignInTokenData(
idToken: '123',
@@ -60,6 +60,7 @@
photoUrl: _user.photoUrl,
displayName: _user.displayName,
serverAuthCode: _user.serverAuthCode,
+ idToken: _user.idToken,
));
final dynamic response = await googleSignIn.signInSilently();
@@ -82,6 +83,7 @@
photoUrl: _user.photoUrl,
displayName: _user.displayName,
serverAuthCode: _user.serverAuthCode,
+ idToken: _user.idToken,
));
final dynamic response = await googleSignIn.signIn();