1. Sebelum memulai
Dalam codelab ini, Anda akan mempelajari cara menambahkan Firebase Authentication ke aplikasi Flutter menggunakan paket UI FlutterFire. Dengan paket ini, Anda akan menambahkan autentikasi email dan sandi serta autentikasi Login dengan Google ke aplikasi Flutter. Anda juga akan mempelajari cara menyiapkan project Firebase, dan menggunakan FlutterFire CLI untuk menginisialisasi Firebase di aplikasi Flutter Anda.
Prasyarat
Codelab ini mengasumsikan bahwa Anda memiliki pengalaman menggunakan Flutter. Jika tidak, sebaiknya pelajari dasar-dasarnya terlebih dahulu. Link berikut akan membantu:
- Ikuti Tur Framework Widget Flutter
- Coba ikuti codelab Menulis Aplikasi Flutter Pertama Anda, bagian 1
Anda juga harus memiliki beberapa pengalaman Firebase, tetapi tidak masalah jika Anda belum pernah menambahkan Firebase ke project Flutter. Jika Anda belum memahami Firebase console, atau Anda benar-benar baru mengenal Firebase, lihat link berikut terlebih dahulu:
Yang akan Anda buat
Codelab ini memandu Anda dalam membangun alur autentikasi untuk aplikasi Flutter, menggunakan Firebase untuk Autentikasi. Aplikasi akan memiliki layar login, layar 'Daftar', layar pemulihan sandi, dan layar profil pengguna.
Yang akan Anda pelajari
Codelab ini mencakup:
- Menambahkan Firebase ke aplikasi Flutter
- Penyiapan Firebase Console
- Menggunakan Firebase CLI untuk menambahkan Firebase ke aplikasi Anda
- Menggunakan FlutterFire CLI untuk membuat konfigurasi Firebase di Dart
- Menambahkan Firebase Authentication ke aplikasi Flutter
- Penyiapan Firebase Authentication di konsol
- Menambahkan login dengan Email dan Sandi menggunakan paket
firebase_ui_auth
- Menambahkan pendaftaran pengguna dengan paket
firebase_ui_auth
- Menambahkan halaman 'Lupa sandi?'
- Menambahkan Login dengan Google dengan
firebase_ui_auth
- Mengonfigurasi aplikasi Anda agar berfungsi dengan beberapa penyedia login.
- Menambahkan layar profil pengguna ke aplikasi Anda dengan paket
firebase_ui_auth
Codelab ini secara khusus membahas penambahan sistem Autentikasi yang andal menggunakan paket firebase_ui_auth
. Seperti yang akan Anda lihat, seluruh aplikasi ini, dengan semua fitur di atas, dapat diimplementasikan dengan sekitar 100 baris kode.
Yang Anda butuhkan
- Pengetahuan dasar tentang Flutter, dan SDK yang diinstal
- Editor teks (JetBrains IDE, Android Studio, dan VS Code didukung oleh Flutter)
- Browser Google Chrome, atau target pengembangan pilihan Anda lainnya untuk Flutter. (Beberapa perintah terminal dalam codelab ini akan mengasumsikan bahwa Anda menjalankan aplikasi di Chrome)
2. Membuat dan menyiapkan project Firebase
Tugas pertama yang harus Anda selesaikan adalah membuat project Firebase di konsol web Firebase.
Membuat project Firebase
- Login ke Firebase console menggunakan Akun Google Anda.
- Klik tombol untuk membuat project baru, lalu masukkan nama project (misalnya,
FlutterFire-UI-Codelab
).
- Klik Lanjutkan.
- Jika diminta, tinjau dan setujui persyaratan Firebase, lalu klik Continue.
- (Opsional) Aktifkan bantuan AI di Firebase console (disebut "Gemini di Firebase").
- Untuk codelab ini, Anda tidak memerlukan Google Analytics, jadi nonaktifkan opsi Google Analytics.
- Klik Buat project, tunggu hingga project Anda disediakan, lalu klik Lanjutkan.
Untuk mempelajari lebih lanjut project Firebase, lihat Memahami project Firebase.
Mengaktifkan login email untuk Firebase Authentication
Aplikasi yang Anda buat menggunakan Firebase Authentication untuk memungkinkan pengguna login ke aplikasi Anda. Aplikasi ini juga memungkinkan pengguna baru mendaftar dari aplikasi Flutter.
Firebase Authentication harus diaktifkan menggunakan Firebase Console, dan memerlukan konfigurasi khusus setelah diaktifkan.
Untuk mengizinkan pengguna login ke aplikasi web, Anda harus menggunakan metode login Email/Sandi terlebih dahulu. Nanti, Anda akan menambahkan metode Login dengan Google.
- Di Firebase console, luaskan menu Build di panel kiri.
- Klik Authentication, lalu klik tombol Get Started, lalu tab Sign-in method (atau langsung buka tab Sign-in method).
- Klik Email/Password di daftar Sign-in providers, setel tombol akses Enable ke posisi aktif, lalu klik Save.
3. Menyiapkan aplikasi Flutter
Anda harus mendownload kode awal dan menginstal Firebase CLI sebelum kita memulai.
Mendapatkan kode awal
Clone repositori GitHub dari command line:
git clone https://github.com/flutter/codelabs.git flutter-codelabs
Atau, jika Anda telah menginstal alat CLI GitHub:
gh repo clone flutter/codelabs flutter-codelabs
Kode contoh harus di-clone ke direktori flutter-codelabs
di komputer Anda, yang berisi kode untuk kumpulan codelab. Kode untuk codelab ini ada di subdirektori flutter-codelabs/firebase-auth-flutterfire-ui
.
Direktori flutter-codelabs/firebase-auth-flutterfire-ui
berisi dua project Flutter. Satu disebut complete
dan yang lainnya disebut start
. Direktori start
berisi project yang tidak lengkap, dan di sinilah Anda akan menghabiskan sebagian besar waktu.
cd flutter-codelabs/firebase-auth-flutterfire-ui/start
Jika Anda ingin melompat ke depan, atau melihat seperti apa tampilan sesuatu saat selesai, lihat di direktori bernama complete untuk melakukan referensi silang.
Jika ingin mengikuti codelab dan menambahkan kode sendiri, Anda harus memulai dengan aplikasi Flutter di flutter-codelabs/firebase-auth-flutterfire-ui/start
, dan menambahkan kode ke project tersebut selama codelab. Buka atau impor direktori tersebut ke IDE pilihan Anda.
Instal Firebase CLI
Firebase CLI menyediakan alat untuk mengelola project Firebase Anda. CLI diperlukan untuk FlutterFire CLI, yang akan Anda instal sebentar lagi.
Ada berbagai cara untuk menginstal CLI. Tinjau semua opsi yang tersedia untuk sistem operasi Anda di firebase.google.com/docs/cli.
Setelah menginstal CLI, Anda harus melakukan autentikasi dengan Firebase.
- Login ke Firebase menggunakan Akun Google Anda dengan menjalankan perintah berikut:
firebase login
- Perintah ini menghubungkan komputer lokal Anda ke Firebase dan memberikan akses ke project Firebase Anda.
- Uji untuk memastikan bahwa CLI sudah diinstal dengan benar dan memiliki akses ke akun Anda dengan mencantumkan project Firebase Anda. Jalankan perintah berikut:
firebase projects:list
- Daftar yang ditampilkan harus sama dengan project Firebase yang tercantum di Firebase console. Anda akan melihat setidaknya
flutterfire-ui-codelab.
Instal FlutterFire CLI
FlutterFire CLI adalah alat yang membantu mempermudah proses penginstalan Firebase di semua platform yang didukung di aplikasi Flutter Anda. Alat ini dibangun di atas Firebase CLI.
Pertama, instal CLI:
dart pub global activate flutterfire_cli
Pastikan CLI telah diinstal. Jalankan perintah berikut dan pastikan CLI menampilkan menu bantuan.
flutterfire --help
Menambahkan project Firebase ke aplikasi Flutter Anda
Mengonfigurasi FlutterFire
Anda dapat menggunakan FlutterFire untuk membuat kode Dart yang diperlukan untuk menggunakan Firebase di aplikasi Flutter Anda.
flutterfire configure
Saat perintah ini dijalankan, Anda akan diminta untuk memilih project Firebase yang ingin digunakan, dan platform yang ingin disiapkan.
Screenshot berikut menunjukkan perintah yang harus Anda jawab.
- Pilih project yang ingin Anda gunakan. Dalam hal ini, gunakan
flutterfire-ui-codelab
- Pilih platform yang ingin Anda gunakan. Dalam codelab ini, ada langkah-langkah untuk mengonfigurasi Firebase Authentication untuk Flutter untuk web, iOS, dan Android, tetapi Anda dapat menyiapkan project Firebase untuk menggunakan semua opsi.
- Screenshot ini menunjukkan output di akhir proses. Jika sudah terbiasa dengan Firebase, Anda akan melihat bahwa Anda tidak perlu membuat aplikasi platform (misalnya, aplikasi Android) di konsol, dan FlutterFire CLI melakukannya untuk Anda.
Setelah selesai, lihat aplikasi Flutter di editor teks Anda. FlutterFire CLI telah mengubah file bernama firebase_options.dart
. File ini berisi class bernama FirebaseOptions
, yang memiliki variabel statis yang menyimpan konfigurasi Firebase yang diperlukan untuk setiap platform. Jika Anda memilih semua platform saat menjalankan flutterfire configure
, Anda akan melihat nilai statis bernama web
, android
, ios
, dan macos
.
lib/firebase_options.dart
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
return web;
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
return macos;
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyCqFjCV_9CZmYeIvcK9FVy4drmKUlSaIWY',
appId: '1:963656261848:web:7219f7fca5fc70afb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
authDomain: 'flutterfire-ui-codelab.firebaseapp.com',
storageBucket: 'flutterfire-ui-codelab.firebasestorage.app',
measurementId: 'G-DGF0CP099H',
);
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyDconZaCQpkxIJ5KQBF-3tEU0rxYsLkIe8',
appId: '1:963656261848:android:c939ccc86ab2dcdbb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
storageBucket: 'flutterfire-ui-codelab.firebasestorage.app',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyBqLWsqFjYAdGyihKTahMRDQMo0N6NVjAs',
appId: '1:963656261848:ios:d9e01cfe8b675dfcb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
storageBucket: 'flutterfire-ui-codelab.firebasestorage.app',
iosClientId: '963656261848-v7r3vq1v6haupv0l1mdrmsf56ktnua60.apps.googleusercontent.com',
iosBundleId: 'com.example.complete',
);
static const FirebaseOptions macos = FirebaseOptions(
apiKey: 'AIzaSyBqLWsqFjYAdGyihKTahMRDQMo0N6NVjAs',
appId: '1:963656261848:ios:d9e01cfe8b675dfcb237ad',
messagingSenderId: '963656261848',
projectId: 'flutterfire-ui-codelab',
storageBucket: 'flutterfire-ui-codelab.firebasestorage.app',
iosClientId: '963656261848-v7r3vq1v6haupv0l1mdrmsf56ktnua60.apps.googleusercontent.com',
iosBundleId: 'com.example.complete',
);
}
Firebase menggunakan kata aplikasi untuk merujuk pada build tertentu untuk platform tertentu dalam project Firebase. Misalnya, project Firebase yang disebut FlutterFire-ui-codelab memiliki beberapa aplikasi: satu untuk Android, satu untuk iOS, satu untuk macOS, dan satu untuk Web.
Metode DefaultFirebaseOptions.currentPlatform
menggunakan enum TargetPlatform
yang diekspos oleh Flutter untuk mendeteksi platform tempat aplikasi Anda berjalan, lalu menampilkan nilai konfigurasi Firebase yang diperlukan untuk aplikasi Firebase yang benar.
Menambahkan paket Firebase ke aplikasi Flutter
Langkah penyiapan terakhir adalah menambahkan paket Firebase yang relevan ke project Flutter Anda. File firebase_options.dart
akan memiliki error, karena bergantung pada paket Firebase yang belum ditambahkan. Di terminal, pastikan Anda berada di root project Flutter di flutter-codelabs/firebase-emulator-suite/start
. Kemudian, jalankan tiga perintah berikut:
flutter pub add firebase_core firebase_auth firebase_ui_auth
Ini adalah satu-satunya paket yang Anda butuhkan saat ini.
Melakukan inisialisasi Firebase
Untuk menggunakan paket yang ditambahkan, dan DefaultFirebaseOptions.currentPlatform,
, perbarui kode di fungsi main
dalam file main.dart
.
lib/main.dart
import 'package:firebase_core/firebase_core.dart'; // Add this import
import 'package:flutter/material.dart';
import 'app.dart';
import 'firebase_options.dart'; // And this import
// TODO(codelab user): Get API key
const clientId = 'YOUR_CLIENT_ID';
void main() async {
// Add from here...
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
// To here.
runApp(const MyApp(clientId: clientId));
}
Kode ini melakukan dua hal.
WidgetsFlutterBinding.ensureInitialized()
memberi tahu Flutter untuk tidak mulai menjalankan kode widget aplikasi hingga framework Flutter selesai di-boot. Firebase menggunakan saluran platform native, yang mengharuskan framework berjalan.Firebase.initializeApp
menyiapkan koneksi antara aplikasi Flutter dan project Firebase Anda.DefaultFirebaseOptions.currentPlatform
diimpor dari filefirebase_options.dart
yang dihasilkan. Nilai statis ini mendeteksi platform yang Anda gunakan, dan meneruskan kunci Firebase yang sesuai.
4. Menambahkan halaman Firebase UI Auth awal
Firebase UI for Auth menyediakan widget yang merepresentasikan seluruh layar di aplikasi Anda. Layar ini menangani berbagai alur autentikasi di seluruh aplikasi Anda, seperti Login, Pendaftaran, Lupa Sandi, Profil Pengguna, dan lainnya. Untuk memulai, tambahkan halaman landing ke aplikasi Anda yang berfungsi sebagai penjaga autentikasi ke aplikasi utama.
Aplikasi Material atau Cupertino
UI FlutterFire mewajibkan aplikasi Anda di-wrap dalam MaterialApp
atau CupertinoApp
. Bergantung pada pilihan Anda, UI akan otomatis mencerminkan perbedaan widget Material atau Cupertino. Untuk codelab ini, gunakan MaterialApp
, yang sudah ditambahkan ke aplikasi di app.dart
.
lib/app.dart
import 'package:flutter/material.dart';
import 'auth_gate.dart';
class MyApp extends StatelessWidget {
const MyApp({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: AuthGate(clientId: clientId),
);
}
}
Memeriksa status autentikasi
Sebelum dapat menampilkan layar login, Anda harus menentukan apakah pengguna diautentikasi. Cara paling umum untuk memeriksa hal ini adalah dengan memproses authStateChanges
dari FirebaseAuth
menggunakan plugin Firebase Auth.
Dalam contoh kode di atas, MaterialApp
sedang membuat widget AuthGate
dalam metode build
-nya. (Ini adalah widget kustom, bukan disediakan oleh FlutterFire UI.)
Widget tersebut perlu diupdate untuk menyertakan streaming authStateChanges
.
API authStateChanges
menampilkan Stream
dengan pengguna saat ini (jika mereka login), atau null jika mereka tidak login. Untuk berlangganan status ini di aplikasi, Anda dapat menggunakan widget StreamBuilder Flutter dan meneruskan stream ke widget tersebut.
StreamBuilder
adalah widget yang membangun dirinya sendiri berdasarkan snapshot data terbaru dari Stream yang Anda teruskan. Widget ini otomatis dibangun kembali saat Stream
memunculkan snapshot baru.
Perbarui kode di auth_gate.dart
.
lib/auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider; // Add this import
import 'package:firebase_ui_auth/firebase_ui_auth.dart'; // And this import
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>( // Modify from here...
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(providers: []);
}
return const HomeScreen();
},
); // To here.
}
}
StreamBuilder.stream
meneruskanFirebaseAuth.instance.authStateChanged
, yaitu stream yang disebutkan di atas, yang akan menampilkan objekUser
Firebase jika pengguna telah diautentikasi, atau akan menampilkannull
.- Selanjutnya, kode menggunakan
snapshot.hasData
untuk memeriksa apakah nilai dari stream berisi objekUser
. - Jika tidak ada, widget
SignInScreen
akan ditampilkan. Untuk saat ini, layar ini tidak akan melakukan apa pun, dan akan diperbarui di langkah berikutnya. - Jika tidak, aplikasi akan menampilkan
HomeScreen
, yang merupakan bagian utama aplikasi yang hanya dapat diakses oleh pengguna terautentikasi.
SignInScreen
adalah widget yang berasal dari paket UI FlutterFire. Ini akan menjadi fokus langkah berikutnya dalam codelab ini. Saat menjalankan aplikasi pada tahap ini, Anda akan melihat layar login kosong.
5. Layar Login
Widget SignInScreen
, yang disediakan oleh FlutterFire UI, menambahkan fungsi berikut:
- Mengizinkan pengguna login
- Jika pengguna lupa sandi mereka, mereka dapat mengetuk "Lupa sandi?" dan diarahkan ke formulir untuk mereset sandi mereka
- Jika pengguna belum terdaftar, mereka dapat mengetuk "Daftar", dan diarahkan ke formulir lain yang memungkinkan mereka mendaftar.
Sekali lagi, ini hanya memerlukan beberapa baris kode. Panggil kembali kode di widget AuthGate
:
lib/auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(providers: [EmailAuthProvider()]); // Modify this line
}
return const HomeScreen();
},
);
}
}
Widget SignInScreen
, dan argumen providers
-nya, adalah satu-satunya kode yang diperlukan untuk mendapatkan semua fungsi yang disebutkan di atas. Sekarang Anda akan melihat layar login yang memiliki input teks 'email' dan 'sandi', serta tombol 'Login'.
Meskipun berfungsi, tidak ada gaya. Widget ini mengekspos parameter untuk menyesuaikan tampilan layar login. Misalnya, Anda mungkin ingin menambahkan logo perusahaan Anda.
Menyesuaikan Layar login
headerBuilder
Dengan menggunakan argumen SignInScreen.headerBuilder
, Anda dapat menambahkan widget apa pun yang Anda inginkan di atas formulir login. Widget ini hanya ditampilkan di layar sempit, seperti perangkat seluler. Di layar lebar, Anda dapat menggunakan SignInScreen.sideBuilder
, yang akan dibahas nanti dalam codelab ini.
Perbarui file lib/auth_gate.dart
dengan kode ini:
lib/auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen( // Modify from here...
providers: [EmailAuthProvider()],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('assets/flutterfire_300x.png'),
),
);
},
); // To here.
}
return const HomeScreen();
},
);
}
}```
The headerBuilder argument requires a function of the type HeaderBuilder, which
is defined in the FlutterFire UI package.
```dart
typedef HeaderBuilder = Widget Function(
BuildContext context,
BoxConstraints constraints,
double shrinkOffset,
);
Karena merupakan callback, fungsi ini menampilkan nilai yang dapat Anda gunakan, seperti BuildContext
dan BoxConstraints
, dan mengharuskan Anda menampilkan widget. Widget apa pun yang Anda kembalikan akan ditampilkan di bagian atas layar. Dalam contoh ini, kode baru menambahkan gambar ke bagian atas layar. Aplikasi Anda sekarang akan terlihat seperti ini.
Pembuat Subtitel
Layar login menampilkan tiga parameter tambahan yang memungkinkan Anda menyesuaikan layar: subtitleBuilder
, footerBuilder
, dan sideBuilder
.
subtitleBuilder
sedikit berbeda karena argumen callback mencakup tindakan, yang berjenis AuthAction
. AuthAction
adalah enum yang dapat Anda gunakan untuk mendeteksi apakah layar yang sedang dilihat pengguna adalah layar "login" atau layar "daftar".
Perbarui kode di auth_gate.dart untuk menggunakan subtitleBuilder
.
lib/auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [EmailAuthProvider()],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('assets/flutterfire_300x.png'),
),
);
},
subtitleBuilder: (context, action) { // Add from here...
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: action == AuthAction.signIn
? const Text('Welcome to FlutterFire, please sign in!')
: const Text('Welcome to Flutterfire, please sign up!'),
);
}, // To here.
);
}
return const HomeScreen();
},
);
}
}
Pembuat footer
Argumen footerBuilder sama dengan subtitleBuilder. API ini tidak mengekspos BoxConstraints
atau shrinkOffset
, karena ditujukan untuk teks, bukan gambar. Tentu saja, Anda dapat menambahkan widget apa pun yang Anda inginkan.
Tambahkan footer ke layar login Anda dengan kode ini.
lib/auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [EmailAuthProvider()],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('assets/flutterfire_300x.png'),
),
);
},
subtitleBuilder: (context, action) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: action == AuthAction.signIn
? const Text('Welcome to FlutterFire, please sign in!')
: const Text('Welcome to Flutterfire, please sign up!'),
);
},
footerBuilder: (context, action) { // Add from here...
return const Padding(
padding: EdgeInsets.only(top: 16),
child: Text(
'By signing in, you agree to our terms and conditions.',
style: TextStyle(color: Colors.grey),
),
);
}, // To here.
);
}
return const HomeScreen();
},
);
}
}
Side Builder
Argumen SignInScreen.sidebuilder menerima callback, dan kali ini argumen untuk callback tersebut adalah BuildContext
dan double shrinkOffset
. Widget yang ditampilkan oleh sideBuilder
akan ditampilkan di sebelah kiri formulir login, dan hanya pada layar lebar. Artinya, widget hanya akan ditampilkan di desktop dan aplikasi web.
Secara internal, UI FlutterFire menggunakan titik henti sementara untuk menentukan apakah konten header harus ditampilkan (di layar tinggi, seperti seluler) atau konten samping harus ditampilkan (di layar lebar, desktop, atau web). Secara khusus, jika layar memiliki lebar lebih dari 800 piksel, konten pembuat sisi akan ditampilkan, dan konten header tidak akan ditampilkan. Jika layar memiliki lebar kurang dari 800 piksel, maka sebaliknya.
Perbarui kode di auth_gate.dart untuk menambahkan widget sideBuilder
.
lib/auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [EmailAuthProvider()],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('assets/flutterfire_300x.png'),
),
);
},
subtitleBuilder: (context, action) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: action == AuthAction.signIn
? const Text('Welcome to FlutterFire, please sign in!')
: const Text('Welcome to Flutterfire, please sign up!'),
);
},
footerBuilder: (context, action) {
return const Padding(
padding: EdgeInsets.only(top: 16),
child: Text(
'By signing in, you agree to our terms and conditions.',
style: TextStyle(color: Colors.grey),
),
);
},
sideBuilder: (context, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('flutterfire_300x.png'),
),
);
},
);
}
return const HomeScreen();
},
);
}
}
Aplikasi Anda sekarang akan terlihat seperti ini saat Anda memperluas lebar jendela (jika Anda menggunakan Flutter web atau MacOS).
Membuat pengguna
Pada tahap ini, semua kode untuk layar ini telah selesai. Namun, sebelum dapat login, Anda harus membuat Pengguna. Anda dapat melakukannya dengan layar "Daftar", atau Anda dapat membuat pengguna di Firebase console.
Untuk menggunakan konsol:
- Buka tabel"Pengguna" di Firebase console. Pilih ‘flutterfire-ui-codelab', atau project lain jika Anda menggunakan nama yang berbeda. Anda akan melihat tabel ini:
- Klik tombol "Tambahkan pengguna".
- Masukkan alamat email dan sandi untuk pengguna baru. Ini bisa berupa email dan sandi palsu, seperti yang telah saya masukkan dalam gambar di bawah. Cara ini akan berhasil, tetapi fungsi "Lupa sandi" tidak akan berfungsi jika Anda menggunakan alamat email palsu.
- Klik "Tambahkan pengguna"
Sekarang, Anda dapat kembali ke aplikasi Flutter, dan login pengguna menggunakan halaman login. Aplikasi Anda akan terlihat seperti ini:
6. Layar Profil
UI FlutterFire juga menyediakan widget ProfileScreen
, yang sekali lagi, memberi Anda banyak fungsi hanya dalam beberapa baris kode.
Menambahkan widget ProfileScreen
Buka file home.dart
di editor teks Anda. Perbarui dengan kode ini:
lib/home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => const ProfileScreen(),
),
);
},
),
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
SizedBox(width: 250, child: Image.asset('assets/dash.png')),
Text('Welcome!', style: Theme.of(context).textTheme.displaySmall),
const SignOutButton(),
],
),
),
);
}
}
Kode baru yang perlu diperhatikan adalah callback yang diteruskan ke metode IconButton.isPressed
. Saat IconButton
tersebut ditekan, aplikasi Anda akan membuat rute anonim baru dan menavigasi ke rute tersebut. Rute tersebut akan menampilkan widget ProfileScreen
, yang ditampilkan dari callback MaterialPageRoute.builder
.
Muat ulang aplikasi Anda, lalu tekan ikon di kanan atas (di panel aplikasi), dan halaman seperti ini akan ditampilkan:
Ini adalah UI standar yang disediakan oleh halaman UI FlutterFire. Semua tombol dan kolom teks terhubung ke Firebase Auth, dan langsung berfungsi. Misalnya, Anda dapat memasukkan nama ke dalam kolom teks "Name", dan UI FlutterFire akan memanggil metode FirebaseAuth.instance.currentUser?.updateDisplayName
, yang akan menyimpan nama tersebut di Firebase.
Logout
Saat ini, jika Anda menekan tombol "Logout", aplikasi tidak akan berubah. Anda akan logout, tetapi Anda tidak akan dialihkan kembali ke widget AuthGate. Untuk mengimplementasikannya, gunakan parameter ProfileScreen.actions.
Pertama, perbarui kode di home.dart.
lib/home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => ProfileScreen(
actions: [
SignedOutAction((context) {
Navigator.of(context).pop();
}),
],
),
),
);
},
),
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
SizedBox(width: 250, child: Image.asset('assets/dash.png')),
Text('Welcome!', style: Theme.of(context).textTheme.displaySmall),
const SignOutButton(),
],
),
),
);
}
}
Sekarang, saat membuat instance ProfileScreen
, Anda juga meneruskan daftar tindakan ke argumen ProfileScreen.actions
. Tindakan ini adalah jenis FlutterFireUiAction
. Ada banyak class berbeda yang merupakan subjenis FlutterFireUiAction
, dan secara umum Anda menggunakannya untuk memberi tahu aplikasi agar bereaksi terhadap berbagai perubahan status autentikasi. SignedOutAction memanggil fungsi callback yang Anda berikan saat status auth Firebase berubah menjadi currentUser menjadi null.
Dengan menambahkan callback yang memanggil Navigator.of(context).pop()
saat SignedOutAction
dipicu, aplikasi akan membuka halaman sebelumnya. Dalam aplikasi contoh ini, hanya ada satu rute permanen, yang menampilkan layar Login jika tidak ada pengguna yang login, dan halaman beranda jika ada pengguna. Karena hal ini terjadi saat pengguna logout, aplikasi akan menampilkan layar Login.
Menyesuaikan Halaman Profil
Mirip dengan layar Login, halaman profil dapat disesuaikan. Pertama, halaman saat ini tidak memiliki cara untuk kembali ke halaman beranda setelah pengguna berada di halaman profil. Perbaiki hal ini dengan memberi widget ProfileScreen AppBar.
lib/home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => ProfileScreen(
appBar: AppBar(title: const Text('User Profile')),
actions: [
SignedOutAction((context) {
Navigator.of(context).pop();
}),
],
),
),
);
},
),
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
SizedBox(width: 250, child: Image.asset('assets/dash.png')),
Text('Welcome!', style: Theme.of(context).textTheme.displaySmall),
const SignOutButton(),
],
),
),
);
}
}
Argumen ProfileScreen.appBar
menerima widget AppBar
dari paket Material Flutter, sehingga dapat diperlakukan seperti AppBar
lain yang telah Anda buat dan diteruskan ke Scaffold
. Dalam contoh ini, fungsi default untuk menambahkan tombol "kembali" secara otomatis tetap dipertahankan, dan layar kini memiliki judul.
Menambahkan Anak ke Layar Profil
Widget ProfileScreen
juga memiliki argumen opsional bernama children. Argumen ini menerima daftar widget, dan widget tersebut akan ditempatkan secara vertikal di dalam widget Column
yang sudah digunakan secara internal untuk membangun ProfileScreen
. Widget Column
ini dalam metode build ProfileScreen
akan menempatkan turunan yang Anda teruskan di atas tombol "Logout".
Perbarui kode di home.dart
untuk menampilkan logo perusahaan di sini, mirip dengan layar Login.
lib/home.dart
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: const Icon(Icons.person),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute<ProfileScreen>(
builder: (context) => ProfileScreen(
appBar: AppBar(title: const Text('User Profile')),
actions: [
SignedOutAction((context) {
Navigator.of(context).pop();
}),
],
children: [
const Divider(),
Padding(
padding: const EdgeInsets.all(2),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('flutterfire_300x.png'),
),
),
],
),
),
);
},
),
],
automaticallyImplyLeading: false,
),
body: Center(
child: Column(
children: [
SizedBox(width: 250, child: Image.asset('assets/dash.png')),
Text('Welcome!', style: Theme.of(context).textTheme.displaySmall),
const SignOutButton(),
],
),
),
);
}
}
Muat ulang aplikasi, dan Anda akan melihat ini di layar:
7. Login dengan Google Auth Multiplatform
UI FlutterFire juga menyediakan widget dan fungsi untuk mengautentikasi dengan penyedia pihak ketiga, seperti Google, Twitter, Facebook, Apple, dan GitHub.
Untuk berintegrasi dengan autentikasi Google, instal plugin firebase_ui_oauth_google resmi dan dependensinya, yang akan menangani alur autentikasi native. Di terminal, buka root project Flutter Anda dan masukkan perintah berikut:
flutter pub add google_sign_in firebase_ui_oauth_google
Mengaktifkan Penyedia Login dengan Google
Selanjutnya, aktifkan penyedia Google di Firebase Console:
- Buka layar Penyedia login autentikasi di konsol.
- Klik "Tambahkan penyedia baru".
- Pilih "Google".
- Alihkan tombol berlabel "Aktifkan", lalu tekan "Simpan".
- Jika muncul modal dengan informasi tentang mendownload file konfigurasi, klik "Selesai".
- Konfirmasi bahwa penyedia login dengan Google telah ditambahkan.
Menambahkan tombol login dengan Google
Dengan login dengan Google diaktifkan, tambahkan widget yang diperlukan untuk menampilkan tombol login dengan Google yang bergaya ke layar login. Buka file auth_gate.dart
dan perbarui kode menjadi berikut:
lib/auth_gate.dart
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';
import 'package:firebase_ui_oauth_google/firebase_ui_oauth_google.dart'; // Add this import
import 'package:flutter/material.dart';
import 'home.dart';
class AuthGate extends StatelessWidget {
const AuthGate({super.key, required this.clientId});
final String clientId;
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return SignInScreen(
providers: [
EmailAuthProvider(),
GoogleProvider(clientId: clientId), // Add this line
],
headerBuilder: (context, constraints, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('assets/flutterfire_300x.png'),
),
);
},
subtitleBuilder: (context, action) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: action == AuthAction.signIn
? const Text('Welcome to FlutterFire, please sign in!')
: const Text('Welcome to Flutterfire, please sign up!'),
);
},
footerBuilder: (context, action) {
return const Padding(
padding: EdgeInsets.only(top: 16),
child: Text(
'By signing in, you agree to our terms and conditions.',
style: TextStyle(color: Colors.grey),
),
);
},
sideBuilder: (context, shrinkOffset) {
return Padding(
padding: const EdgeInsets.all(20),
child: AspectRatio(
aspectRatio: 1,
child: Image.asset('flutterfire_300x.png'),
),
);
},
);
}
return const HomeScreen();
},
);
}
}
Satu-satunya kode baru di sini adalah penambahan GoogleProvider(clientId: "YOUR_WEBCLIENT_ID")
ke konfigurasi widget SignInScreen
.
Setelah ditambahkan, muat ulang aplikasi, dan Anda akan melihat tombol login dengan Google.
Mengonfigurasi tombol login
Tombol tidak berfungsi tanpa konfigurasi tambahan. Jika Anda mengembangkan dengan Flutter Web, ini adalah satu-satunya langkah yang harus Anda tambahkan agar dapat berfungsi. Platform lain memerlukan langkah tambahan, yang akan dibahas sebentar lagi.
- Buka halaman Penyedia autentikasi di Firebase Console.
- Klik penyedia Google.
- Klik panel perluasan "Konfigurasi Web SDK".
- Salin nilai dari "Web client ID".
- Kembali ke editor teks Anda, dan perbarui instance
GoogleProvider
di fileauth_gate.dart
dengan meneruskan ID ini ke parameter bernamaclientId
.
GoogleProvider(
clientId: "YOUR_WEBCLIENT_ID"
)
Setelah ID klien web dimasukkan, muat ulang aplikasi Anda. Saat Anda menekan tombol "Login dengan Google", jendela baru akan muncul, jika Anda menggunakan web, yang memandu Anda melalui alur login Google. Awalnya, tampilannya seperti ini:
Mengonfigurasi iOS
Agar dapat berfungsi di iOS, ada proses konfigurasi tambahan.
- Buka layar Setelan Project di Firebase console. Akan ada kartu yang mencantumkan aplikasi Firebase Anda yang terlihat seperti ini:
- Pilih iOS. Perhatikan bahwa nama aplikasi Anda akan berbeda dengan yang ditampilkan dalam screenshot. Jika screenshot bertuliskan "selesai", screenshot Anda akan bertuliskan "mulai", jika Anda menggunakan project
flutter-codelabs/firebase-auth-flutterfire-ui/start
untuk mengikuti codelab ini. - Klik tombol yang bertuliskan
GoogleServices-Info.plist
untuk mendownload file konfigurasi yang diperlukan. - Tarik file yang didownload ke direktori bernama
/ios/Runner
di project Flutter Anda. - Buka Xcode dengan menjalankan perintah terminal berikut dari root project Anda:
open ios/Runner.xcworkspace
- Klik kanan direktori Runner, lalu pilih Tambahkan File ke "Runner".
- Pilih
GoogleService-Info.plist
dari pengelola file. - Kembali di editor teks Anda (yang bukan Xcode), tambahkan atribut
CFBundleURLTypes
di bawah ke dalam fileios/Runner/Info.plist
.<!-- Put me in the [my_project]/ios/Runner/Info.plist file --> <!-- Google Sign-in Section --> <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLSchemes</key> <array> <!-- TODO Replace this value: --> <!-- Copied from GoogleService-Info.plist key REVERSED_CLIENT_ID --> <string>com.googleusercontent.apps.861823949799-vc35cprkp249096uujjn0vvnmcvjppkn</string> </array> </dict> </array> <!-- End of the Google Sign-in Section -->
- Anda perlu mengganti
GoogleProvider.clientId
yang Anda tambahkan di penyiapan web dengan Client ID yang terkait dengan Client ID iOS Firebase Anda. Pertama, Anda dapat menemukan ID ini dalam filefirebase_options.dart
, sebagai bagian dari konstantaiOS
. Salin nilai yang diteruskan keiOSClientId
.static const FirebaseOptions ios = FirebaseOptions( apiKey: 'YOUR API KEY', appId: 'YOUR APP ID', messagingSenderId: '', projectId: 'PROJECT_ID', storageBucket: 'PROJECT_ID.firebasestorage.app', iosClientId: 'IOS CLIENT ID', // Find your iOS client Id here. iosBundleId: 'com.example.BUNDLE', );
- Tempelkan nilai tersebut ke dalam variabel
clientId
di filelib/main.dart
.
lib/main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'app.dart';
import 'firebase_options.dart';
const clientId = 'YOUR_CLIENT_ID'; // Replace this value with your Client ID.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(const MyApp(clientId: clientId));
}
Jika aplikasi Flutter Anda sudah berjalan di iOS, Anda harus menutupnya sepenuhnya, lalu menjalankan kembali aplikasi. Jika tidak, jalankan aplikasi di iOS.
8. Selamat!
Anda telah menyelesaikan codelab Firebase Auth UI untuk Flutter . Anda dapat menemukan kode lengkap untuk Codelab ini di direktori firebase-auth-flutterfire-ui/complete
di GitHub.
Yang telah kita bahas
- Menyiapkan aplikasi Flutter untuk menggunakan Firebase
- Menyiapkan project Firebase di Firebase console
- FlutterFire CLI
- Firebase CLI
- Menggunakan Firebase Authentication
- Menggunakan UI FlutterFire untuk menangani autentikasi Firebase di aplikasi Flutter Anda
Langkah Berikutnya
- Pelajari lebih lanjut cara menggunakan Firestore dan Authentication di Flutter: Codelab Kenali Firebase untuk Flutter
- Pelajari alat Firebase lainnya untuk membangun aplikasi Flutter Anda:
Pelajari lebih lanjut
- Situs Firebase: firebase.google.com
- Situs Flutter: flutter.dev
- Widget Firebase Flutter FlutterFire: firebase.flutter.dev
- Channel YouTube Firebase
- Channel YouTube Flutter
Sparky hadir untuk merayakan bersama Anda!