diff --git a/apps/docs/pages/guides/auth/social-login/auth-google.mdx b/apps/docs/pages/guides/auth/social-login/auth-google.mdx index be1ca53e2a4..fcf03da9931 100644 --- a/apps/docs/pages/guides/auth/social-login/auth-google.mdx +++ b/apps/docs/pages/guides/auth/social-login/auth-google.mdx @@ -234,11 +234,11 @@ Before you can use Sign in with Google, you need to obtain a [Google Cloud Platf ## Using Native Sign in with Google in Flutter - Unlike the OAuth flow which requires the use of a web browser, the native Sign in with Google flow on Android uses the [operating system's built-in functionalities](https://developers.google.com/android/reference/com/google/android/gms/auth/api/identity/package-summary) to prompt the user for consent. Note that native sign-in has been rebranded as _One Tap sign-in on Android_ by Google, which you should not confuse with _One Tap sign in for web_, as mentioned below. + Native Google sign in with Supabase is done through [flutter_appauth](https://pub.dev/packages/flutter_appauth) package for iOS and [google_sign_in](https://pub.dev/packages/google_sign_in) package for Android. When the user provides consent, Google issues an identity token (commonly abbreviated as ID token) that is then sent to your project's Supabase Auth server. When valid, a new user session is started by issuing an access and refresh token from Supabase Auth. - If you are building a Flutter app, you can use the [flutter_appauth](https://pub.dev/packages/flutter_appauth) package to sign a user into your Supabase project: + If you are building a Flutter app, you can use the [google_sign_in](https://pub.dev/packages/google_sign_in) package for Android and [flutter_appauth](https://pub.dev/packages/flutter_appauth) package for iOS to sign a user into your Supabase project: ```dart import 'dart:convert'; @@ -246,6 +246,7 @@ Before you can use Sign in with Google, you need to obtain a [Google Cloud Platf import 'package:crypto/crypto.dart'; import 'package:flutter_appauth/flutter_appauth.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; + import 'package:google_sign_in/google_sign_in.dart'; /// Function to generate a random 16 character string. String _generateRandomString() { @@ -254,70 +255,95 @@ Before you can use Sign in with Google, you need to obtain a [Google Cloud Platf } Future signInWithGoogle() { - // Just a random string - final rawNonce = _generateRandomString(); - final hashedNonce = - sha256.convert(utf8.encode(rawNonce)).toString(); - - /// TODO: update the client ID with your own + /// TODO: update the iOS and Web client ID with your own. /// /// Client ID that you registered with Google Cloud. - /// You will have two different values for iOS and Android. - const clientId = 'YOUR_CLIENT_ID_HERE'; + /// Note that in order to perform Google sign in on Android, you need to + /// provide the web client ID, not the Android client ID. + final clientId = Platform.isIOS ? 'IOS_CLIENT_ID' : 'WEB_CLIENT_ID'; - /// reverse DNS form of the client ID + `:/` is set as the redirect URL - final redirectUrl = '${clientId.split('.').reversed.join('.')}:/'; + late final String? idToken; + late final String? accessToken; + String? rawNonce; - /// Fixed value for google login - const discoveryUrl = - 'https://accounts.google.com/.well-known/openid-configuration'; + // Use AppAuth to perform Google sign in on iOS + // and use GoogleSignIn package for Google sign in on Android + if (Platform.isIOS) { + const appAuth = FlutterAppAuth(); - final appAuth = FlutterAppAuth(); + // Just a random string + rawNonce = _generateRandomString(); + final hashedNonce = sha256.convert(utf8.encode(rawNonce)).toString(); - // authorize the user by opening the consent page - final result = await appAuth.authorize( - AuthorizationRequest( - clientId, - redirectUrl, - discoveryUrl: discoveryUrl, - nonce: hashedNonce, + /// Set as reversed DNS form of Google Client ID + `:/` for Google login + final redirectUrl = '${clientId.split('.').reversed.join('.')}:/'; + + /// Fixed value for google login + const discoveryUrl = + 'https://accounts.google.com/.well-known/openid-configuration'; + + // authorize the user by opening the concent page + final result = await appAuth.authorize( + AuthorizationRequest( + clientId, + redirectUrl, + discoveryUrl: discoveryUrl, + nonce: hashedNonce, + scopes: [ + 'openid', + 'email', + 'profile', + ], + ), + ); + + if (result == null) { + throw 'No result'; + } + + // Request the access and id token to google + final tokenResult = await appAuth.token( + TokenRequest( + clientId, + redirectUrl, + authorizationCode: result.authorizationCode, + discoveryUrl: discoveryUrl, + codeVerifier: result.codeVerifier, + nonce: result.nonce, + scopes: [ + 'openid', + 'email', + ], + ), + ); + + accessToken = tokenResult?.accessToken; + idToken = tokenResult?.idToken; + } else { + final GoogleSignIn googleSignIn = GoogleSignIn( + serverClientId: clientId, scopes: [ 'openid', 'email', ], - ), - ); - - if (result == null) { - throw 'Could not find AuthorizationResponse after authorizing'; + ); + final googleUser = await googleSignIn.signIn(); + final googleAuth = await googleUser!.authentication; + accessToken = googleAuth.accessToken; + idToken = googleAuth.idToken; } - // Request the access and id token to google - final tokenResult = await appAuth.token( - TokenRequest( - clientId, - redirectUrl, - authorizationCode: result.authorizationCode, - discoveryUrl: discoveryUrl, - codeVerifier: result.codeVerifier, - nonce: result.nonce, - scopes: [ - 'openid', - 'email', - ], - ), - ); - - final idToken = tokenResult?.idToken; - if (idToken == null) { - throw 'Could not find idToken from the token response'; + throw 'No ID Token'; + } + if (accessToken == null) { + throw 'No Access Token'; } return supabase.auth.signInWithIdToken( provider: Provider.google, idToken: idToken, - accessToken: tokenResponse?.accessToken, + accessToken: accessToken, nonce: rawNonce, ); } @@ -327,7 +353,7 @@ Before you can use Sign in with Google, you need to obtain a [Google Cloud Platf 1. Configure OAuth credentials for your Google Cloud project in the [Credentials](https://console.cloud.google.com/apis/credentials) page of the console. When creating a new OAuth client ID, choose _Android_ or _iOS_ depending on the mobile operating system your app is built for. - - For Android, use the instructions on screen to provide the SHA-1 certificate fingerprint used to sign your Android app. + - For Android, use the instructions on screen to provide the SHA-1 certificate fingerprint used to sign your Android app. You also need to create a web client ID to perform Google sign in on Android. - For iOS, use the instructions on screen to provide the app Bundle ID, and App Store ID and Team ID if the app is already published on the Apple AppStore. 2. Configure the [OAuth Consent Screen](https://console.cloud.google.com/apis/credentials/consent). This information is shown to the user when giving consent to your app. In particular, make sure you have set up links to your app's privacy policy and terms of service. diff --git a/apps/www/_blog/2023-07-18-flutter-authentication.mdx b/apps/www/_blog/2023-07-18-flutter-authentication.mdx index ddcb61eb074..1eb8c67dbf1 100644 --- a/apps/www/_blog/2023-07-18-flutter-authentication.mdx +++ b/apps/www/_blog/2023-07-18-flutter-authentication.mdx @@ -52,18 +52,20 @@ flutter create myauthapp then we can install the dependencies. Change the working directory to the newly created app directory and run the following command to install our dependencies. ```dart -flutter pub add supabase_flutter flutter_appauth crypto +flutter pub add supabase_flutter flutter_appauth crypto google_sign_in ``` -We will use [supabase_flutter](https://pub.dev/packages/supabase_flutter) to interact with our Supabase instance. [flutter_appauth](https://pub.dev/packages/flutter_appauth) will be used to implement Google login, and [crypto](https://pub.dev/packages/crypto) is a library that has utility functions for encryption that we will use when performing OIDC logins. +We will use [supabase_flutter](https://pub.dev/packages/supabase_flutter) to interact with our Supabase instance. [google_sign_in](https://pub.dev/packages/google_sign_in) will be used to authenticate on Android, and [flutter_appauth](https://pub.dev/packages/flutter_appauth) will be used for iOS. [crypto](https://pub.dev/packages/crypto) is a library that has utility functions for encryption that we will use when performing OIDC logins. We are done installing our dependencies. Let’s set up [authentication](https://supabase.com/docs/guides/auth) now. ## Configure Google sign-in on Supabase Auth -We will obtain client IDs for iOS and Android from the Google Cloud console, and register them to our Supabase project. +We will obtain client IDs for iOS, Android, and web from the Google Cloud console, and register them to our Supabase project. +We need the web client ID in order to use the Google sign-in flow on Android. -First, create your Google Cloud project [here](https://cloud.google.com/) if you do not have one yet. Within your Google Cloud project, follow the [Configure a Google API Console project for Android](https://developers.google.com/identity/sign-in/android/start-integrating#configure_a_project) guide and [Get an OAuth client ID for the iOS](https://developers.google.com/identity/sign-in/ios/start-integrating#get_an_oauth_client_id) guide to obtain client IDs for Android and iOS respectively. +First, create your Google Cloud project [here](https://cloud.google.com/) if you do not have one yet. +Within your Google Cloud project, follow the [Get an OAuth client ID for the iOS](https://developers.google.com/identity/sign-in/ios/start-integrating#get_an_oauth_client_id) guide, [Configure a Google API Console project for Android](https://developers.google.com/identity/sign-in/android/start-integrating#configure_a_project) guide, and [Get your backend server's OAuth 2.0 client ID](https://developers.google.com/identity/sign-in/android/start-integrating#configure_a_project) to obtain client IDs for iOS, Android, and web respectively. Once you have the client IDs, let’s add them to our Supabase dashboard. If you don’t have a Supabase project created yet, you can create one at [database.new](https://database.new) for free. The name is just an internal name, so we can call it “Auth” for now. Database Password will not be used in this example and can be reconfigured later, so press the `Generate a password` button and let Supabase generate a secure random password. No need to copy it anywhere. The region should be anywhere close to where you live, or where your users live in an actual production app. @@ -71,11 +73,11 @@ Lastly, for the pricing plan choose the free plan that allows you to connect wit ![Supabase project creation](/images/blog/flutter-authentication/supabase-project-creation.png) -Your project should be ready in a minute or two. Once your project is ready, you can open `authentication -> Providers -> Google` to set up Google auth. Toggle the `Enable Sign in with Google` switch first. Then add the two client IDs you obtained in your Google Cloud console to `Authorized Client IDs` field with a comma in between the two client IDs like this: `ANDROID_CLIENT_ID,IOS_CLIENT_ID`. +Your project should be ready in a minute or two. Once your project is ready, you can open `authentication -> Providers -> Google` to set up Google auth. Toggle the `Enable Sign in with Google` switch first. Then add the two client IDs you obtained in your Google Cloud console to `Authorized Client IDs` field with a comma in between the two client IDs like this: `IOS_CLIENT_ID,ANDROID_CLIENT_ID,WEB_CLIENT_ID`. ![Supabase auth Google auth provider](/images/blog/flutter-authentication/supabase-google-provider.png) -We also need some Android specific settings to make [flutter_appauth](https://pub.dev/packages/flutter_appauth#android-setup) work. Open `android/app/build.gradle` and find the `defaultConfig`. We need to set the reversed DNS form of the Android Client ID as the`appAuthRedirectScheme` manifest placeholder value. +We also need some Android specific settings to make [flutter_appauth](https://pub.dev/packages/flutter_appauth#android-setup) not throw during app building. Open `android/app/build.gradle` and find the `defaultConfig`. We need to to provide an empty string here. ```groovy ... @@ -83,15 +85,15 @@ android { ... defaultConfig { ... + // We need an empty manifestPlaceholders for appauth to not throw an error manifestPlaceholders += [ - // *account_id* will be unique for every single app - 'appAuthRedirectScheme': 'com.googleusercontent.apps.*account_id*' + 'appAuthRedirectScheme': '' ] } } ``` -That is it for setting up our [Supabase auth to prepare for Google sign-in](https://supabase.com/docs/guides/auth/social-login/auth-google#using-native-sign-in). +That is it for setting up our [Supabase auth to prepare for Google sign-in](https://supabase.com/docs/guides/auth/social-login/auth-google?platform=flutter). Finally, we can initialize Supabase in our Flutter application with the credentials of our Supabase instance. Update your `main.dart` file and add `Supabase.initialize()` in the `main` function like the following. Note that you will see some errors since the home screen is set to the `LoginScreen`, which we will create later. @@ -145,6 +147,7 @@ import 'dart:math'; import 'package:crypto/crypto.dart'; import 'package:flutter/material.dart'; import 'package:flutter_appauth/flutter_appauth.dart'; +import 'package:google_sign_in/google_sign_in.dart'; import 'package:myauthapp/main.dart'; import 'package:myauthapp/screens/profile_screen.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; @@ -182,6 +185,100 @@ class _LoginScreenState extends State { return base64Url.encode(List.generate(16, (_) => random.nextInt(256))); } + Future _googleSignIn() async { + /// TODO: update the iOS and Web client ID with your own. + /// + /// Client ID that you registered with Google Cloud. + /// Note that in order to perform Google sign in on Android, you need to + /// provide the web client ID, not the Android client ID. + final clientId = Platform.isIOS ? 'IOS_CLIENT_ID' : 'WEB_CLIENT_ID'; + + late final String? idToken; + late final String? accessToken; + String? rawNonce; + + // Use AppAuth to perform Google sign in on iOS + // and use GoogleSignIn package for Google sign in on Android + if (Platform.isIOS) { + const appAuth = FlutterAppAuth(); + + // Just a random string + rawNonce = _generateRandomString(); + final hashedNonce = sha256.convert(utf8.encode(rawNonce)).toString(); + + /// Set as reversed DNS form of Google Client ID + `:/` for Google login + final redirectUrl = '${clientId.split('.').reversed.join('.')}:/'; + + /// Fixed value for google login + const discoveryUrl = + 'https://accounts.google.com/.well-known/openid-configuration'; + + // authorize the user by opening the concent page + final result = await appAuth.authorize( + AuthorizationRequest( + clientId, + redirectUrl, + discoveryUrl: discoveryUrl, + nonce: hashedNonce, + scopes: [ + 'openid', + 'email', + 'profile', + ], + ), + ); + + if (result == null) { + throw 'No result'; + } + + // Request the access and id token to google + final tokenResult = await appAuth.token( + TokenRequest( + clientId, + redirectUrl, + authorizationCode: result.authorizationCode, + discoveryUrl: discoveryUrl, + codeVerifier: result.codeVerifier, + nonce: result.nonce, + scopes: [ + 'openid', + 'email', + ], + ), + ); + + accessToken = tokenResult?.accessToken; + idToken = tokenResult?.idToken; + } else { + final GoogleSignIn googleSignIn = GoogleSignIn( + serverClientId: clientId, + scopes: [ + 'openid', + 'email', + ], + ); + final googleUser = await googleSignIn.signIn(); + final googleAuth = await googleUser!.authentication; + accessToken = googleAuth.accessToken; + idToken = googleAuth.idToken; + } + + if (idToken == null) { + throw 'No ID Token'; + } + if (accessToken == null) { + throw 'No Access Token'; + } + + return supabase.auth.signInWithIdToken( + provider: Provider.google, + idToken: idToken, + accessToken: accessToken, + nonce: rawNonce, + ); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -190,75 +287,7 @@ class _LoginScreenState extends State { ), body: Center( child: ElevatedButton( - onPressed: () async { - const appAuth = FlutterAppAuth(); - - // Just a random string - final rawNonce = _generateRandomString(); - final hashedNonce = - sha256.convert(utf8.encode(rawNonce)).toString(); - - /// TODO: update the iOS and Android client ID with your own. - /// - /// Client ID that you registered with Google Cloud. - /// You will have two different values for iOS and Android. - final clientId = - Platform.isIOS ? 'IOS_CLIENT_ID' : 'ANDROID_CLIENT_ID'; - - /// Set as reversed DNS form of Google Client ID + `:/` for Google login - final redirectUrl = '${clientId.split('.').reversed.join('.')}:/'; - - /// Fixed value for google login - const discoveryUrl = - 'https://accounts.google.com/.well-known/openid-configuration'; - - // authorize the user by opening the concent page - final result = await appAuth.authorize( - AuthorizationRequest( - clientId, - redirectUrl, - discoveryUrl: discoveryUrl, - nonce: hashedNonce, - scopes: [ - 'openid', - 'email', - 'profile', - ], - ), - ); - - if (result == null) { - throw 'No result'; - } - - // Request the access and id token to google - final tokenResult = await appAuth.token( - TokenRequest( - clientId, - redirectUrl, - authorizationCode: result.authorizationCode, - discoveryUrl: discoveryUrl, - codeVerifier: result.codeVerifier, - nonce: result.nonce, - scopes: [ - 'openid', - 'email', - ], - ), - ); - - final idToken = tokenResult?.idToken; - - if (idToken == null) { - throw 'No idToken'; - } - - await supabase.auth.signInWithIdToken( - provider: Provider.google, - idToken: idToken, - nonce: rawNonce, - ); - }, + onPressed: _googleSignIn, child: const Text('Google login'), ), ), @@ -272,6 +301,8 @@ In terms of UI, this page is very simple, it just has a basic `Scaffold` with an ![Google sign in](/images/blog/flutter-authentication/google-sign-in.png) Let’s break down what is going on within the `onPressed` callback of the sign in button. +At the top, we check on which platform the user is running the application. +We will break down the iOS flow, because it helps us understand how the Open ID Connect flow works. First, we are generating a [nonce](https://openid.net/specs/openid-connect-core-1_0.html#SelfIssuedDiscovery:~:text=auth_time%20response%20parameter.)-,nonce,-String%20value%20used), which is essentially just a random string. This string is later passed to Google after being hashed to verify that the ID token has not been tampered to prevent a man-in-the-middle attack. @@ -349,6 +380,8 @@ await supabase.auth.signInWithIdToken( ); ``` +The android flow goes through similar steps, but all of the heavy lifting of obtaining the access token and ID token is done by the `google_sign_in` package. + ## Create the Profile Screen The `ProfileScreen` will be just a simple UI presenting some of the information we obtained in the `LoginPage`. We can access the user data with `supabase.auth.currentUser`, where Supabase has saved the personal information in a property called `userMetadata`. In this example, we are displaying the `avatar_url` and `full_name` to display a basic profile page. Create a `lib/screens/profile_screen.dart` file and add the following. diff --git a/examples/auth/flutter-native-google-auth/README.md b/examples/auth/flutter-native-google-auth/README.md index bb53729a0ba..a7f1c0750dc 100644 --- a/examples/auth/flutter-native-google-auth/README.md +++ b/examples/auth/flutter-native-google-auth/README.md @@ -11,10 +11,9 @@ A simple Flutter application with native Google login capabilities on iOS and An - Create a new Supabase project [here](https://database.new) - Add your Supabase credentials to `lib/main.dart` -- Obtain Google API client ID for [Android](https://developers.google.com/identity/sign-in/android/start-integrating#configure_a_project) and [iOS](https://developers.google.com/identity/sign-in/ios/start-integrating#get_an_oauth_client_id) -- Add the client IDs in Supabase dashboard under `Auth -> Providers -> Google -> Authorized Client IDs` and turn on `Enable Sign in with Google` -- Find the `clientId` variable in `lib/screens/login_screen.dart` and paste the two client IDs -- For android open `android/app/build.gradle` file, locate `appAuthRedirectScheme` variable and replace the value with your reversed DNS form of the Android client ID. For example, if your client ID is `1234567890-abc123def456.apps.googleusercontent.com`, then the value should be `com.googleusercontent.apps.1234567890-abc123def456` +- Obtain Google API client ID for [iOS](https://developers.google.com/identity/sign-in/ios/start-integrating#get_an_oauth_client_id), [Android](https://developers.google.com/identity/sign-in/android/start-integrating#configure_a_project), and [Web](https://developers.google.com/identity/sign-in/android/start-integrating#get_your_backend_servers_oauth_20_client_id) +- Add all of the client IDs in Supabase dashboard under `Auth -> Providers -> Google -> Authorized Client IDs` as comma separated values and turn on `Enable Sign in with Google` +- Find the `clientId` variable in `lib/screens/login_screen.dart` and paste the iOS and web client IDs. - Run the app on iOS or Android and test the login flow 🚀 ## Resources diff --git a/examples/auth/flutter-native-google-auth/android/app/build.gradle b/examples/auth/flutter-native-google-auth/android/app/build.gradle index 1eb3c6c9639..ceb7ccdfa1f 100644 --- a/examples/auth/flutter-native-google-auth/android/app/build.gradle +++ b/examples/auth/flutter-native-google-auth/android/app/build.gradle @@ -48,15 +48,15 @@ android { applicationId "com.example.myauthapp" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion 20 + minSdkVersion 21 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName + // You need an empty manifestPlaceholders for appauth to not throw an error manifestPlaceholders += [ - // *account_id* will be unique for every single app - 'appAuthRedirectScheme': 'com.googleusercontent.apps.*account_id*' + 'appAuthRedirectScheme': '' ] - + multiDexEnabled true } buildTypes { @@ -74,4 +74,5 @@ flutter { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'androidx.multidex:multidex:2.0.1' } diff --git a/examples/auth/flutter-native-google-auth/lib/screens/login_screen.dart b/examples/auth/flutter-native-google-auth/lib/screens/login_screen.dart index 562e3d8376b..b91f6f1ff77 100644 --- a/examples/auth/flutter-native-google-auth/lib/screens/login_screen.dart +++ b/examples/auth/flutter-native-google-auth/lib/screens/login_screen.dart @@ -5,6 +5,7 @@ import 'dart:math'; import 'package:crypto/crypto.dart'; import 'package:flutter/material.dart'; import 'package:flutter_appauth/flutter_appauth.dart'; +import 'package:google_sign_in/google_sign_in.dart'; import 'package:myauthapp/main.dart'; import 'package:myauthapp/screens/profile_screen.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; @@ -42,6 +43,100 @@ class _LoginScreenState extends State { return base64Url.encode(List.generate(16, (_) => random.nextInt(256))); } + Future _googleSignIn() async { + /// TODO: update the iOS and Web client ID with your own. + /// + /// Client ID that you registered with Google Cloud. + /// Note that in order to perform Google sign in on Android, you need to + /// provide the web client ID, not the Android client ID. + final clientId = Platform.isIOS ? 'IOS_CLIENT_ID' : 'WEB_CLIENT_ID'; + + late final String? idToken; + late final String? accessToken; + String? rawNonce; + + // Use AppAuth to perform Google sign in on iOS + // and use GoogleSignIn package for Google sign in on Android + if (Platform.isIOS) { + const appAuth = FlutterAppAuth(); + + // Just a random string + rawNonce = _generateRandomString(); + final hashedNonce = sha256.convert(utf8.encode(rawNonce)).toString(); + + /// Set as reversed DNS form of Google Client ID + `:/` for Google login + final redirectUrl = '${clientId.split('.').reversed.join('.')}:/'; + + /// Fixed value for google login + const discoveryUrl = + 'https://accounts.google.com/.well-known/openid-configuration'; + + // authorize the user by opening the concent page + final result = await appAuth.authorize( + AuthorizationRequest( + clientId, + redirectUrl, + discoveryUrl: discoveryUrl, + nonce: hashedNonce, + scopes: [ + 'openid', + 'email', + 'profile', + ], + ), + ); + + if (result == null) { + throw 'No result'; + } + + // Request the access and id token to google + final tokenResult = await appAuth.token( + TokenRequest( + clientId, + redirectUrl, + authorizationCode: result.authorizationCode, + discoveryUrl: discoveryUrl, + codeVerifier: result.codeVerifier, + nonce: result.nonce, + scopes: [ + 'openid', + 'email', + ], + ), + ); + + accessToken = tokenResult?.accessToken; + idToken = tokenResult?.idToken; + } else { + final GoogleSignIn googleSignIn = GoogleSignIn( + serverClientId: clientId, + scopes: [ + 'openid', + 'email', + ], + ); + final googleUser = await googleSignIn.signIn(); + final googleAuth = await googleUser!.authentication; + accessToken = googleAuth.accessToken; + idToken = googleAuth.idToken; + } + + if (idToken == null) { + throw 'No ID Token'; + } + if (accessToken == null) { + throw 'No Access Token'; + } + + return supabase.auth.signInWithIdToken( + provider: Provider.google, + idToken: idToken, + accessToken: accessToken, + nonce: rawNonce, + ); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -50,75 +145,7 @@ class _LoginScreenState extends State { ), body: Center( child: ElevatedButton( - onPressed: () async { - const appAuth = FlutterAppAuth(); - - // Just a random string - final rawNonce = _generateRandomString(); - final hashedNonce = - sha256.convert(utf8.encode(rawNonce)).toString(); - - /// TODO: update the iOS and Android client ID with your own. - /// - /// Client ID that you registered with Google Cloud. - /// You will have two different values for iOS and Android. - final clientId = - Platform.isIOS ? 'IOS_CLIENT_ID' : 'ANDROID_CLIENT_ID'; - - /// Set as reversed DNS form of Google Client ID + `:/` for Google login - final redirectUrl = '${clientId.split('.').reversed.join('.')}:/'; - - /// Fixed value for google login - const discoveryUrl = - 'https://accounts.google.com/.well-known/openid-configuration'; - - // authorize the user by opening the concent page - final result = await appAuth.authorize( - AuthorizationRequest( - clientId, - redirectUrl, - discoveryUrl: discoveryUrl, - nonce: hashedNonce, - scopes: [ - 'openid', - 'email', - 'profile', - ], - ), - ); - - if (result == null) { - throw 'No result'; - } - - // Request the access and id token to google - final tokenResult = await appAuth.token( - TokenRequest( - clientId, - redirectUrl, - authorizationCode: result.authorizationCode, - discoveryUrl: discoveryUrl, - codeVerifier: result.codeVerifier, - nonce: result.nonce, - scopes: [ - 'openid', - 'email', - ], - ), - ); - - final idToken = tokenResult?.idToken; - - if (idToken == null) { - throw 'No idToken'; - } - - await supabase.auth.signInWithIdToken( - provider: Provider.google, - idToken: idToken, - nonce: rawNonce, - ); - }, + onPressed: _googleSignIn, child: const Text('Google login'), ), ), diff --git a/examples/auth/flutter-native-google-auth/pubspec.lock b/examples/auth/flutter-native-google-auth/pubspec.lock index 8af39a793f2..44ae97ef67f 100644 --- a/examples/auth/flutter-native-google-auth/pubspec.lock +++ b/examples/auth/flutter-native-google-auth/pubspec.lock @@ -1,14 +1,38 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + url: "https://pub.dev" + source: hosted + version: "61.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + url: "https://pub.dev" + source: hosted + version: "5.13.0" app_links: dependency: transitive description: name: app_links - sha256: "16725e716afd0634a5441654b1dda2b6c5557aa230884b5e1f41a5aa546a4cb6" + sha256: eb83c2b15b78a66db04e95132678e910fcdb8dc3a9b0aed0c138f50b2bef0dae url: "https://pub.dev" source: hosted - version: "3.4.3" + version: "3.4.5" + args: + dependency: transitive + description: + name: args + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 + url: "https://pub.dev" + source: hosted + version: "2.4.2" async: dependency: transitive description: @@ -45,10 +69,18 @@ packages: dependency: transitive description: name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 url: "https://pub.dev" source: hosted - version: "1.17.1" + version: "1.17.2" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" crypto: dependency: "direct main" description: @@ -57,14 +89,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.3" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be - url: "https://pub.dev" - source: hosted - version: "1.0.5" fake_async: dependency: transitive description: @@ -77,10 +101,10 @@ packages: dependency: transitive description: name: ffi - sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.1.0" file: dependency: transitive description: @@ -98,10 +122,10 @@ packages: dependency: "direct main" description: name: flutter_appauth - sha256: a047019b525ab0e260776d1b0da1000b7416b45b9e8dd02d124c9da571fc1918 + sha256: "19031ea2438a513762e64ec7b58ae1f00cad6fb87f818e405325cd183dfb9fec" url: "https://pub.dev" source: hosted - version: "6.0.0" + version: "6.0.2" flutter_appauth_platform_interface: dependency: transitive description: @@ -114,10 +138,10 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c + sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.3" flutter_test: dependency: "direct dev" description: flutter @@ -136,14 +160,70 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.2" + glob: + dependency: transitive + description: + name: glob + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + google_identity_services_web: + dependency: transitive + description: + name: google_identity_services_web + sha256: "554748f2478619076128152c58905620d10f9c7fc270ff1d3a9675f9f53838ed" + url: "https://pub.dev" + source: hosted + version: "0.2.1+1" + google_sign_in: + dependency: "direct main" + description: + name: google_sign_in + sha256: f45038d27bcad37498f282295ae97eece23c9349fc16649154067b87b9f1fd03 + url: "https://pub.dev" + source: hosted + version: "6.1.5" + google_sign_in_android: + dependency: transitive + description: + name: google_sign_in_android + sha256: "6031f59074a337fdd81be821aba84cee3a41338c6e958499a5cd34d3e1db80ef" + url: "https://pub.dev" + source: hosted + version: "6.1.20" + google_sign_in_ios: + dependency: transitive + description: + name: google_sign_in_ios + sha256: "974944859f9cd40eb8a15b3fe8efb2d47fb7e99438f763f61a1ccd28d74ff4ce" + url: "https://pub.dev" + source: hosted + version: "5.6.4" + google_sign_in_platform_interface: + dependency: transitive + description: + name: google_sign_in_platform_interface + sha256: "35ceee5f0eadc1c07b0b4af7553246e315c901facbb7d3dadf734ba2693ceec4" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + google_sign_in_web: + dependency: transitive + description: + name: google_sign_in_web + sha256: "939e9172a378ec4eaeb7f71eeddac9b55ebd0e8546d336daec476a68e5279766" + url: "https://pub.dev" + source: hosted + version: "0.12.0+5" gotrue: dependency: transitive description: name: gotrue - sha256: "3639beedcbf3d63d9b2a6ca856138aff03d9e09bddd4c5477de77c58f36c83ae" + sha256: "3d15ee24bd05c6b4e5587f6dba727a7c031e5513424aa2ab4fb35b42f8c45ba7" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.12.2" hive: dependency: transitive description: @@ -204,18 +284,18 @@ packages: dependency: transitive description: name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" url: "https://pub.dev" source: hosted - version: "0.12.15" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.5.0" meta: dependency: transitive description: @@ -232,6 +312,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" path: dependency: transitive description: @@ -244,90 +332,106 @@ packages: dependency: transitive description: name: path_provider - sha256: "3087813781ab814e4157b172f1a11c46be20179fcc9bea043e0fba36bc0acaa2" + sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa url: "https://pub.dev" source: hosted - version: "2.0.15" + version: "2.1.1" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: "2cec049d282c7f13c594b4a73976b0b4f2d7a1838a6dd5aaf7bd9719196bee86" + sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1" url: "https://pub.dev" source: hosted - version: "2.0.27" + version: "2.2.0" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "1995d88ec2948dac43edf8fe58eb434d35d22a2940ecee1a9fefcd62beee6eb3" + sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.3.1" path_provider_linux: dependency: transitive description: name: path_provider_linux - sha256: ffbb8cc9ed2c9ec0e4b7a541e56fd79b138e8f47d2fb86815f15358a349b3b57 + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 url: "https://pub.dev" source: hosted - version: "2.1.11" + version: "2.2.1" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" + sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" url: "https://pub.dev" source: hosted - version: "2.0.6" + version: "2.1.1" path_provider_windows: dependency: transitive description: name: path_provider_windows - sha256: "1cb68ba4cd3a795033de62ba1b7b4564dace301f952de6bfb3cd91b202b6ee96" + sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" url: "https://pub.dev" source: hosted - version: "2.1.7" + version: "2.2.1" + pigeon: + dependency: transitive + description: + name: pigeon + sha256: "5a79fd0b10423f6b5705525e32015597f861c31220b522a67d1e6b580da96719" + url: "https://pub.dev" + source: hosted + version: "11.0.1" platform: dependency: transitive description: name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.2" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc" + sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.1.6" postgrest: dependency: transitive description: name: postgrest - sha256: "78fd180ecd2274df7b04c406746495b5c627248856458f8f537bf5348de9c817" + sha256: "87e35d3a59e327188321befbfbfcc5a7a2e71f0d0a13d975cbc7d169387ec712" url: "https://pub.dev" source: hosted - version: "1.3.2" - process: + version: "1.5.1" + pub_semver: dependency: transitive description: - name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" url: "https://pub.dev" source: hosted - version: "4.2.4" + version: "2.1.4" + quiver: + dependency: transitive + description: + name: quiver + sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 + url: "https://pub.dev" + source: hosted + version: "3.2.1" realtime_client: dependency: transitive description: name: realtime_client - sha256: "0342f73f42345f3547e3cdcc804a0ed108fcd9142d1537d159aead94a213e248" + sha256: bf25420988263ba3811f65756685bf4813a527277a784150b8b7de0a583e122f url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.3" retry: dependency: transitive description: @@ -348,66 +452,66 @@ packages: dependency: transitive description: name: shared_preferences - sha256: "396f85b8afc6865182610c0a2fc470853d56499f75f7499e2a73a9f0539d23d0" + sha256: b7f41bad7e521d205998772545de63ff4e6c97714775902c199353f8bf1511ac url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.2.1" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "6478c6bbbecfe9aced34c483171e90d7c078f5883558b30ec3163cf18402c749" + sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.1" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: e014107bb79d6d3297196f4f2d0db54b5d1f85b8ea8ff63b8e8b391a02700feb + sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.3.4" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - sha256: "9d387433ca65717bbf1be88f4d5bb18f10508917a8fa2fb02e0fd0d7479a9afa" + sha256: c2eb5bf57a2fe9ad6988121609e47d3e07bb3bdca5b6f8444e4cf302428a128a url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.1" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - sha256: "23b052f17a25b90ff2b61aad4cc962154da76fb62848a9ce088efe30d7c50ab1" + sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.1" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - sha256: "74083203a8eae241e0de4a0d597dbedab3b8fef5563f33cf3c12d7e93c655ca5" + sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.2.1" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - sha256: "5e588e2efef56916a3b229c3bfe81e6a525665a454519ca51dbcc4236a274173" + sha256: f763a101313bd3be87edffe0560037500967de9c394a714cd598d945517f694f url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.1" sign_in_with_apple: dependency: transitive description: name: sign_in_with_apple - sha256: ac3b113767dfdd765078c507dad9d4d9fe96b669cc7bd88fc36fc15376fb3400 + sha256: "0975c23b9f8b30a80e27d5659a75993a093d4cb5f4eb7d23a9ccc586fea634e0" url: "https://pub.dev" source: hosted - version: "4.3.0" + version: "5.0.0" sign_in_with_apple_platform_interface: dependency: transitive description: @@ -433,10 +537,10 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" stack_trace: dependency: transitive description: @@ -449,10 +553,10 @@ packages: dependency: transitive description: name: storage_client - sha256: a3024569213b064587d616827747b766f9bc796e80cec99bd5ffb597b8aeb018 + sha256: "4bf2fc76f09c3698f0ba3f1a44d567995796f6aef76501f194631d0c03752ab7" url: "https://pub.dev" source: hosted - version: "1.5.1" + version: "1.5.2" stream_channel: dependency: transitive description: @@ -473,18 +577,18 @@ packages: dependency: transitive description: name: supabase - sha256: d854acbcfcfe0b3b703854aedd05858d684b2e46f8dca70b262665d7f70ad3d8 + sha256: ee6ab8aa31438de59027888f87e53df97e138cdd00c0125d4f6f5244c31fc21e url: "https://pub.dev" source: hosted - version: "1.9.5" + version: "1.11.6" supabase_flutter: dependency: "direct main" description: name: supabase_flutter - sha256: "2a32140420a3bd1a9e8c093c08d12bbd93ee9fbb8fc373397ef5a3ad9d93f55c" + sha256: "27ae595efb3ef6612be1270bd368237916e41b2ba20ea99fedd2df220b424888" url: "https://pub.dev" source: hosted - version: "1.10.6" + version: "1.10.19" term_glyph: dependency: transitive description: @@ -497,10 +601,10 @@ packages: dependency: transitive description: name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" url: "https://pub.dev" source: hosted - version: "0.5.1" + version: "0.6.0" typed_data: dependency: transitive description: @@ -521,66 +625,66 @@ packages: dependency: transitive description: name: url_launcher - sha256: eb1e00ab44303d50dd487aab67ebc575456c146c6af44422f9c13889984c00f3 + sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27" url: "https://pub.dev" source: hosted - version: "6.1.11" + version: "6.1.14" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "15f5acbf0dce90146a0f5a2c4a002b1814a6303c4c5c075aa2623b2d16156f03" + sha256: b04af59516ab45762b2ca6da40fa830d72d0f6045cd97744450b73493fa76330 url: "https://pub.dev" source: hosted - version: "6.0.36" + version: "6.1.0" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2" + sha256: "7c65021d5dee51813d652357bc65b8dd4a6177082a9966bc8ba6ee477baa795f" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "6.1.5" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5" + sha256: b651aad005e0cb06a01dbd84b428a301916dc75f0e7ea6165f80057fee2d8e8e url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.6" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: "91ee3e75ea9dadf38036200c5d3743518f4a5eb77a8d13fda1ee5764373f185e" + sha256: b55486791f666e62e0e8ff825e58a023fd6b1f71c49926483f1128d3bbd8fe88 url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.7" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface - sha256: bfdfa402f1f3298637d71ca8ecfe840b4696698213d5346e9d12d4ab647ee2ea + sha256: "95465b39f83bfe95fcb9d174829d6476216f2d548b79c38ab2506e0458787618" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.5" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: "6bb1e5d7fe53daf02a8fee85352432a40b1f868a81880e99ec7440113d5cfcab" + sha256: "2942294a500b4fa0b918685aff406773ba0a4cd34b7f42198742a94083020ce5" url: "https://pub.dev" source: hosted - version: "2.0.17" + version: "2.0.20" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "254708f17f7c20a9c8c471f67d86d76d4a3f9c1591aad1e15292008aceb82771" + sha256: "95fef3129dc7cfaba2bc3d5ba2e16063bb561fc6d78e63eee16162bc70029069" url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.0.8" vector_math: dependency: transitive description: @@ -589,6 +693,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + watcher: + dependency: transitive + description: + name: watcher + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + url: "https://pub.dev" + source: hosted + version: "0.1.4-beta" web_socket_channel: dependency: transitive description: @@ -601,50 +721,58 @@ packages: dependency: transitive description: name: webview_flutter - sha256: "789d52bd789373cc1e100fb634af2127e86c99cf9abde09499743270c5de8d00" + sha256: c1ab9b81090705c6069197d9fdc1625e587b52b8d70cdde2339d177ad0dbb98e url: "https://pub.dev" source: hosted - version: "4.2.2" + version: "4.4.1" webview_flutter_android: dependency: transitive description: name: webview_flutter_android - sha256: "532135f6f6b8030cd039f30eab23f340d650350e29f38e9b37d2eaad028f1018" + sha256: b0cd33dd7d3dd8e5f664e11a19e17ba12c352647269921a3b568406b001f1dff url: "https://pub.dev" source: hosted - version: "3.8.0" + version: "3.12.0" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface - sha256: "656e2aeaef318900fffd21468b6ddc7958c7092a642f0e7220bac328b70d4a81" + sha256: "6d9213c65f1060116757a7c473247c60f3f7f332cac33dc417c9e362a9a13e4f" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.6.0" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview - sha256: "7b203961d6830f3e5ed1df4c4f0493fea8388a46c4d43716167c4a8ba8ecbe83" + sha256: "30b9af6bdd457b44c08748b9190d23208b5165357cc2eb57914fee1366c42974" url: "https://pub.dev" source: hosted - version: "3.6.0" + version: "3.9.1" win32: dependency: transitive description: name: win32 - sha256: dfdf0136e0aa7a1b474ea133e67cb0154a0acd2599c4f3ada3b49d38d38793ee + sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" url: "https://pub.dev" source: hosted - version: "5.0.5" + version: "5.0.9" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1 + sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "1.0.3" + yaml: + dependency: transitive + description: + name: yaml + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" + url: "https://pub.dev" + source: hosted + version: "3.1.2" yet_another_json_isolate: dependency: transitive description: @@ -654,5 +782,5 @@ packages: source: hosted version: "1.1.1" sdks: - dart: ">=3.0.5 <4.0.0" - flutter: ">=3.3.0" + dart: ">=3.1.0 <4.0.0" + flutter: ">=3.13.0" diff --git a/examples/auth/flutter-native-google-auth/pubspec.yaml b/examples/auth/flutter-native-google-auth/pubspec.yaml index 50025acda2c..ec21d01fdcd 100644 --- a/examples/auth/flutter-native-google-auth/pubspec.yaml +++ b/examples/auth/flutter-native-google-auth/pubspec.yaml @@ -12,10 +12,10 @@ dependencies: flutter: sdk: flutter - cupertino_icons: ^1.0.2 - supabase_flutter: ^1.10.6 + supabase_flutter: ^1.10.19 flutter_appauth: ^6.0.0 crypto: ^3.0.3 + google_sign_in: ^6.1.5 dev_dependencies: flutter_test: