Sitemap

🔐 Google Authentication in Flutter using Supabase (Web + Mobile)

4 min readNov 14, 2025

--

Authentication can be one of the most challenging parts of any mobile app - especially when you want a smooth and secure Google sign-in flow that works on both web and mobile.

In this post, we’ll learn how to implement Google Login in Flutter using Supabase, with proper handling for:

  • 🌐 Web Sign-In (via Supabase OAuth)
  • 📱 Native Android/iOS Sign-In (via GoogleSignIn)
  • 🔄 Auth State Listener
  • ⚠️ Error Handling

🧩 Why Supabase + Google Sign-In?

Supabase offers a simple yet powerful authentication system built on top of PostgreSQL and supports OAuth providers like Google, GitHub, and Apple out of the box.

With Flutter, we can easily integrate Supabase authentication and extend it with native sign-in using the google_sign_in package.

Get Snehal Singh 👩‍💻’s stories in your inbox

Join Medium for free to get updates from this writer.

✅ Works across Web, Android, and iOS
✅ Automatically manages sessions and tokens
✅ Simple integration with your Supabase backend

Step 1: Initialize Supabase

Initialize Supabase in your main.dart file:

void main() async {
WidgetsFlutterBinding.ensureInitialized();

await Supabase.initialize(
url: 'https://your-project.supabase.co',
anonKey: 'YOUR_SUPABASE_ANON_KEY',
);

runApp(const MyApp());
}

Step 2: Create the Google Auth Service

Let’s create a service to handle Google authentication logic.

File: lib/services/auth_service.dart

import 'package:flutter/foundation.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

class AuthService {
static final AuthService instance = AuthService._internal();
AuthService._internal();

final SupabaseClient _client = Supabase.instance.client;

// Main method to handle Google sign-in
Future<bool> signInWithGoogle() async {
try {
const webClientId = String.fromEnvironment(
'GOOGLE_WEB_CLIENT_ID',
defaultValue: '',
);

if (kIsWeb) {
// For Web
return await _signInWithGoogleWeb();
} else {
// For Android/iOS
return await _signInWithGoogleNative(webClientId);
}
} catch (error) {
throw AuthException('Google sign-in failed: ${error.toString()}');
}
}

// Web Sign-In using Supabase OAuth
Future<bool> _signInWithGoogleWeb() async {
await _client.auth.signInWithOAuth(OAuthProvider.google);
return true;
}

// Native Sign-In using GoogleSignIn package
Future<bool> _signInWithGoogleNative(String webClientId) async {
if (webClientId.isEmpty) {
throw AuthException('Google Web Client ID not configured');
}

final googleSignIn = GoogleSignIn(serverClientId: webClientId);
GoogleSignInAccount? user = await googleSignIn.signInSilently();
user ??= await googleSignIn.signIn();

if (user == null) return false;

final googleAuth = await user.authentication;

final response = await _client.auth.signInWithIdToken(
provider: OAuthProvider.google,
idToken: googleAuth.idToken!,
accessToken: googleAuth.accessToken,
);

return response.user != null;
}

Future<void> signOut() async {
await _client.auth.signOut();
}
}

What’s Happening Here?

  • For Web: Supabase handles OAuth redirection automatically.
  • For Mobile: We manually handle the sign-in using the google_sign_in plugin and pass the tokens to Supabase.
  • Cross-platform logic ensures the right flow is used based on kIsWeb.

Step 3: Using It in Your Flutter App

Now let’s use our service in a simple button press.

File: lib/screens/login_screen.dart

import 'package:flutter/material.dart';
import '../services/auth_service.dart';

class LoginScreen extends StatefulWidget {
const LoginScreen({super.key});

@override
State<LoginScreen> createState() => _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> {
bool _isLoading = false;
String? _errorMessage;

Future<void> _handleGoogleSignIn() async {
setState(() {
_isLoading = true;
_errorMessage = null;
});

try {
final success = await AuthService.instance.signInWithGoogle();

if (success && mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Google sign-in successful!'),
backgroundColor: Colors.green,
),
);
} else {
_errorMessage = 'Sign-in was cancelled';
}
} catch (e) {
setState(() {
_errorMessage = e.toString();
});
} finally {
setState(() => _isLoading = false);
}
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: _isLoading
? const CircularProgressIndicator()
: ElevatedButton.icon(
onPressed: _handleGoogleSignIn,
icon: const Icon(Icons.login),
label: const Text("Continue with Google"),
),
),
);
}
}

Step 4: Configure Google Cloud Console

This is an essential step to make your Google Auth work seamlessly across Android and Web.

  1. Go to the Google Cloud Console.
  2. Navigate to APIs & Services → Credentials → Create Credentials → OAuth client ID.
  3. Create two separate OAuth clients:
  • Web Client:
  • Application Type: Web Application
  • Add your redirect URI and callback URI (from Supabase project or local setup).
  • Android Client:
  • Application Type: Android
  • Add your package name (same as your app’s) and SHA-1 key.
  • You can generate SHA-1 using:
  • keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

4. Copy the generated Client IDs — they’ll be used in code and by Supabase during authentication.

Press enter or click to view image in full size

Step 5: Set Up Google Credentials in Supabase

  1. Go to your Supabase Project Dashboard
  2. Navigate to Authentication → Providers → Google
  3. Enable Google Provider
  4. Add your Client ID and Client Secret
  • You can find these in the Google Cloud Console → Credentials

Step 6: Handle Auth State Changes

You can listen to authentication state changes globally:

Supabase.instance.client.auth.onAuthStateChange.listen((data) {
final event = data.event;
if (event == AuthChangeEvent.signedIn) {
debugPrint('✅ User signed in: ${data.session?.user.email}');
} else if (event == AuthChangeEvent.signedOut) {
debugPrint('🚪 User signed out');
}
});

This is useful for automatically navigating users to home or login screens.

Step 7: Logging Out

To sign out from both Supabase and Google:

Future<void> signOut() async {
final googleSignIn = GoogleSignIn();
if (await googleSignIn.isSignedIn()) {
await googleSignIn.signOut();
}
await Supabase.instance.client.auth.signOut();
}

Demo:

Full Souce Code

Here is the source code that you can clone and use for your application.
GitHub Link: Google Auth Using Supabase

Please Follow 💙 and clap 👏, if you find the article useful. And get notified of my upcoming articles.

Follow me on Twitter: @imsnehalsingh and Github: Snehal Singh to hear about my projects.

--

--

Snehal Singh 👩‍💻
Snehal Singh 👩‍💻