fix: Update Google login example app, guide, and blog article to use new Google login flow for Flutter (#18222)

* update Flutter Google login example to use google_sign_in package

* update build.gradle to support multidex

* compatible with native google login

* update comments

* update readme of sample app

* fix the blog to use the new flow

* update google login guide for Flutter to use the new flow

* Add an intro line for Flutter native google auth guide
This commit is contained in:
Tyler authored and GitHub committed 2023-10-16 15:40:46 +09:00
1 parent 3e95f766ed
commit cb51a8bb9c
7 files changed
+524 -310

No files matched your search

@@ -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<AuthResponse> 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.
@@ -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<LoginScreen> {
return base64Url.encode(List<int>.generate(16, (_) => random.nextInt(256)));
}
Future<AuthResponse> _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<LoginScreen> {
),
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.
@@ -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
@@ -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'
}
@@ -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<LoginScreen> {
return base64Url.encode(List<int>.generate(16, (_) => random.nextInt(256)));
}
Future<AuthResponse> _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<LoginScreen> {
),
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'),
),
),
@@ -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"
@@ -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: