-
Notifications
You must be signed in to change notification settings - Fork 3.3k
[google_sign_in] Redesign API for current identity SDKs #9267
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[google_sign_in] Redesign API for current identity SDKs #9267
Conversation
Also reworks app-facing package example app for testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed the Android implementation!
Future<PlatformGoogleIdTokenCredential?> _authenticate({ | ||
required bool filterToAuthorized, | ||
required bool autoSelectEnabled, | ||
required bool useButtonFlow, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if useButtonFlow
is true, then basically the other options are ignored? Would it be helpful to warn users here about that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a wrapper class at this layer and the Pigeon layer that encapsulate the options that are specific to the non-button flow, and also added some docs, to make things clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've reworked the API here and at the Pigeon layer to put the options specific to non-button-flow in a class, and added comments, to make it clearer what doesn't apply. (When I first wrote this code I didn't use the button flow, so the flat arguments made sense.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok cool this is much clearer, thank you!
...ign_in_android/android/src/main/java/io/flutter/plugins/googlesignin/GoogleSignInPlugin.java
Outdated
Show resolved
Hide resolved
packages/google_sign_in/google_sign_in_android/lib/google_sign_in_android.dart
Outdated
Show resolved
Hide resolved
..._sign_in_android/android/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInTest.java
Show resolved
Hide resolved
ResultCompat.asCompatCallback( | ||
reply -> { | ||
// This is never called, since this test doesn't trigger the getCredentialsAsync callback. | ||
return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: could throw an exception to ensure it's not called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added fail()
to all of these, and adjusted the comment slightly to explain why.
..._sign_in_android/android/src/test/java/io/flutter/plugins/googlesignin/GoogleSignInTest.java
Show resolved
Hide resolved
@@ -13,3 +13,28 @@ should add it to your `pubspec.yaml` as usual. | |||
|
|||
[1]: https://pub.dev/packages/google_sign_in | |||
[2]: https://flutter.dev/to/endorsed-federated-plugin | |||
|
|||
## Integration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we consider linking to the credentials
docs on this? https://developer.android.com/identity/sign-in/credential-manager-siwg#set-google for the non-firebase option? If it's more confusing than helpful because some steps don't apply, maybe not though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By the time I was updating the READMEs I was so used to skipping down to the code on that page I forgot it had setup instructions! I've adjusted to link to that as the non-Firebase option, and removed some of the details since they are covered more thoroughly there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hahaha totally understandable! LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Android implementation LGTM!
Future<PlatformGoogleIdTokenCredential?> _authenticate({ | ||
required bool filterToAuthorized, | ||
required bool autoSelectEnabled, | ||
required bool useButtonFlow, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok cool this is much clearer, thank you!
@@ -13,3 +13,28 @@ should add it to your `pubspec.yaml` as usual. | |||
|
|||
[1]: https://pub.dev/packages/google_sign_in | |||
[2]: https://flutter.dev/to/endorsed-federated-plugin | |||
|
|||
## Integration |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hahaha totally understandable! LGTM!
@LongCatIsLooong / @cbracken Ping on the iOS portion of this review. |
@bparrishMines Could you review the platform interface and app-facing package changes? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As someone that's new to this plugin, thanks for the design doc! I still have a few questions after reading the doc.
|
||
### Requesting more scopes when needed | ||
|
||
If an app determines that the user hasn't granted the scopes it requires, it | ||
should initiate an Authorization request. (Remember that in the web platform, | ||
this request **must be initiated from an user interaction**, like a button press). | ||
should initiate an Authorization request. On some platforms, such as web, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this sounds like there are platforms other than web where user interactions are required for Authorization request. Is that the case? How do I know which of the platforms my app targets have such restriction?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
supportsAuthenticate
? But that's for authentication I assume?
} | ||
// #enddocregion CanAccessScopes | ||
// #docregion Setup | ||
final GoogleSignIn signIn = GoogleSignIn.instance; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm this reminds me of flutter/flutter#168100, if the user connects / disconnects a mouse / keyboard on Android the activity will restart and that would result in the element tree being re-inflated anew.
I guess that does not break the new flow (from reading the docs initialize
has to be called exactly once in a program) since the new activity will spin up a new dart vm? Still it would be an annoyance that every time I unplug my keyboard I have to go over the sign-in process again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or when the activity restarts, the lightweight authentication path will be taken and the flow will typically be invisible to user / require no additional user interactions?
EDIT: Just read the design doc and it mentioned "Fully silent sign in is no longer available"
Future<void> _handleAuthenticationEvent( | ||
GoogleSignInAuthenticationEvent event) async { | ||
// #docregion CheckAuthorization | ||
GoogleSignInAccount? user; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uber nit, consider making user
and authorization
final if possible?
/// | ||
/// Returned Future resolves to an instance of [GoogleSignInAccount] for a | ||
/// successful sign in or `null` in case sign in process was aborted. | ||
/// If this returns false, [authenticate] will throw an UnsupportedError if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: missing backticks / square brackets around UnsupportedError?
/// successful sign in or `null` in case sign in process was aborted. | ||
/// If this returns false, [authenticate] will throw an UnsupportedError if | ||
/// called. See the platform-specific documentation for the package to | ||
/// determine how authentication his handled. For instance, the platform may |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
his -> is
|
||
/// A base class for authentication event streams. | ||
@immutable | ||
sealed class GoogleSignInAuthenticationEvent { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these classes needed? It seems the sealed type is a glorified GoogleSignInAccount?
.
|
||
// The plugin registrar, for querying views. | ||
@property(strong, nonnull) id<FlutterPluginRegistrar> registrar; | ||
@property(nonatomic) id<FlutterPluginRegistrar> registrar; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this still nonnull
?
completion:(nullable void (^)(GIDSignInResult *_Nullable signInResult, | ||
NSError *_Nullable error))completion { | ||
GIDGoogleUser *currentUser = self.signIn.currentUser; | ||
forGoogleSignInUser:(GIDGoogleUser *)user |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume the user
argument is not nullable, otherwise it's failing silently?
}]; | ||
} | ||
|
||
- (void)addScopes:(nonnull NSArray<NSString *> *)scopes | ||
forUser:(NSString *)userId |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can userId be null?
- (void)signOutWithError:(FlutterError *_Nullable *_Nonnull)error { | ||
[self.signIn signOut]; | ||
[self.usersByIdentifier removeAllObjects]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The signOut
method seems to only sign out the current user: https://developers.google.com/identity/sign-in/ios/reference/Classes/GIDSignIn
Why do we have to remove everything in the dictionary? If refreshedAuthorizationTokensForUser
gets called for a different user (is that possible`?) the app would get an error it seems?
This is a full overhaul of the
google_sign_in
API, with breaking changes for all component packages—including the platform interface. The usual model of adding the new approach while keeping the old one is not viable here, as the underlying SDKs have changed significantly since the original API was designed. Web already had some only-partially-compatible shims for this reason, and Android would have had to do something similar; see flutter/flutter#119300 and flutter/flutter#154205, and the design doc for more background.google_sign_in
to reflect changes in underlying SDKs flutter#119300play-services-auth
flutter#150365signIn
method. flutter#137727canAccessScopes
on mobile flutter#124206Pre-Review Checklist
[shared_preferences]
pubspec.yaml
with an appropriate new version according to the pub versioning philosophy, or I have commented below to indicate which version change exemption this PR falls under1.CHANGELOG.md
to add a description of the change, following repository CHANGELOG style, or I have commented below to indicate which CHANGELOG exemption this PR falls under1.///
).Footnotes
Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2 ↩3