Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit b9134b1

Browse files
committed
[google_sign_in] Support Dart-only configuration
1 parent d945080 commit b9134b1

File tree

22 files changed

+273
-38
lines changed

22 files changed

+273
-38
lines changed

packages/google_sign_in/google_sign_in/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## Next
2+
3+
* Add support for configuring `serverClientId` through `GoogleSignIn` constructor.
4+
15
## 5.3.0
26

37
* Moves Android and iOS implementations to federated packages.

packages/google_sign_in/google_sign_in/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,20 @@ This plugin requires iOS 9.0 or higher.
6565
<!-- End of the Google Sign-in Section -->
6666
```
6767

68+
Instead of adding `GoogleService-Info.plist` to your Xcode project, you can configure your app in
69+
Dart code. In this case, skip steps 3-6 and pass `clientId` and `serverClientId` to the
70+
`GoogleSignIn` constructor:
71+
72+
```dart
73+
GoogleSignIn _googleSignIn = GoogleSignIn(
74+
...
75+
// Copied from GoogleService-Info.plist key CLIENT_ID
76+
clientId: '861823949799-vc35cprkp249096uujjn0vvnmcvjppkn.apps.googleusercontent.com',
77+
// Copied from GoogleService-Info.plist key SERVER_CLIENT_ID
78+
serverClientId: 'YOUR_SERVER_CLIENT_ID',
79+
);
80+
```
81+
6882
#### iOS additional requirement
6983

7084
Note that according to

packages/google_sign_in/google_sign_in/lib/google_sign_in.dart

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ class GoogleSignIn {
183183
this.scopes = const <String>[],
184184
this.hostedDomain,
185185
this.clientId,
186+
this.serverClientId,
186187
});
187188

188189
/// Factory for creating default sign in user experience.
@@ -228,9 +229,14 @@ class GoogleSignIn {
228229
/// Domain to restrict sign-in to.
229230
final String? hostedDomain;
230231

231-
/// Client ID being used to connect to google sign-in. Only supported on web.
232+
/// Client ID being used to connect to google sign-in. Only supported on Web
233+
/// and iOS.
232234
final String? clientId;
233235

236+
/// Client ID of the backend server to which ID tokens will be sent. Only
237+
/// supported on Android and iOS.
238+
final String? serverClientId;
239+
234240
final StreamController<GoogleSignInAccount?> _currentUserController =
235241
StreamController<GoogleSignInAccount?>.broadcast();
236242

@@ -260,11 +266,12 @@ class GoogleSignIn {
260266
}
261267

262268
Future<void> _ensureInitialized() {
263-
return _initialization ??= GoogleSignInPlatform.instance.init(
269+
return _initialization ??= GoogleSignInPlatform.instance.init2(
264270
signInOption: signInOption,
265271
scopes: scopes,
266272
hostedDomain: hostedDomain,
267273
clientId: clientId,
274+
serverClientId: serverClientId,
268275
)..catchError((dynamic _) {
269276
// Invalidate initialization if it errors out.
270277
_initialization = null;

packages/google_sign_in/google_sign_in/pubspec.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,14 @@ false_secrets:
4444
- /example/ios/RunnerTests/GoogleSignInTests.m
4545
- /example/lib/main.dart
4646
- /example/web/index.html
47+
48+
# FOR TESTING ONLY. DO NOT MERGE.
49+
dependency_overrides:
50+
google_sign_in_android:
51+
path: ../../google_sign_in/google_sign_in_android
52+
google_sign_in_ios:
53+
path: ../../google_sign_in/google_sign_in_ios
54+
google_sign_in_platform_interface:
55+
path: ../../google_sign_in/google_sign_in_platform_interface
56+
google_sign_in_web:
57+
path: ../../google_sign_in/google_sign_in_web

packages/google_sign_in/google_sign_in/test/google_sign_in_test.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,27 @@ void main() {
9696
'scopes': <String>[],
9797
'hostedDomain': null,
9898
'clientId': fakeClientId,
99+
'serverClientId': null,
100+
}),
101+
isMethodCall('signIn', arguments: null),
102+
],
103+
);
104+
});
105+
106+
test('signIn prioritize serverClientId parameter when available', () async {
107+
const String fakeServerClientId = 'fakeServerClientId';
108+
googleSignIn = GoogleSignIn(serverClientId: fakeServerClientId);
109+
await googleSignIn.signIn();
110+
expect(googleSignIn.currentUser, isNotNull);
111+
expect(
112+
log,
113+
<Matcher>[
114+
isMethodCall('init', arguments: <String, dynamic>{
115+
'signInOption': 'SignInOption.standard',
116+
'scopes': <String>[],
117+
'hostedDomain': null,
118+
'clientId': null,
119+
'serverClientId': fakeServerClientId,
99120
}),
100121
isMethodCall('signIn', arguments: null),
101122
],
@@ -431,5 +452,6 @@ Matcher _isSignInMethodCall({String signInOption = 'SignInOption.standard'}) {
431452
'scopes': <String>[],
432453
'hostedDomain': null,
433454
'clientId': null,
455+
'serverClientId': null,
434456
});
435457
}
Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## Next
2+
3+
* **BREAKING CHANGES**:
4+
* Add `serverClientId` parameter to `IDelegate.init`.
5+
* Make `clientId` unsupported and support `serverClientId` instead.
6+
Historically `clientId` was interpreted as `serverClientId`, but only on Android. On
7+
other platforms it was interpreted as the OAuth `clientId` of the app.
8+
19
## 5.2.5
210

3-
* Splits from `video_player` as a federated implementation.
11+
* Splits from `google_sign_in` as a federated implementation.

packages/google_sign_in/google_sign_in_android/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,9 @@ public void onMethodCall(MethodCall call, Result result) {
137137
List<String> requestedScopes = call.argument("scopes");
138138
String hostedDomain = call.argument("hostedDomain");
139139
String clientId = call.argument("clientId");
140-
delegate.init(result, signInOption, requestedScopes, hostedDomain, clientId);
140+
String serverClientId = call.argument("serverClientId");
141+
delegate.init(
142+
result, signInOption, requestedScopes, hostedDomain, clientId, serverClientId);
141143
break;
142144

143145
case METHOD_SIGN_IN_SILENTLY:
@@ -193,7 +195,8 @@ public void init(
193195
String signInOption,
194196
List<String> requestedScopes,
195197
String hostedDomain,
196-
String clientId);
198+
String clientId,
199+
String serverClientId);
197200

198201
/**
199202
* Returns the account information for the user who is signed in to this app. If no user is
@@ -318,7 +321,8 @@ public void init(
318321
String signInOption,
319322
List<String> requestedScopes,
320323
String hostedDomain,
321-
String clientId) {
324+
String clientId,
325+
String serverClientId) {
322326
try {
323327
GoogleSignInOptions.Builder optionsBuilder;
324328

@@ -335,20 +339,28 @@ public void init(
335339
throw new IllegalStateException("Unknown signInOption");
336340
}
337341

338-
// Only requests a clientId if google-services.json was present and parsed
339-
// by the google-services Gradle script.
340-
// TODO(jackson): Perhaps we should provide a mechanism to override this
341-
// behavior.
342-
int clientIdIdentifier =
343-
context
344-
.getResources()
345-
.getIdentifier("default_web_client_id", "string", context.getPackageName());
346342
if (!Strings.isNullOrEmpty(clientId)) {
347-
optionsBuilder.requestIdToken(clientId);
348-
optionsBuilder.requestServerAuthCode(clientId);
349-
} else if (clientIdIdentifier != 0) {
350-
optionsBuilder.requestIdToken(context.getString(clientIdIdentifier));
351-
optionsBuilder.requestServerAuthCode(context.getString(clientIdIdentifier));
343+
throw new IllegalArgumentException(
344+
"clientId is not supported on Android. "
345+
+ "To set a server client ID use serverClientId instead.");
346+
}
347+
348+
if (Strings.isNullOrEmpty(serverClientId)) {
349+
// Only requests a clientId if google-services.json was present and parsed
350+
// by the google-services Gradle script.
351+
// TODO(jackson): Perhaps we should provide a mechanism to override this
352+
// behavior.
353+
int webClientIdIdentifier =
354+
context
355+
.getResources()
356+
.getIdentifier("default_web_client_id", "string", context.getPackageName());
357+
if (webClientIdIdentifier != 0) {
358+
serverClientId = context.getString(webClientIdIdentifier);
359+
}
360+
}
361+
if (!Strings.isNullOrEmpty(serverClientId)) {
362+
optionsBuilder.requestIdToken(serverClientId);
363+
optionsBuilder.requestServerAuthCode(serverClientId);
352364
}
353365
for (String scope : requestedScopes) {
354366
optionsBuilder.requestScopes(new Scope(scope));

packages/google_sign_in/google_sign_in_android/example/pubspec.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,10 @@ dev_dependencies:
2828

2929
flutter:
3030
uses-material-design: true
31+
32+
# FOR TESTING ONLY. DO NOT MERGE.
33+
dependency_overrides:
34+
google_sign_in_android:
35+
path: ../../../google_sign_in/google_sign_in_android
36+
google_sign_in_platform_interface:
37+
path: ../../../google_sign_in/google_sign_in_platform_interface

packages/google_sign_in/google_sign_in_android/pubspec.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,8 @@ dev_dependencies:
3333
false_secrets:
3434
- /example/android/app/google-services.json
3535
- /example/lib/main.dart
36+
37+
# FOR TESTING ONLY. DO NOT MERGE.
38+
dependency_overrides:
39+
google_sign_in_platform_interface:
40+
path: ../../google_sign_in/google_sign_in_platform_interface
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## Next
2+
3+
* Remove the requirement for a `GoogleService-Info` file.
4+
* Add support for `serverClientId` configuration option.
5+
16
## 5.2.5
27

3-
* Splits from `video_player` as a federated implementation.
8+
* Splits from `google_sign_in` as a federated implementation.

0 commit comments

Comments
 (0)