🔐 Google Authentication in Flutter using Supabase (Web + Mobile)
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_inplugin 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.
- Go to the Google Cloud Console.
- Navigate to APIs & Services → Credentials → Create Credentials → OAuth client ID.
- 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.
Step 5: Set Up Google Credentials in Supabase
- Go to your Supabase Project Dashboard
- Navigate to Authentication → Providers → Google
- Enable Google Provider
- 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.








