Pengembangan lokal untuk aplikasi Flutter Anda menggunakan Firebase Emulator Suite

1. Sebelum memulai

Dalam codelab ini, Anda akan mempelajari cara menggunakan Firebase Emulator Suite dengan Flutter selama pengembangan lokal. Anda akan mempelajari cara menggunakan autentikasi email-sandi melalui Emulator Suite, dan cara membaca serta menulis data ke emulator Firestore. Terakhir, Anda akan bekerja dengan mengimpor dan mengekspor data dari emulator, untuk bekerja dengan data palsu yang sama setiap kali Anda kembali ke pengembangan.

Prasyarat

Codelab ini mengasumsikan bahwa Anda memiliki pengalaman menggunakan Flutter. Jika tidak, sebaiknya pelajari dasar-dasarnya terlebih dahulu. Link berikut akan membantu:

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 membuat aplikasi Journaling sederhana. Aplikasi ini akan memiliki layar login, dan layar yang memungkinkan Anda membaca entri jurnal sebelumnya, dan membuat entri baru.

cd5c4753bbee8af.png 8cb4d21f656540bf.png

Yang akan Anda pelajari

Anda akan mempelajari cara mulai menggunakan Firebase, serta cara mengintegrasikan dan menggunakan Firebase Emulator Suite ke dalam alur kerja pengembangan Flutter. Topik Firebase berikut akan dibahas:

Perhatikan bahwa topik ini dibahas sejauh yang diperlukan untuk membahas rangkaian emulator Firebase. Codelab ini berfokus pada penambahan project Firebase ke aplikasi Flutter Anda, dan pengembangan menggunakan Firebase Emulator Suite. Tidak akan ada pembahasan mendalam tentang Firebase Authentication atau Firestore. Jika Anda belum memahami topik ini, sebaiknya mulai dengan codelab Kenali Firebase untuk Flutter.

Yang Anda butuhkan

  • Pengetahuan dasar tentang Flutter, dan SDK yang diinstal
  • Editor teks Intellij JetBrains atau VS Code
  • Browser Google Chrome (atau target pengembangan pilihan Anda 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. Sebagian besar codelab ini akan berfokus pada Emulator Suite, yang menggunakan UI yang berjalan secara lokal, tetapi Anda harus menyiapkan project Firebase lengkap terlebih dahulu.

Membuat project Firebase

  1. Login ke Firebase console menggunakan Akun Google Anda.
  2. Klik tombol untuk membuat project baru, lalu masukkan nama project (misalnya, Firebase-Flutter-Codelab).
  3. Klik Lanjutkan.
  4. Jika diminta, tinjau dan setujui persyaratan Firebase, lalu klik Continue.
  5. (Opsional) Aktifkan bantuan AI di Firebase console (disebut "Gemini di Firebase").
  6. Untuk codelab ini, Anda tidak memerlukan Google Analytics, jadi nonaktifkan opsi Google Analytics.
  7. Klik Buat project, tunggu hingga project Anda disediakan, lalu klik Lanjutkan.

Untuk mempelajari lebih lanjut project Firebase, lihat Memahami project Firebase.

Menyiapkan produk Firebase

Aplikasi yang Anda build menggunakan dua produk Firebase yang tersedia untuk aplikasi Flutter:

  • Firebase Authentication untuk memungkinkan pengguna login ke aplikasi Anda.
  • Cloud Firestore untuk menyimpan data terstruktur di cloud dan menerima notifikasi instan saat data berubah.

Kedua produk ini memerlukan konfigurasi khusus atau perlu diaktifkan menggunakan Firebase console.

Aktifkan Cloud Firestore

Aplikasi Flutter menggunakan Cloud Firestore untuk menyimpan entri jurnal.

Aktifkan Cloud Firestore:

  1. Di bagian Build Firebase console, klik Cloud Firestore.
  2. Klik Buat database. 99e8429832d23fa3.png
  3. Pilih opsi Start in test mode. Baca pernyataan penyangkalan tentang aturan keamanan. Mode uji memastikan bahwa Anda dapat menulis database dengan bebas selama masa pengembangan. Klik Berikutnya. 6be00e26c72ea032.png
  4. Pilih lokasi untuk database Anda (Anda cukup menggunakan default). Perhatikan bahwa lokasi ini tidak dapat diubah nanti. 278656eefcfb0216.png
  5. Klik Enable.

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, yang berisi kode untuk kumpulan codelab. Kode untuk codelab ini ada di flutter-codelabs/firebase-emulator-suite.

Struktur direktori di flutter-codelabs/firebase-emulator-suite terdiri dari dua project Flutter. Salah satunya disebut complete, yang dapat Anda lihat jika ingin melewati, atau merujuk silang kode Anda sendiri. Project lainnya disebut start.

Kode yang ingin Anda mulai ada di direktori flutter-codelabs/firebase-emulator-suite/start. Buka atau impor direktori tersebut ke IDE pilihan Anda.

cd flutter-codelabs/firebase-emulator-suite/start

Instal Firebase CLI

Firebase CLI menyediakan alat untuk mengelola project Firebase Anda. CLI diperlukan untuk menggunakan Emulator Suite, jadi Anda harus menginstalnya.

Ada berbagai cara untuk menginstal CLI. Cara paling sederhana, jika Anda menggunakan MacOS atau Linux, adalah menjalankan perintah ini dari terminal:

curl -sL https://firebase.tools | bash

Setelah menginstal CLI, Anda harus melakukan autentikasi dengan Firebase.

  1. Login ke Firebase menggunakan akun Google Anda dengan menjalankan perintah berikut:
firebase login
  1. Perintah ini menghubungkan komputer lokal Anda ke Firebase dan memberikan akses ke project Firebase Anda.
  1. 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
  1. Daftar yang ditampilkan harus sama dengan project Firebase yang tercantum di Firebase console. Anda akan melihat setidaknya firebase-flutter-codelab.

Instal FlutterFire CLI

FlutterFire CLI dibangun di atas Firebase CLI, dan memudahkan integrasi project Firebase dengan aplikasi Flutter Anda.

Pertama, instal CLI:

dart pub global activate flutterfire_cli

Pastikan CLI telah diinstal. Jalankan perintah berikut dalam direktori project Flutter dan pastikan CLI menampilkan menu bantuan.

flutterfire --help

Gunakan Firebase CLI dan FlutterFire CLI untuk menambahkan project Firebase ke aplikasi Flutter Anda

Setelah menginstal kedua CLI, Anda dapat menyiapkan setiap produk Firebase (seperti Firestore), mendownload emulator, dan menambahkan Firebase ke aplikasi Flutter hanya dengan beberapa perintah terminal.

Pertama, selesaikan penyiapan Firebase dengan menjalankan perintah berikut:

firebase init

Perintah ini akan memandu Anda melalui serangkaian pertanyaan yang diperlukan untuk menyiapkan project Anda. Screenshot ini menunjukkan alurnya:

  1. Saat diminta untuk memilih fitur, pilih "Firestore" dan "Emulator". (Tidak ada opsi Authentication, karena tidak menggunakan konfigurasi yang dapat diubah dari file project Flutter Anda.) fe6401d769be8f53.png
  2. Selanjutnya, pilih "Gunakan project yang ada" saat diminta.

f11dcab439e6ac1e.png

  1. Sekarang, pilih project yang Anda buat pada langkah sebelumnya: flutter-firebase-codelab.

3bdc0c6934991c25.png

  1. Selanjutnya, Anda akan ditanyai serangkaian pertanyaan tentang penamaan file yang akan dibuat. Sebaiknya tekan "enter" untuk setiap pertanyaan guna memilih default. 9bfa2d507e199c59.png
  2. Terakhir, Anda harus mengonfigurasi emulator. Pilih Firestore dan Authentication dari daftar, lalu tekan "Enter" untuk setiap pertanyaan tentang port tertentu yang akan digunakan untuk setiap emulator. Anda harus memilih default, Ya, saat ditanya apakah Anda ingin menggunakan UI Emulator.

Di akhir proses, Anda akan melihat output yang terlihat seperti screenshot berikut.

Penting: Output Anda mungkin sedikit berbeda dengan output saya, seperti yang terlihat pada screenshot di bawah, karena pertanyaan terakhir akan ditetapkan ke "Tidak" jika Anda sudah mendownload emulator.

8544e41037637b07.png

Mengonfigurasi FlutterFire

Selanjutnya, 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. Dalam codelab ini, contoh menggunakan Flutter Web, tetapi Anda dapat menyiapkan project Firebase untuk menggunakan semua opsi.

Screenshot berikut menunjukkan perintah yang harus Anda jawab.

619b7aca6dc15472.png 301c9534f594f472.png

Screenshot ini menunjukkan output di akhir proses. Jika sudah terbiasa dengan Firebase, Anda akan melihat bahwa Anda tidak perlu membuat aplikasi di konsol, dan FlutterFire CLI melakukannya untuk Anda.

12199a85ade30459.png

Menambahkan paket Firebase ke aplikasi Flutter

Langkah penyiapan terakhir adalah menambahkan paket Firebase yang relevan ke project Flutter Anda. 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
flutter pub add firebase_auth
flutter pub add cloud_firestore

Ini adalah satu-satunya paket yang akan Anda gunakan dalam aplikasi ini.

4. Mengaktifkan emulator Firebase

Sejauh ini, aplikasi Flutter dan project Firebase Anda telah disiapkan agar dapat menggunakan emulator, tetapi Anda masih perlu memberi tahu kode Flutter untuk mengalihkan permintaan Firebase keluar ke port lokal.

Pertama, tambahkan kode inisialisasi Firebase dan kode penyiapan emulator ke fungsi main di main.dart.

main.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

import 'app_state.dart';
import 'firebase_options.dart';
import 'logged_in_view.dart';
import 'logged_out_view.dart';


void main() async {
 WidgetsFlutterBinding.ensureInitialized();
 await Firebase.initializeApp(
   options: DefaultFirebaseOptions.currentPlatform,
 );

 if (kDebugMode) {
   try {
     FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080);
     await FirebaseAuth.instance.useAuthEmulator('localhost', 9099);
   } catch (e) {
     // ignore: avoid_print
     print(e);
   }
 }

 runApp(MyApp());
}

Beberapa baris pertama kode menginisialisasi Firebase. Hampir secara universal, jika Anda bekerja dengan Firebase di aplikasi Flutter, Anda harus memulai dengan memanggil WidgetsFlutterBinding.ensureInitialized dan Firebase.initializeApp.

Setelah itu, kode yang dimulai dengan baris if (kDebugMode) akan memberi tahu aplikasi Anda untuk menargetkan emulator, bukan project Firebase produksi. kDebugMode memastikan bahwa penargetan emulator hanya akan terjadi jika Anda berada di lingkungan pengembangan. Karena kDebugMode adalah nilai konstanta, compiler Dart tahu untuk menghapus blok kode tersebut sepenuhnya dalam mode rilis.

Mulai emulator

Anda harus memulai emulator sebelum memulai aplikasi Flutter. Pertama, mulai emulator dengan menjalankan perintah ini di terminal:

firebase emulators:start

Perintah ini akan mem-boot emulator dan mengekspos port localhost yang dapat kita gunakan untuk berinteraksi dengan emulator tersebut. Saat menjalankan perintah tersebut, Anda akan melihat output yang mirip dengan ini:

bb7181eb70829606.png

Output ini memberi tahu Anda emulator mana yang sedang berjalan, dan tempat Anda dapat melihat emulator tersebut. Pertama, lihat UI emulator di localhost:4000.

11563f4c7216de81.png

Ini adalah halaman beranda untuk UI emulator lokal. Perintah ini mencantumkan semua emulator yang tersedia, dan masing-masing diberi label dengan status aktif atau nonaktif.

5. Emulator Firebase Auth

Emulator pertama yang akan Anda gunakan adalah emulator Authentication. Mulai dengan emulator Auth dengan mengklik "Go to emulator" di kartu Authentication di UI, dan Anda akan melihat halaman yang terlihat seperti ini:

3c1bfded40733189.png

Halaman ini memiliki kemiripan dengan halaman konsol web Auth. Aplikasi ini memiliki tabel yang mencantumkan pengguna seperti konsol online, dan memungkinkan Anda menambahkan pengguna secara manual. Salah satu perbedaan besar di sini adalah bahwa opsi metode autentikasi yang tersedia di emulator hanya melalui Email dan Sandi. Hal ini sudah cukup untuk pengembangan lokal.

Selanjutnya, Anda akan mempelajari proses menambahkan pengguna ke emulator Firebase Auth, lalu login pengguna tersebut melalui UI Flutter.

Tambahkan pengguna

Klik tombol "Tambahkan pengguna", lalu isi formulir dengan informasi ini:

  • Nama tampilan: Dash
  • Email: dash@email.com
  • Sandi: dashword

Kirimkan formulir, dan Anda akan melihat bahwa tabel kini menyertakan pengguna. Sekarang Anda dapat memperbarui kode untuk login dengan pengguna tersebut.

logged_out_view.dart

Satu-satunya kode di widget LoggedOutView yang harus diperbarui ada di callback yang dipicu saat pengguna menekan tombol login. Perbarui kode agar terlihat seperti ini:

class LoggedOutView extends StatelessWidget {
 final AppState state;
 const LoggedOutView({super.key, required this.state});
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: const Text('Firebase Emulator Suite Codelab'),
     ),
     body: Center(
       child: Column(
         mainAxisAlignment: MainAxisAlignment.center,
         children: [
          Text(
           'Please log in',
            style: Theme.of(context).textTheme.displaySmall,
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: ElevatedButton(
             onPressed: () async {
              await state.logIn('dash@email.com', 'dashword').then((_) {
                if (state.user != null) {
                 context.go('/');
                }
              });
              },
              child: const Text('Log In'),
          ),
        ),
      ],
    ),
   ),
  );
 }
}

Kode yang diperbarui menggantikan string TODO dengan email dan sandi yang Anda buat di emulator Auth. Di baris berikutnya, baris if(true) telah diganti dengan kode yang memeriksa apakah state.user adalah null. Kode di AppClass memberikan penjelasan lebih lanjut tentang hal ini.

app_state.dart

Dua bagian kode di AppState perlu diperbarui. Pertama, berikan anggota class AppState.user jenis User dari paket firebase_auth, bukan jenis Object.

Kedua, isi metode AppState.login seperti yang ditunjukkan di bawah:

import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

import 'entry.dart';

class AppState {
 AppState() {
   _entriesStreamController = StreamController.broadcast(onListen: () {
     _entriesStreamController.add([
       Entry(
         date: '10/09/2022',
         text: lorem,
         title: '[Example] My Journal Entry',
       )
     ]);
   });
 }

 User? user; // <-- changed variable type
 Stream<List<Entry>> get entries => _entriesStreamController.stream;
 late final StreamController<List<Entry>> _entriesStreamController;

 Future<void> logIn(String email, String password) async {
   final credential = await FirebaseAuth.instance
       .signInWithEmailAndPassword(email: email, password: password);
   if (credential.user != null) {
     user = credential.user!;
     _listenForEntries();
   } else {
     print('no user!');
   }
 } 
 // ...
}

Definisi jenis untuk pengguna kini adalah User?. Class User tersebut berasal dari Firebase Auth, dan memberikan informasi yang diperlukan seperti User.displayName, yang akan dibahas sebentar lagi.

Ini adalah kode dasar yang diperlukan untuk login pengguna dengan email dan sandi di Firebase Auth. Metode ini melakukan panggilan ke FirebaseAuth untuk login, yang menampilkan objek Future<UserCredential>. Setelah masa depan selesai, kode ini akan memeriksa apakah ada User yang terlampir pada UserCredential. Jika ada pengguna di objek kredensial, pengguna telah berhasil login, dan properti AppState.user dapat disetel. Jika tidak ada, berarti terjadi error, dan error tersebut dicetak.

Perhatikan bahwa satu-satunya baris kode dalam metode ini yang khusus untuk aplikasi ini (bukan kode FirebaseAuth umum) adalah panggilan ke metode _listenForEntries, yang akan dibahas di langkah berikutnya.

TODO: Ikon Tindakan – Muat ulang aplikasi Anda, lalu tekan tombol Login saat dirender. Hal ini akan menyebabkan aplikasi membuka halaman yang bertuliskan "Selamat Datang Kembali, Pengguna!" di bagian atas. Autentikasi harus berfungsi, karena memungkinkan Anda membuka halaman ini, tetapi update kecil perlu dilakukan pada logged_in_view.dart untuk menampilkan nama sebenarnya pengguna.

logged_in_view.dart

Ubah baris pertama dalam metode LoggedInView.build:

class LoggedInView extends StatelessWidget {
 final AppState state;
 LoggedInView({super.key, required this.state});

 final PageController _controller = PageController(initialPage: 1);

 @override
 Widget build(BuildContext context) {
   final name = state.user!.displayName ?? 'No Name';

   return Scaffold(
 // ...

Sekarang, baris ini mengambil displayName dari properti User pada objek AppState. displayName ini ditetapkan di emulator saat Anda menentukan pengguna pertama. Aplikasi Anda sekarang akan menampilkan "Selamat datang kembali, Dash!" saat Anda login, bukan TODO.

6. Membaca dan Menulis data ke emulator Firestore

Pertama, lihat emulator Firestore. Di halaman beranda UI Emulator (localhost:4000), klik "Go to emulator" di kartu Firestore. Kodenya akan terlihat seperti berikut:

Emulator:

791fce7dc137910a.png

Firebase console:

e0dde9aea34af050.png

Jika Anda memiliki pengalaman dengan Firestore, Anda akan melihat bahwa halaman ini terlihat mirip dengan halaman Firestore di Firebase console. Namun, ada beberapa perbedaan penting.

  1. Anda dapat menghapus semua data dengan mengetuk satu tombol. Hal ini akan berbahaya jika dilakukan pada data produksi, tetapi berguna untuk iterasi cepat. Jika Anda sedang mengerjakan project baru dan model data Anda berubah, Anda dapat menghapusnya dengan mudah.
  2. Ada tab "Permintaan". Tab ini memungkinkan Anda melihat permintaan masuk yang dibuat ke emulator ini. Saya akan membahas tab ini secara lebih mendetail sebentar lagi.
  3. Tidak ada tab untuk Aturan, Indeks, atau Penggunaan. Ada alat (yang dibahas di bagian berikutnya) yang membantu menulis aturan keamanan, tetapi Anda tidak dapat menetapkan aturan keamanan untuk emulator lokal.

Untuk meringkas daftar tersebut, Firestore versi ini menyediakan lebih banyak alat yang berguna selama pengembangan, dan menghapus alat yang diperlukan dalam produksi.

Menulis ke Firestore

Sebelum membahas tab 'Permintaan' di emulator, buat permintaan terlebih dahulu. Tindakan ini memerlukan update kode. Mulailah dengan menghubungkan formulir di aplikasi untuk menulis entri jurnal Entry baru ke Firestore.

Alur tingkat tinggi untuk mengirimkan Entry adalah:

  1. Pengguna mengisi formulir dan menekan tombol Submit
  2. UI memanggil AppState.writeEntryToFirebase
  3. AppState.writeEntryToFirebase menambahkan entri ke Firebase

Tidak ada kode yang terlibat dalam langkah 1 atau 2 yang perlu diubah. Satu-satunya kode yang perlu ditambahkan untuk langkah 3 akan ditambahkan di class AppState. Buat perubahan berikut pada AppState.writeEntryToFirebase.

app_state.dart

import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

import 'entry.dart';

class AppState {
 AppState() {
   _entriesStreamController = StreamController.broadcast(onListen: () {
     _entriesStreamController.add([
       Entry(
         date: '10/09/2022',
         text: lorem,
         title: '[Example] My Journal Entry',
       )
     ]);
   });
 }

 User? user;
 Stream<List<Entry>> get entries => _entriesStreamController.stream;
 late final StreamController<List<Entry>> _entriesStreamController;

 Future<void> logIn(String email, String password) async {
   final credential = await FirebaseAuth.instance
       .signInWithEmailAndPassword(email: email, password: password);
   if (credential.user != null) {
     user = credential.user!;
     _listenForEntries();
   } else {
     print('no user!');
   }
 }

 void writeEntryToFirebase(Entry entry) {
   FirebaseFirestore.instance.collection('Entries').add(<String, String>{
     'title': entry.title,
     'date': entry.date.toString(),
     'text': entry.text,
   });
 }
 // ...
}

Kode dalam metode writeEntryToFirebase mengambil referensi ke koleksi yang disebut "Entries" di Firestore. Kemudian, menambahkan entri baru, yang harus berjenis Map<String, String>.

Dalam kasus ini, koleksi "Entries" di Firestore tidak ada, jadi Firestore membuatnya.

Setelah kode tersebut ditambahkan, lakukan hot reload atau mulai ulang aplikasi, login, dan buka tampilan EntryForm. Anda dapat mengisi formulir dengan Strings apa pun yang Anda inginkan. (Kolom Date akan mengambil String apa pun, karena telah disederhanakan untuk codelab ini. Tidak memiliki validasi yang kuat atau peduli dengan objek DateTime dengan cara apa pun.)

Tekan kirim pada formulir. Tidak ada yang akan terjadi di aplikasi, tetapi Anda dapat melihat entri baru di UI emulator.

Tab permintaan di emulator Firestore

Di UI, buka emulator Firestore, lalu lihat tab "Data". Anda akan melihat bahwa sekarang ada Kumpulan di root database Anda yang bernama "Entri". Dokumen tersebut harus berisi informasi yang sama dengan yang Anda masukkan ke dalam formulir.

a978fb34fb8a83da.png

Hal ini mengonfirmasi bahwa AppState.writeEntryToFirestore berhasil, dan kini Anda dapat mempelajari lebih lanjut permintaan di tab Permintaan. Klik tab tersebut sekarang.

Permintaan emulator Firestore

Di sini, Anda akan melihat daftar yang mirip dengan ini:

f0b37f0341639035.png

Anda dapat mengklik salah satu item daftar tersebut dan melihat banyak informasi bermanfaat. Klik item daftar CREATE yang sesuai dengan permintaan Anda untuk membuat entri jurnal baru. Anda akan melihat tabel baru yang terlihat seperti ini:

385d62152e99aad4.png

Seperti yang disebutkan, emulator Firestore menyediakan alat untuk mengembangkan aturan keamanan aplikasi Anda. Tampilan ini menunjukkan dengan tepat baris mana dalam aturan keamanan yang dilewati permintaan ini (atau gagal, jika itu yang terjadi). Dalam aplikasi yang lebih andal, Aturan Keamanan dapat berkembang dan memiliki beberapa pemeriksaan otorisasi. Tampilan ini digunakan untuk membantu menulis dan men-debug aturan otorisasi tersebut.

Alat ini juga menyediakan cara mudah untuk memeriksa setiap bagian permintaan ini, termasuk metadata dan data autentikasi. Data ini digunakan untuk menulis aturan otorisasi yang kompleks.

Membaca dari Firestore

Firestore menggunakan sinkronisasi data untuk mengirimkan data yang diperbarui ke perangkat yang terhubung. Dalam kode Flutter, Anda dapat memproses (atau berlangganan) koleksi dan dokumen Firestore, dan kode Anda akan diberi tahu setiap kali data berubah. Di aplikasi ini, pemrosesan update Firestore dilakukan dalam metode yang disebut AppState._listenForEntries.

Kode ini berfungsi bersama dengan StreamController dan Stream yang masing-masing disebut AppState._entriesStreamController dan AppState.entries. Kode tersebut sudah ditulis, begitu juga semua kode yang diperlukan di UI untuk menampilkan data dari Firestore.

Perbarui metode _listenForEntries agar cocok dengan kode di bawah:

app_state.dart

import 'dart:async';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';

import 'entry.dart';

class AppState {
 AppState() {
   _entriesStreamController = StreamController.broadcast(onListen: () {
     _entriesStreamController.add([
       Entry(
         date: '10/09/2022',
         text: lorem,
         title: '[Example] My Journal Entry',
       )
     ]);
   });
 }

 User? user;
 Stream<List<Entry>> get entries => _entriesStreamController.stream;
 late final StreamController<List<Entry>> _entriesStreamController;

 Future<void> logIn(String email, String password) async {
   final credential = await FirebaseAuth.instance
       .signInWithEmailAndPassword(email: email, password: password);
   if (credential.user != null) {
     user = credential.user!;
     _listenForEntries();
   } else {
     print('no user!');
   }
 }

 void writeEntryToFirebase(Entry entry) {
   FirebaseFirestore.instance.collection('Entries').add(<String, String>{
     'title': entry.title,
     'date': entry.date.toString(),
     'text': entry.text,
   });
 }

 void _listenForEntries() {
   FirebaseFirestore.instance
       .collection('Entries')
       .snapshots()
       .listen((event) {
     final entries = event.docs.map((doc) {
       final data = doc.data();
       return Entry(
         date: data['date'] as String,
         text: data['text'] as String,
         title: data['title'] as String,
       );
     }).toList();

     _entriesStreamController.add(entries);
   });
 }
 // ...
}

Kode ini memproses koleksi "Entries" di Firestore. Saat Firestore memberi tahu klien ini bahwa ada data baru, Firestore akan meneruskan data tersebut dan kode di _listenForEntries mengubah semua dokumen turunannya menjadi objek yang dapat digunakan aplikasi kita (Entry). Kemudian, Firestore menambahkan entri tersebut ke StreamController yang disebut _entriesStreamController (yang dipantau oleh UI). Kode ini adalah satu-satunya update yang diperlukan.

Terakhir, ingat bahwa metode AppState.logIn melakukan panggilan ke _listenForEntries, yang memulai proses mendengarkan setelah pengguna login.

// ...
Future<void> logIn(String email, String password) async {
 final credential = await FirebaseAuth.instance
     .signInWithEmailAndPassword(email: email, password: password);
 if (credential.user != null) {
   user = credential.user!;
   _listenForEntries();
 } else {
   print('no user!');
 }
}
// ...

Sekarang jalankan aplikasi. Tampilannya akan terlihat seperti ini:

b8a31c7a8900331.gif

7. Mengekspor dan mengimpor data ke emulator

Emulator Firebase mendukung impor dan ekspor data. Dengan menggunakan impor dan ekspor, Anda dapat melanjutkan pengembangan dengan data yang sama saat Anda beristirahat dari pengembangan, lalu melanjutkannya. Anda juga dapat melakukan commit file data ke git, dan developer lain yang bekerja sama dengan Anda akan memiliki data yang sama untuk dikerjakan.

Mengekspor data emulator

Pertama, ekspor data emulator yang sudah Anda miliki. Saat emulator masih berjalan, buka jendela terminal baru, lalu masukkan perintah berikut:

firebase emulators:export ./emulators_data

.emulators_data adalah argumen, yang memberi tahu Firebase tempat mengekspor data. Jika tidak ada, direktori akan dibuat. Anda dapat menggunakan nama apa pun yang Anda inginkan untuk direktori tersebut.

Saat menjalankan perintah ini, Anda akan melihat output ini di terminal tempat Anda menjalankan perintah:

i  Found running emulator hub for project flutter-firebase-codelab-d6b79 at http://localhost:4400
i  Creating export directory /Users/ewindmill/Repos/codelabs/firebase-emulator-suite/complete/emulators_data
i  Exporting data to: /Users/ewindmill/Repos/codelabs/firebase-emulator-suite/complete/emulators_data
✔  Export complete

Jika Anda beralih ke jendela terminal tempat emulator berjalan, Anda akan melihat output ini:

i  emulators: Received export request. Exporting data to /Users/ewindmill/Repos/codelabs/firebase-emulator-suite/complete/emulators_data.
✔  emulators: Export complete.

Terakhir, jika Anda melihat di direktori project, Anda akan melihat direktori bernama ./emulators_data, yang berisi file JSON, di antara file metadata lainnya, dengan data yang telah Anda simpan.

Mengimpor data emulator

Sekarang, Anda dapat mengimpor data tersebut sebagai bagian dari alur kerja pengembangan, dan melanjutkan dari bagian terakhir yang Anda kerjakan.

Pertama, hentikan emulator jika sedang berjalan dengan menekan CTRL+C di terminal Anda.

Selanjutnya, jalankan perintah emulators:start yang sudah Anda lihat, tetapi dengan tanda yang memberi tahu data yang akan diimpor:

firebase emulators:start --import ./emulators_data

Saat emulator aktif, buka UI emulator di localhost:4000, dan Anda akan melihat data yang sama dengan yang Anda gunakan sebelumnya.

Mengekspor data secara otomatis saat menutup emulator

Anda juga dapat mengekspor data secara otomatis saat keluar dari emulator, daripada harus mengingat untuk mengekspor data di akhir setiap sesi pengembangan.

Saat memulai emulator, jalankan perintah emulators:start dengan dua tanda tambahan.

firebase emulators:start --import ./emulators_data --export-on-exit

Nah! Data Anda kini akan disimpan dan dimuat ulang setiap kali Anda menggunakan emulator untuk project ini. Anda juga dapat menentukan direktori lain sebagai argumen ke –export-on-exit flag, tetapi direktori tersebut akan ditetapkan secara default ke direktori yang diteruskan ke –import.

Anda juga dapat menggunakan kombinasi dari opsi ini. Berikut catatan dari dokumen: Direktori ekspor dapat ditentukan dengan flag ini: firebase emulators:start --export-on-exit=./saved-data. Jika --import digunakan, jalur ekspor akan disetel ke default yang sama; misalnya: firebase emulators:start --import=./data-path --export-on-exit. Terakhir, jika diinginkan, teruskan jalur direktori yang berbeda ke flag --import dan --export-on-exit.

8. Selamat!

Anda telah menyelesaikan Memulai penggunaan emulator Firebase dan Flutter. Anda dapat menemukan kode lengkap untuk Codelab ini di direktori "complete" di github: Flutter Codelabs

Yang telah kita bahas

  • Menyiapkan aplikasi Flutter untuk menggunakan Firebase
  • Menyiapkan project Firebase
  • FlutterFire CLI
  • Firebase CLI
  • Emulator Firebase Authentication
  • Emulator Firebase Firestore
  • Mengimpor dan mengekspor data emulator

Langkah Berikutnya

Pelajari lebih lanjut

Sparky bangga padamu!

2a0ad195769368b1.gif