Integrasi login Google di aplikasi Flutter sudah menjadi standar industri. Hampir setiap aplikasi modern, baik mobile maupun web, menawarkan opsi login dengan akun Google karena kemudahan dan kepercayaan yang ditawarkannya. Bagi developer Flutter, menambahkan fitur ini bukan sekadar mengikuti tren, tapi juga meningkatkan user experience dan mempercepat proses onboarding pengguna.
Sebagai developer, saya tahu betul betapa pentingnya menjaga alur kerja tetap efisien. Membangun sistem otentikasi dari nol bisa sangat memakan waktu. Untungnya, Flutter punya ekosistem yang matang, termasuk plugin google_sign_in yang sangat andal. Artikel ini akan memandu Anda langkah demi langkah, mulai dari persiapan di Google Cloud hingga implementasi di kode Flutter Anda, baik untuk platform Android maupun iOS. Kita akan membahas konfigurasi yang sering menjadi batu sandungan, tips praktis, dan masalah umum yang sering saya temui di lapangan.
Siapkan IDE Anda, karena kita akan segera membuat aplikasi Flutter dengan login Google!
Persiapan Awal: Yang Perlu Anda Miliki
Sebelum kita terjun ke kode, ada beberapa hal dasar yang harus Anda persiapkan. Ini adalah pondasi agar proses integrasi berjalan mulus:
- Flutter SDK Terinstall: Pastikan Anda memiliki versi Flutter SDK yang terbaru dan stabil.
- IDE (Android Studio/VS Code): Pilih salah satu favorit Anda untuk pengembangan Flutter.
- Akun Google: Tentu saja, Anda butuh akun Google untuk mengakses Google Cloud Console.
- Perangkat Uji/Emulator: Siapkan emulator Android/iOS atau perangkat fisik untuk menguji aplikasi.
- Pengetahuan Dasar Flutter: Pahami struktur project Flutter, widget, dan manajemen state sederhana.
Langkah 1: Konfigurasi di Google Cloud Console
Ini adalah bagian paling krusial dan seringkali menjadi sumber error jika tidak dilakukan dengan benar. Kita perlu mendaftarkan aplikasi kita ke Google dan mendapatkan kredensial yang diperlukan.
Membuat Project Google Cloud Baru
- Buka Google Cloud Console.
- Pilih “Select a project” di bagian atas, lalu klik “New Project”.
- Berikan nama project yang sesuai (misalnya, “Flutter Google Login Demo”) dan klik “Create”.
Mengaktifkan Google Sign-In API
- Setelah project dibuat, pastikan project tersebut terpilih.
- Di panel navigasi kiri, pergi ke “APIs & Services” > “Enabled APIs & Services”.
- Klik “+ ENABLE APIS AND SERVICES” di bagian atas.
- Cari “Google Sign-In API” (atau “Google People API” yang sering digunakan bersamaan) dan aktifkan.
Membuat Layar Persetujuan OAuth (OAuth Consent Screen)
Ini adalah layar yang akan dilihat pengguna saat pertama kali mereka mencoba login dengan Google. Tujuannya agar pengguna tahu data apa yang diakses aplikasi Anda.
- Di panel navigasi kiri, pergi ke “APIs & Services” > “OAuth consent screen”.
- Pilih tipe pengguna “External” (karena aplikasi ini untuk pengguna umum) dan klik “Create”.
- Isi informasi aplikasi:
- App name: Nama aplikasi Anda (misalnya, “My Flutter App”).
- User support email: Email dukungan.
- App logo: Opsional, tambahkan logo aplikasi Anda.
- Developer contact information: Email kontak developer.
- Klik “SAVE AND CONTINUE”.
- Pada bagian “Scopes”, Anda bisa menambahkan scope yang diperlukan. Untuk Google Sign-In dasar, scope
userinfo.emaildanuserinfo.profilesudah cukup. Klik “ADD OR REMOVE SCOPES”, pilih kedua scope tersebut, lalu klik “UPDATE”. - Klik “SAVE AND CONTINUE”.
- Pada bagian “Test users”, Anda bisa menambahkan akun Google untuk pengujian. Ini penting jika aplikasi Anda masih dalam status “Testing”.
- Klik “SAVE AND CONTINUE” lalu “BACK TO DASHBOARD”.
Membuat Kredensial OAuth Client ID
Kita perlu membuat kredensial terpisah untuk platform Android dan iOS.
Untuk Android
- Di panel navigasi kiri, pergi ke “APIs & Services” > “Credentials”.
- Klik “+ CREATE CREDENTIALS” > “OAuth client ID”.
- Pilih “Android” sebagai “Application type”.
- Berikan nama (misalnya, “Flutter Android Client”).
- Untuk “Package name”, masukkan package name aplikasi Flutter Android Anda (biasanya di
android/app/src/main/AndroidManifest.xml, caripackage="com.example.your_app_name"). - Untuk “SHA-1 certificate fingerprint”, Anda perlu mendapatkannya dari mesin pengembangan Anda.
- Cara mendapatkan SHA-1 Debug Key:
Buka terminal di root project Flutter Anda, lalu jalankan perintah berikut:
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass androidJika Anda menggunakan Android Studio, Anda juga bisa menemukan SHA-1 di panel “Gradle” > “Tasks” > “android” > “signingReport”.
Salin nilai SHA-1 (misalnya,
XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX). - Penting: Untuk aplikasi rilis (production), Anda harus membuat SHA-1 dari release keystore Anda. Prosesnya serupa, tetapi menggunakan keystore yang berbeda.
google-services.json.Untuk iOS
- Di halaman “Credentials”, klik “+ CREATE CREDENTIALS” > “OAuth client ID” lagi.
- Pilih “iOS” sebagai “Application type”.
- Berikan nama (misalnya, “Flutter iOS Client”).
- Untuk “Bundle ID”, masukkan Bundle ID aplikasi Flutter iOS Anda (biasanya di
ios/Runner.xcodeproj/project.pbxproj, cariPRODUCT_BUNDLE_IDENTIFIERatau di Xcode, pilih target Runner, di tab “General”). - Klik “CREATE”.
- Anda akan mendapatkan Client ID dan juga “Reverse Client ID” (seringkali formatnya terbalik). Catat kedua nilai ini.
Untuk Web (Opsional, tapi Direkomendasikan untuk Backend)
Meskipun kita fokus pada mobile, seringkali ada kebutuhan untuk memverifikasi token Google di backend. Untuk itu, buat satu lagi OAuth client ID dengan tipe “Web application”. Client ID dari tipe ini yang biasanya digunakan di backend untuk validasi token.
- Di halaman “Credentials”, klik “+ CREATE CREDENTIALS” > “OAuth client ID”.
- Pilih “Web application” sebagai “Application type”.
- Berikan nama (misalnya, “Flutter Web Backend Client”).
- Biarkan kolom “Authorized JavaScript origins” dan “Authorized redirect URIs” kosong jika Anda hanya butuh Client ID untuk backend.
- Klik “CREATE”. Catat Client ID ini.
Mengunduh File Konfigurasi
Ini adalah langkah terakhir di Google Cloud Console yang sangat penting:
- Untuk Android: Di halaman “Credentials”, Anda akan melihat daftar Client ID yang sudah dibuat. Klik ikon unduh (panah ke bawah) di samping Client ID Android Anda. File yang terunduh akan bernama
client_secret_XXXX.json. Ubah namanya menjadigoogle-services.json. - Untuk iOS: Tidak ada file konfigurasi khusus yang perlu diunduh. Anda akan menggunakan Client ID dan Reverse Client ID yang sudah dicatat sebelumnya.
Langkah 2: Konfigurasi Project Flutter
Sekarang kita akan memasukkan kredensial yang sudah kita dapatkan ke dalam project Flutter kita.
Menambahkan Dependency
Buka file pubspec.yaml di root project Flutter Anda dan tambahkan dependency google_sign_in:
dependencies:
flutter:
sdk: flutter
google_sign_in: ^6.2.1 # Pastikan menggunakan versi terbaru
Setelah itu, jalankan flutter pub get di terminal.
Konfigurasi Platform Android
Menambahkan google-services.json
Pindahkan file google-services.json yang sudah Anda unduh dan ganti nama ke direktori android/app/ di project Flutter Anda.
Mengupdate Gradle Build Files
-
android/build.gradle(Project Level)Tambahkan baris berikut di bagian
dependencies:buildscript { ext.kotlin_version = '1.8.20' // Sesuaikan dengan versi Kotlin Anda repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:7.4.2' // Sesuaikan dengan versi Gradle Anda classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.google.gms:google-services:4.3.15' // Tambahkan baris ini } } allprojects { repositories { google() mavenCentral() } } -
android/app/build.gradle(Module Level)Tambahkan plugin di bagian paling atas file:
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" apply plugin: 'com.google.gms.google-services' // Tambahkan baris iniPastikan
minSdkVersiondiatur minimal ke 19 atau lebih tinggi (biasanya 21 atau 23). Cari di bagiandefaultConfig:android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.flutter_google_login_demo" minSdkVersion 21 // Pastikan ini minimal 19 targetSdkVersion flutter.targetSdkVersion versionCode flutter.versionCode versionName flutter.versionName } }
Konfigurasi Platform iOS
Untuk iOS, kita perlu menambahkan Reverse Client ID dan informasi URL Scheme.
-
Membuka Project di Xcode:
Buka folder
iosdi project Flutter Anda menggunakan Xcode. -
Menambahkan URL Scheme:
Di Xcode, pilih project “Runner” di navigator project kiri. Pilih target “Runner” lalu buka tab “Info”.
Pada bagian “URL Types”, klik tombol “+” untuk menambahkan URL Type baru.
- Untuk “Identifier”, masukkan nama unik (misalnya,
com.googleusercontent.apps.YOUR_CLIENT_ID). - Untuk “URL Schemes”, masukkan “Reverse Client ID” yang Anda dapatkan dari Google Cloud Console. Ini adalah Client ID iOS Anda tetapi urutannya terbalik (misalnya,
com.googleusercontent.apps.123456789012-abcdefghijklmnomenjadiapps.123456789012-abcdefghijklmno.com.googleusercontent).
Ini akan menambahkan entri serupa ke file
Info.plistAnda:<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLSchemes</key> <array> <string>com.googleusercontent.apps.123456789012-abcdefghijklmno</string> <!-- Masukkan Reverse Client ID Anda di sini --> </array> </dict> </array> - Untuk “Identifier”, masukkan nama unik (misalnya,
Langkah 3: Mengimplementasikan Google Sign-In di Kode Flutter
Setelah semua konfigurasi selesai, saatnya menulis kode Flutter untuk mengintegrasikan login Google.
Membuat Tampilan Dasar
Kita akan membuat layar sederhana dengan tombol login Google, teks untuk menampilkan status, dan tombol logout.
import 'package:flutter/material.dart';
import 'package:google_sign_in/google_sign_in.dart';
class GoogleSignInPage extends StatefulWidget {
const GoogleSignInPage({Key? key}) : super(key: key);
@override
State<GoogleSignInPage> createState() => _GoogleSignInPageState();
}
class _GoogleSignInPageState extends State<GoogleSignInPage> {
GoogleSignIn _googleSignIn = GoogleSignIn(
scopes: [
'email',
'https://www.googleapis.com/auth/contacts.readonly', // Contoh scope tambahan
],
);
GoogleSignInAccount? _currentUser;
String _contactText = '';
@override
void initState() {
super.initState();
_googleSignIn.onCurrentUserChanged.listen((GoogleSignInAccount? account) {
setState(() {
_currentUser = account;
});
if (_currentUser != null) {
_handleGetContact();
}
});
_googleSignIn.signInSilently(); // Mencoba login secara pasif jika sudah pernah
}
Future<void> _handleGetContact() async {
setState(() {
_contactText = 'Loading contact info...';
});
final http.Response response = await _googleSignIn.authenticatedClient!.get(
Uri.parse('https://people.googleapis.com/v1/people/me/connections'
'?requestMask.includeField=person.names,person.photos'),
headers: await _currentUser!.authHeaders,
);
if (response.statusCode != 200) {
setState(() {
_contactText = "People API gave a ${response.statusCode} "
"response. Check logs for details.";
});
print('People API ${response.statusCode} response: ${response.body}');
return;
}
final Map<String, dynamic> data =
json.decode(response.body) as Map<String, dynamic>;
final String? namedContact = _pickContact(data);
setState(() {
if (namedContact != null) {
_contactText = 'I see you, $namedContact!';
} else {
_contactText = 'No contacts to display.';
}
});
}
String? _pickContact(Map<String, dynamic> data) {
final List<dynamic> connections = data['connections'] as List<dynamic>;
final Map<String, dynamic> contact = connections.firstWhere(
(dynamic contact) => (contact as Map<String, dynamic>)['names'] != null,
orElse: () => null,
) as Map<String, dynamic>;
if (contact != null) {
final Map<String, dynamic> name = contact['names'].first as Map<String, dynamic>;
return name['displayName'] as String?;
}
return null;
}
Future<void> _handleSignIn() async {
try {
await _googleSignIn.signIn();
} catch (error) {
print('Error during Google Sign-In: $error');
// Tampilkan pesan error ke user jika diperlukan
}
}
Future<void> _handleSignOut() => _googleSignIn.disconnect();
Widget _buildBody() {
GoogleSignInAccount? user = _currentUser;
if (user != null) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
ListTile(
leading: GoogleUserCircleAvatar(identity: user),
title: Text(user.displayName ?? ''),
subtitle: Text(user.email),
),
const Text('Signed in successfully.'),
Text(_contactText),
ElevatedButton(
onPressed: _handleSignOut,
child: const Text('SIGN OUT'),
),
],
);
} else {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
const Text('You are not currently signed in.'),
ElevatedButton(
onPressed: _handleSignIn,
child: const Text('SIGN IN WITH GOOGLE'),
),
],
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Google Sign In Flutter'),
),
body: ConstrainedBox(
constraints: const BoxConstraints.expand(),
child: _buildBody(),
),
);
}
}
Catatan: Kode di atas adalah contoh dari dokumentasi resmi google_sign_in yang dimodifikasi. Anda mungkin perlu menambahkan import 'dart:convert'; dan import 'package:http/http.dart' as http; jika ingin menggunakan API kontak seperti contoh.
Penjelasan Kode
GoogleSignIn _googleSignIn: Ini adalah instance utama dari plugingoogle_sign_in. Anda bisa menentukanscopesdi sini. Scope menentukan data apa saja yang akan diminta dari akun Google pengguna (misalnya, email, profil, atau akses ke Google Contacts)._googleSignIn.onCurrentUserChanged.listen(): Listener ini akan aktif setiap kali status login pengguna berubah (misalnya, setelah login atau logout). Ini berguna untuk memperbarui UI secara real-time._googleSignIn.signInSilently(): Fungsi ini mencoba untuk login kembali secara otomatis jika pengguna sebelumnya sudah pernah login ke aplikasi ini dan sesi mereka masih aktif. Ini sangat bagus untuk user experience._handleSignIn(): Metode ini dipanggil saat tombol “SIGN IN WITH GOOGLE” ditekan. Ini akan memunculkan pop-up browser atau dialog sistem operasi untuk otentikasi Google. Jika berhasil,_currentUserakan terisi._handleSignOut(): Metode ini dipanggil saat tombol “SIGN OUT” ditekan. Ini akan menghapus sesi login Google dari aplikasi._currentUser: Variabel ini menyimpan objekGoogleSignInAccountjika ada pengguna yang login. Dari objek ini, kita bisa mendapatkan detail sepertidisplayName,email,photoUrl, danid.
Masalah yang Sering Terjadi dan Solusinya
Integrasi Google Sign-In memang punya beberapa titik rawan. Berikut adalah beberapa masalah umum yang sering saya temui dan bagaimana cara mengatasinya:
1. Error di Android: “A non-recoverable sign in failure occurred.” atau Status 10
- Penyebab: Biasanya disebabkan oleh SHA-1 fingerprint yang salah atau tidak terdaftar di Google Cloud Console. Bisa juga
google-services.jsontidak diletakkan di lokasi yang benar atau tidak ada di project. - Solusi:
- Verifikasi kembali SHA-1 fingerprint Anda. Pastikan Anda menggunakan SHA-1 dari debug keystore (untuk pengembangan) atau release keystore (untuk produksi) yang benar.
- Pastikan file
google-services.jsonberada di direktoriandroid/app/. - Pastikan plugin
com.google.gms.google-servicestelah ditambahkan dengan benar di kedua filebuild.gradleseperti yang dijelaskan di atas. - Coba
flutter cleanlaluflutter pub getdan bangun ulang aplikasi.
2. Error di iOS: Aplikasi Crash atau Gagal Login Tanpa Pesan Jelas
- Penyebab: Seringkali terkait dengan konfigurasi URL Schemes atau Bundle ID yang salah di Xcode.
- Solusi:
- Pastikan “Bundle Identifier” di Google Cloud Console untuk kredensial iOS sama persis dengan “Bundle ID” di Xcode (General > Identity).
- Verifikasi “Reverse Client ID” di “URL Schemes” Xcode. Pastikan tidak ada typo dan formatnya benar-benar terbalik dari Client ID Anda.
- Coba bersihkan build folder di Xcode (Product > Clean Build Folder) lalu bangun ulang.
3. “API Not Enabled” Saat Login
- Penyebab: Anda lupa mengaktifkan “Google Sign-In API” atau “Google People API” di Google Cloud Console.
- Solusi: Kembali ke Google Cloud Console, navigasi ke “APIs & Services” > “Enabled APIs & Services”, dan pastikan API yang relevan sudah diaktifkan.
4. Tidak Bisa Login dengan Akun Tertentu (Developer Only)
- Penyebab: Jika aplikasi Anda di Google Cloud Console masih dalam status “Testing”, hanya “Test Users” yang terdaftar di OAuth Consent Screen yang bisa login.
- Solusi:
- Tambahkan akun Google Anda sebagai “Test User” di OAuth Consent Screen.
- Atau, publikasikan aplikasi Anda ke status “In Production” setelah melewati proses verifikasi Google.
5. Tidak Mendapatkan Informasi User Profile (Nama, Foto)
- Penyebab: Scope yang diminta tidak mencakup informasi profil atau Anda lupa meminta scope yang diperlukan.
- Solusi: Pastikan Anda telah menyertakan scope seperti
'email'dan'profile'dalam inisialisasiGoogleSignIn:GoogleSignIn _googleSignIn = GoogleSignIn( scopes: [ 'email', 'profile', // Pastikan ini ada // ... scope lainnya ], );
Pengalaman dan Pertimbangan Praktis
Sebagai developer yang sering berurusan dengan integrasi login, ada beberapa hal yang perlu Anda pertimbangkan di luar sekadar implementasi dasar:
Keamanan Token dan Backend Integration
Dalam praktiknya, seringkali Anda tidak hanya ingin login di sisi klien (aplikasi Flutter) saja, tetapi juga ingin memverifikasi login tersebut di backend Anda. Setelah pengguna berhasil login dengan Google di Flutter, Anda akan mendapatkan GoogleSignInAuthentication yang berisi accessToken dan idToken.
idToken: Ini adalah JSON Web Token (JWT) yang bisa Anda kirim ke backend Anda. Backend kemudian dapat memverifikasiidTokenini menggunakan Google Auth Library untuk memastikan keasliannya dan mendapatkan informasi dasar pengguna. Ini adalah cara paling aman untuk otentikasi di backend.accessToken: Ini digunakan untuk mengakses Google APIs atas nama pengguna (misalnya, Google Calendar, Google Drive) jika Anda meminta scope yang sesuai.
Penting: Jangan pernah percaya otentikasi hanya dari sisi klien. Selalu verifikasi idToken di backend Anda untuk mencegah serangan.
User Experience (UX)
- Seamless Experience: Gunakan
signInSilently()agar pengguna yang sudah pernah login tidak perlu login ulang setiap kali membuka aplikasi. - Loading State: Tunjukkan indikator loading saat proses login sedang berjalan. Otentikasi melibatkan komunikasi jaringan, jadi ada potensi jeda.
- Error Handling: Jangan biarkan aplikasi crash. Tampilkan pesan yang ramah pengguna jika terjadi error, misalnya “Gagal login dengan Google, coba lagi nanti.”
Multi-Platform Considerations
Meskipun plugin google_sign_in dirancang untuk multi-platform, konfigurasi di Google Cloud Console dan file project (Gradle untuk Android, Xcode untuk iOS) tetap memerlukan perhatian ekstra. Selalu uji di kedua platform secara menyeluruh.
Dampak Terhadap Performansi dan Ukuran Aplikasi
Plugin google_sign_in cukup ringan dan tidak akan secara signifikan membebani performa atau ukuran aplikasi Anda. Namun, selalu bijak dalam menambahkan dependency.
FAQ
Apakah saya wajib memiliki backend untuk menggunakan Google Sign-In?
Tidak wajib jika aplikasi Anda sepenuhnya berbasis klien dan tidak memerlukan data pengguna yang disimpan di server. Namun, sangat disarankan untuk memiliki backend dan memverifikasi idToken di sana untuk keamanan dan untuk menyimpan data pengguna yang persisten.
Bagaimana cara mendapatkan informasi profil pengguna setelah login?
Setelah pengguna berhasil login, Anda bisa mengakses _currentUser!.displayName, _currentUser!.email, dan _currentUser!.photoUrl dari objek GoogleSignInAccount. Pastikan scope 'profile' dan 'email' diminta saat inisialisasi GoogleSignIn.
Bisakah saya menggunakan Google Sign-In untuk otentikasi ke Firebase?
Ya, Google Sign-In adalah metode otentikasi yang sangat populer untuk Firebase. Setelah berhasil login dengan google_sign_in, Anda bisa mendapatkan idToken dari GoogleSignInAuthentication, lalu menggunakannya untuk membuat kredensial Firebase: FirebaseAuth.instance.signInWithCredential(GoogleAuthProvider.credential(idToken: auth.idToken, accessToken: auth.accessToken)).
Apa perbedaan antara Client ID Android, iOS, dan Web Application?
Setiap Client ID dibuat untuk platform spesifik dengan tujuan keamanan. Client ID Android menggunakan package name dan SHA-1 untuk identifikasi, sementara iOS menggunakan Bundle ID. Client ID Web Application biasanya tidak terkait langsung dengan aplikasi mobile, melainkan untuk server backend yang perlu memverifikasi token atau berinteraksi dengan Google APIs.
Apakah saya bisa mengganti logo aplikasi atau nama yang muncul di layar persetujuan Google?
Tentu. Anda bisa mengedit “App logo” dan “App name” di “OAuth consent screen” pada Google Cloud Console.
Kesimpulan
Integrasi Google Sign-In di Flutter memang melibatkan beberapa langkah konfigurasi di Google Cloud Console dan di project Flutter itu sendiri. Namun, dengan panduan yang tepat, proses ini menjadi jauh lebih mudah dan hasilnya sangat bermanfaat bagi aplikasi Anda. Kita sudah membahas dari persiapan awal, detail konfigurasi Android dan iOS, hingga implementasi kode dasar dan cara mengatasi masalah umum.
Ingat, selalu prioritaskan keamanan dengan memverifikasi token di backend jika aplikasi Anda memerlukannya. Dengan Google Sign-In, Anda tidak hanya menyederhanakan proses otentikasi, tetapi juga memberikan pengalaman yang familier dan tepercaya bagi pengguna Anda. Selamat mencoba, dan semoga aplikasi Flutter Anda semakin powerful!
TAGS: Flutter, Google Sign-In, Android, iOS, Firebase, Autentikasi, Tutorial, Developer Tools, Coding, Mobile Development


