Pengembangan lokal untuk aplikasi Flutter Anda menggunakan Firebase Emulator Suite

1. Sebelum Anda mulai

Dalam codelab ini, Anda akan mempelajari cara menggunakan Firebase Emulator Suite dengan Flutter selama pengembangan lokal. Anda akan mempelajari cara menggunakan autentikasi kata sandi email melalui Emulator Suite, dan cara membaca dan menulis data ke emulator Firestore. Terakhir, Anda akan 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 Flutter. Jika belum, Anda mungkin ingin mempelajari dasar-dasarnya terlebih dahulu. Tautan berikut bermanfaat:

Anda juga harus memiliki pengalaman Firebase, namun tidak masalah jika Anda belum pernah menambahkan Firebase ke proyek Flutter. Jika Anda belum terbiasa dengan Firebase console, atau Anda benar-benar baru mengenal Firebase, lihat link berikut terlebih dahulu:

Apa yang akan Anda buat

Codelab ini memandu Anda dalam membuat aplikasi Penjurnalan sederhana. Aplikasi ini akan memiliki layar login, dan layar yang memungkinkan Anda membaca entri jurnal sebelumnya, dan membuat entri jurnal baru.

cd5c4753bbee8af.png8cb4d21f656540bf.png

Apa yang akan Anda pelajari

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

Perlu diperhatikan bahwa topik ini tercakup sepanjang topik tersebut diwajibkan untuk mencakup rangkaian emulator Firebase. Codelab ini difokuskan pada penambahan proyek Firebase ke aplikasi Flutter Anda, dan pengembangan menggunakan Firebase Emulator Suite. Tidak akan ada diskusi mendalam mengenai Firebase Authentication atau Firestore. Jika Anda belum terbiasa dengan topik ini, sebaiknya mulai dengan codelab Mengenal Firebase untuk Flutter .

Apa yang Anda perlukan

  • Pengetahuan tentang Flutter, dan SDK diinstal
  • Intellij JetBrains atau editor teks VS Code
  • Browser Google Chrome (atau target pengembangan pilihan Anda lainnya untuk Flutter. Beberapa perintah terminal dalam codelab ini akan berasumsi Anda menjalankan aplikasi di Chrome)

2. Membuat dan menyiapkan proyek Firebase

Tugas pertama yang harus Anda selesaikan adalah membuat proyek Firebase di konsol web Firebase. Sebagian besar codelab ini akan berfokus pada Emulator Suite, yang menggunakan UI yang berjalan secara lokal, namun Anda harus menyiapkan proyek Firebase lengkap terlebih dahulu.

Buat proyek Firebase

  1. Masuk ke konsol Firebase.
  2. Di Firebase console, klik Tambahkan Proyek (atau Buat proyek ), lalu masukkan nama untuk proyek Firebase Anda (misalnya, " Firebase-Flutter-Codelab") .

fe6aeab3b91965ed.png

  1. Klik opsi pembuatan proyek. Terima persyaratan Firebase jika diminta. Lewati penyiapan Google Analytics, karena Anda tidak akan menggunakan Analytics untuk aplikasi ini.

d1fcec48bf251eaa.png

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

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

  • Firebase Authentication untuk memungkinkan pengguna masuk ke aplikasi Anda.
  • Cloud Firestore untuk menyimpan data terstruktur di cloud dan menerima pemberitahuan instan ketika 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 basis data . 99e8429832d23fa3.png
  3. Pilih opsi Mulai dalam mode pengujian . Baca penafian tentang aturan keamanan. Mode pengujian memastikan Anda dapat dengan bebas menulis ke database selama pengembangan. Klik Berikutnya . 6be00e26c72ea032.png
  4. Pilih lokasi untuk database Anda (Anda bisa menggunakan default saja). Perhatikan bahwa lokasi ini tidak dapat diubah nanti. 278656eefcfb0216.png
  5. Klik Aktifkan .

3. Siapkan aplikasi Flutter

Anda harus mendownload kode awal, dan menginstal Firebase CLI sebelum kita mulai.

Dapatkan kode awal

Kloning repositori GitHub dari baris perintah:

git clone https://github.com/flutter/codelabs.git flutter-codelabs

Alternatifnya, jika Anda memasang alat cli GitHub :

gh repo clone flutter/codelabs flutter-codelabs

Kode contoh harus digandakan ke direktori flutter-codelabs , yang berisi kode untuk kumpulan codelab. Kode untuk codelab ini ada di flutter-codelabs/firebase-emulator-suite .

Struktur direktori pada flutter-codelabs/firebase-emulator-suite adalah dua proyek Flutter. Salah satunya disebut complete , yang dapat Anda rujuk jika Anda ingin melompatinya, atau melakukan referensi silang pada kode Anda sendiri. Proyek lainnya disebut start .

Kode yang ingin Anda gunakan untuk memulai ada di direktori flutter-codelabs/firebase-emulator-suite/start . Buka atau impor direktori itu ke IDE pilihan Anda.

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

Instal Firebase CLI

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

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

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

Setelah menginstal CLI, Anda harus mengautentikasi dengan Firebase.

  1. Masuk ke Firebase menggunakan akun Google Anda dengan menjalankan perintah berikut:
firebase login
  1. Perintah ini menghubungkan mesin lokal Anda ke Firebase dan memberi Anda akses ke proyek Firebase Anda.
  1. Uji apakah CLI terpasang dengan benar dan memiliki akses ke akun Anda dengan mencantumkan proyek Firebase Anda. Jalankan perintah berikut:
firebase projects:list
  1. Daftar yang ditampilkan harus sama dengan proyek Firebase yang tercantum di Firebase console . Anda setidaknya akan melihat firebase-flutter-codelab.

Instal FlutterFire CLI

FlutterFire CLI dibuat di atas Firebase CLI, dan memudahkan pengintegrasian proyek Firebase dengan aplikasi Flutter Anda.

Pertama, instal CLI:

dart pub global activate flutterfire_cli

Pastikan CLI telah diinstal. Jalankan perintah berikut dalam direktori proyek Flutter dan pastikan CLI mengeluarkan menu bantuan.

flutterfire --help

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

Dengan dua CLI terinstal, Anda dapat menyiapkan produk Firebase individual (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 proyek Anda. Tangkapan layar berikut menunjukkan alurnya:

  1. Saat diminta untuk memilih fitur, pilih "Firestore" dan "Emulator". (Tidak ada opsi Otentikasi, karena tidak menggunakan konfigurasi yang dapat dimodifikasi dari file proyek Flutter Anda.) fe6401d769be8f53.png
  2. Selanjutnya, pilih "Gunakan proyek yang sudah ada", ketika diminta.

f11dcab439e6ac1e.png

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

3bdc0c6934991c25.png

  1. Selanjutnya Anda akan ditanya serangkaian pertanyaan tentang penamaan file yang akan dihasilkan. Saya sarankan menekan "enter" untuk setiap pertanyaan untuk memilih default. 9bfa2d507e199c59.png
  2. Terakhir, Anda harus mengonfigurasi emulator. Pilih Firestore dan Autentikasi dari daftar, lalu tekan "Enter" untuk setiap pertanyaan tentang port spesifik yang akan digunakan untuk setiap emulator. Anda harus memilih default, Ya, ketika ditanya apakah Anda ingin menggunakan UI Emulator.

Di akhir proses, Anda akan melihat output seperti gambar berikut.

Penting : Keluaran Anda mungkin sedikit berbeda dengan keluaran saya, seperti terlihat pada tangkapan layar di bawah, karena pertanyaan terakhir akan default ke "Tidak" jika Anda sudah mengunduh emulatornya.

8544e41037637b07.png

Konfigurasikan 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 proyek Firebase mana yang ingin Anda gunakan, dan platform mana yang ingin Anda siapkan. Dalam codelab ini, contohnya menggunakan Flutter Web, tetapi Anda dapat menyiapkan proyek Firebase untuk menggunakan semua opsi.

Tangkapan layar berikut menunjukkan petunjuk yang harus Anda jawab.

619b7aca6dc15472.png301c9534f594f472.png

Tangkapan layar ini menunjukkan keluaran di akhir proses. Jika Anda sudah familiar dengan Firebase, Anda akan menyadari bahwa Anda tidak perlu membuat aplikasi di konsol, dan FlutterFire CLI melakukannya untuk Anda.

12199a85ade30459.png

Tambahkan paket Firebase ke aplikasi Flutter

Langkah penyiapan terakhir adalah menambahkan paket Firebase yang relevan ke proyek Flutter Anda. Di terminal, pastikan Anda berada di root proyek 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 proyek Firebase Anda sudah disiapkan agar dapat menggunakan emulator, namun Anda masih perlu memberi tahu kode Flutter untuk merutekan ulang 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 kode pertama menginisialisasi Firebase. Hampir secara universal, jika Anda bekerja dengan Firebase di aplikasi Flutter, Anda ingin memulai dengan memanggil WidgetsFlutterBinding.ensureInitialized dan Firebase.initializeApp .

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

Mulai emulator

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

firebase emulators:start

Perintah ini mem-boot emulator, dan memperlihatkan port localhost yang dapat kita gunakan untuk berinteraksi dengannya. Saat Anda menjalankan perintah itu, Anda akan melihat keluaran seperti ini:

bb7181eb70829606.png

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

11563f4c7216de81.png

Ini adalah beranda untuk UI emulator lokal. 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. Mulailah menggunakan emulator Auth dengan mengklik "Buka emulator" pada kartu Autentikasi di UI, dan Anda akan melihat halaman seperti ini:

3c1bfded40733189.png

Halaman ini memiliki kemiripan dengan halaman konsol web Auth. Ini memiliki tabel yang mencantumkan pengguna seperti konsol online, dan memungkinkan Anda menambahkan pengguna secara manual. Satu perbedaan besar di sini adalah satu-satunya opsi metode otentikasi yang tersedia di emulator adalah melalui Email dan Kata Sandi. Jumlah ini cukup untuk pembangunan daerah.

Selanjutnya, Anda akan menjalani proses penambahan pengguna ke emulator Firebase Auth, lalu memasukkan pengguna tersebut melalui Flutter UI.

Tambahkan pengguna

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

  • Nama tampilan: Dash
  • Surel: dash@email.com
  • Kata sandi: kata sandi

Kirimkan formulir, dan Anda akan melihat tabel sekarang menyertakan pengguna. Sekarang Anda dapat memperbarui kode untuk masuk dengan pengguna tersebut.

log_out_view.dart

Satu-satunya kode di widget LoggedOutView yang harus diperbarui adalah di callback yang dipicu ketika 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 kata sandi yang Anda buat di emulator auth. Dan di baris berikutnya, baris if(true) telah diganti dengan kode yang memeriksa apakah state.user adalah null. Kode di AppClass menjelaskan lebih lanjut tentang hal ini.

app_state.dart

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

Kedua, isi metode AppState.login seperti gambar di bawah ini:

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 tipe untuk pengguna sekarang adalah User? . Kelas User tersebut berasal dari Firebase Auth, dan memberikan informasi yang diperlukan seperti User.displayName , yang akan dibahas sedikit.

Ini adalah kode dasar yang diperlukan untuk memasukkan pengguna dengan email dan kata sandi di Firebase Auth. Ia melakukan panggilan ke FirebaseAuth untuk masuk, yang mengembalikan objek Future<UserCredential> . Ketika masa depan selesai, kode ini memeriksa apakah ada User yang dilampirkan ke UserCredential . Jika ada pengguna pada objek kredensial, maka pengguna telah berhasil login, dan properti AppState.user dapat diatur. Jika tidak ada, berarti ada kesalahan, dan tercetak.

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 pada langkah berikutnya.

TODO: Ikon Tindakan – Muat ulang aplikasi Anda, lalu tekan tombol Login saat aplikasi dirender. Hal ini menyebabkan aplikasi menavigasi ke halaman yang bertuliskan "Selamat Datang Kembali, Teman!" di atas. Otentikasi harus berfungsi, karena memungkinkan Anda menavigasi ke halaman ini, namun pembaruan kecil perlu dilakukan pada logged_in_view.dart untuk menampilkan nama pengguna yang sebenarnya.

login_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 disetel di emulator saat Anda mendefinisikan pengguna pertama Anda. Aplikasi Anda sekarang akan menampilkan "Selamat datang kembali, Dash!" saat Anda masuk, bukan TODO .

6. Membaca dan Menulis data ke emulator Firestore

Pertama, periksa emulator Firestore. Di beranda UI Emulator ( localhost:4000 ), klik "Buka emulator" pada kartu Firestore. Seharusnya terlihat seperti ini:

Emulator:

791fce7dc137910a.png

Konsol Firebase:

e0dde9aea34af050.png

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

  1. Anda dapat menghapus semua data dengan satu ketukan tombol. Ini akan berbahaya dengan data produksi, namun berguna untuk iterasi cepat! Jika Anda sedang mengerjakan proyek baru dan model data Anda berubah, hal ini mudah untuk diselesaikan.
  2. Ada tab "Permintaan". Tab ini memungkinkan Anda melihat permintaan masuk yang dibuat ke emulator ini. Saya akan membahas tab ini lebih detail sebentar lagi.
  3. Tidak ada tab untuk Aturan, Indeks, atau Penggunaan. Terdapat alat (dibahas di bagian berikutnya) yang membantu menulis aturan keamanan, namun Anda tidak dapat menetapkan aturan keamanan untuk emulator lokal.

Singkatnya, versi Firestore ini menyediakan lebih banyak alat yang berguna selama pengembangan, dan menghilangkan alat yang diperlukan dalam produksi.

Menulis ke Firestore

Sebelum membahas tab 'Requests' di emulator, buatlah request terlebih dahulu. Ini memerlukan pembaruan kode. Mulailah dengan memasang formulir di aplikasi untuk menulis Entry jurnal 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 kelas AppState . Lakukan 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 "Entri" di Firestore. Ia kemudian menambahkan entri baru, yang harus bertipe Map<String, String> .

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

Dengan menambahkan kode tersebut, muat ulang atau mulai ulang aplikasi Anda, masuk, dan navigasikan ke tampilan EntryForm . Anda dapat mengisi formulir dengan Strings apa pun yang Anda inginkan. (Kolom Tanggal akan menggunakan String apa pun, karena telah disederhanakan untuk codelab ini. Kolom ini tidak memiliki validasi yang kuat atau tidak mempedulikan objek DateTime dengan cara apa pun.)

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

Tab permintaan di emulator Firestore

Di UI, navigasikan ke emulator Firestore, dan lihat tab "Data". Anda akan melihat bahwa sekarang ada Koleksi di root database Anda yang disebut "Entri". Itu harus memiliki dokumen yang berisi informasi yang sama dengan yang Anda masukkan ke dalam formulir.

a978fb34fb8a83da.png

Hal ini mengonfirmasi bahwa AppState.writeEntryToFirestore berfungsi, dan sekarang Anda dapat menjelajahi permintaan lebih lanjut di tab Permintaan. Klik tab itu sekarang.

Permintaan emulator Firestore

Di sini, Anda akan melihat daftar yang terlihat seperti ini:

f0b37f0341639035.png

Anda dapat mengeklik salah satu item daftar tersebut dan melihat cukup banyak informasi bermanfaat. Klik pada 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 disebutkan, emulator Firestore menyediakan alat untuk mengembangkan aturan keamanan aplikasi Anda. Tampilan ini menunjukkan dengan tepat baris mana dalam aturan keamanan Anda yang dilewati permintaan ini (atau gagal, jika itu masalahnya). Dalam aplikasi yang lebih tangguh, Aturan Keamanan dapat berkembang dan memiliki beberapa pemeriksaan otorisasi. Tampilan ini digunakan untuk membantu menulis dan men-debug aturan otorisasi tersebut.

Ini juga menyediakan cara mudah untuk memeriksa setiap bagian dari 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 terbaru ke perangkat yang terhubung. Dalam kode Flutter, Anda dapat mendengarkan (atau berlangganan) koleksi dan dokumen Firestore, dan kode Anda akan diberi tahu setiap kali ada perubahan data. Dalam aplikasi ini, mendengarkan pembaruan 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 pula semua kode yang diperlukan di UI untuk menampilkan data dari Firestore.

Perbarui metode _listenForEntries agar sesuai dengan kode di bawah ini:

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 mendengarkan koleksi "Entri" di Firestore. Saat Firestore memberi tahu klien ini bahwa ada data baru, ia meneruskan data tersebut dan kode di _listenForEntries mengubah semua dokumen turunannya menjadi objek yang dapat digunakan aplikasi kita ( Entry ). Kemudian, ia menambahkan entri tersebut ke StreamController yang disebut _entriesStreamController (yang didengarkan oleh UI). Kode ini adalah satu-satunya pembaruan yang diperlukan.

Terakhir, ingatlah 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 aplikasinya. Seharusnya terlihat seperti ini:

b8a31c7a8900331.gif

7. Ekspor dan impor data ke emulator

Emulator Firebase mendukung impor dan ekspor data. Menggunakan impor dan ekspor memungkinkan Anda melanjutkan pengembangan dengan data yang sama saat Anda berhenti sejenak dari pengembangan dan kemudian melanjutkannya. Anda juga dapat memasukkan file data ke git, dan pengembang lain yang bekerja sama dengan Anda akan memiliki data yang sama untuk digunakan.

Ekspor data emulator

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

firebase emulators:export ./emulators_data

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

Saat Anda 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

Dan jika Anda beralih ke jendela terminal tempat emulator berjalan, Anda akan melihat keluaran ini:

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

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

Impor data emulator

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

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 memberitahukan data apa yang akan diimpor:

firebase emulators:start --import ./emulators_data

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

Ekspor data secara otomatis saat menutup emulator

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

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

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

Voila! Data Anda sekarang akan disimpan dan dimuat ulang setiap kali Anda bekerja dengan emulator untuk proyek ini. Anda juga dapat menentukan direktori berbeda sebagai argumen pada –export-on-exit flag , tetapi direktori tersebut akan default ke direktori yang diteruskan ke –import .

Anda juga dapat menggunakan kombinasi apa pun dari opsi ini. Ini adalah catatan dari dokumen : Direktori ekspor dapat ditentukan dengan tanda ini: firebase emulators:start --export-on-exit=./saved-data . Jika --import digunakan, jalur ekspor defaultnya sama; misalnya: firebase emulators:start --import=./data-path --export-on-exit . Terakhir, jika diinginkan, berikan jalur direktori yang berbeda ke flag --import dan --export-on-exit .

8. Selamat!

Anda telah menyelesaikan Persiapan dan pengoperasian dengan emulator Firebase dan Flutter. Anda dapat menemukan kode lengkap untuk Codelab ini di direktori "lengkap" di github: Flutter Codelabs

Apa yang telah kami bahas

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

Langkah selanjutnya

Belajarlah lagi

Sparky bangga padamu!

2a0ad195769368b1.gif