1. ก่อนที่คุณจะเริ่ม
ใน Codelab นี้ คุณจะได้เรียนรู้วิธีใช้ Firebase Emulator Suite กับ Flutter ในระหว่างการพัฒนาในพื้นที่ คุณจะได้เรียนรู้วิธีใช้การตรวจสอบสิทธิ์อีเมลและรหัสผ่านผ่าน Emulator Suite และวิธีอ่านและเขียนข้อมูลไปยัง Firestore emulator สุดท้ายนี้ คุณจะต้องดำเนินการนำเข้าและส่งออกข้อมูลจากโปรแกรมจำลอง เพื่อทำงานกับข้อมูลปลอมเดียวกันทุกครั้งที่คุณกลับสู่การพัฒนา
ข้อกำหนดเบื้องต้น
Codelab นี้ถือว่าคุณมีประสบการณ์ Flutter มาบ้างแล้ว ถ้าไม่ คุณอาจต้องการเรียนรู้พื้นฐานก่อน ลิงก์ต่อไปนี้มีประโยชน์:
- ทัวร์ชมกรอบ Flutter Widget
- ลองใช้ เขียนแอป Flutter แรกของคุณ ตอนที่ 1 codelab
คุณควรมีประสบการณ์ Firebase บ้าง แต่ก็ไม่เป็นไรหากคุณไม่เคยเพิ่ม Firebase ในโครงการ Flutter หากคุณไม่คุ้นเคยกับคอนโซล Firebase หรือคุณเพิ่งเคยใช้ Firebase มาก่อน โปรดดูลิงก์ต่อไปนี้ก่อน:
สิ่งที่คุณจะสร้าง
Codelab นี้จะแนะนำคุณตลอดขั้นตอนการสร้างแอปพลิเคชัน Journaling แบบง่ายๆ แอปพลิเคชันจะมีหน้าจอเข้าสู่ระบบ และหน้าจอที่ให้คุณอ่านรายการบันทึกในอดีต และสร้างรายการใหม่ได้
สิ่งที่คุณจะได้เรียนรู้
คุณจะได้เรียนรู้วิธีเริ่มใช้ Firebase และวิธีผสานรวมและใช้ชุด Firebase Emulator เข้ากับเวิร์กโฟลว์การพัฒนา Flutter ของคุณ หัวข้อ Firebase เหล่านี้จะครอบคลุมถึง:
โปรดทราบว่าหัวข้อเหล่านี้ครอบคลุมถึงความจำเป็นในการครอบคลุมชุดโปรแกรมจำลอง Firebase Codelab นี้มุ่งเน้นไปที่การเพิ่มโปรเจ็กต์ Firebase ให้กับแอป Flutter ของคุณ และการพัฒนาโดยใช้ Firebase Emulator Suite จะไม่มีการสนทนาเชิงลึกเกี่ยวกับ Firebase Authentication หรือ Firestore หากคุณไม่คุ้นเคยกับหัวข้อเหล่านี้ เราขอแนะนำให้เริ่มต้นด้วย การทำความรู้จัก Firebase สำหรับ Flutter codelab
สิ่งที่คุณต้องการ
- ความรู้เกี่ยวกับการทำงานของ Flutter และ ติดตั้ง SDK แล้ว
- โปรแกรมแก้ไขข้อความ Intellij JetBrains หรือ VS Code
- เบราว์เซอร์ Google Chrome (หรือเป้าหมายการพัฒนาอื่น ๆ ที่คุณต้องการสำหรับ Flutter คำสั่งเทอร์มินัลบางคำสั่งใน codelab นี้จะถือว่าคุณใช้งานแอปของคุณบน Chrome)
2. สร้างและตั้งค่าโปรเจ็กต์ Firebase
งานแรกที่คุณต้องทำให้เสร็จคือการสร้างโปรเจ็กต์ Firebase ในเว็บคอนโซลของ Firebase Codelab ส่วนใหญ่จะมุ่งเน้นไปที่ Emulator Suite ซึ่งใช้ UI ที่รันในเครื่อง แต่คุณต้องตั้งค่าโปรเจ็กต์ Firebase แบบเต็มก่อน
สร้างโปรเจ็กต์ Firebase
- ลงชื่อเข้าใช้คอนโซล Firebase
- ในคอนโซล Firebase คลิก เพิ่มโครงการ (หรือ สร้างโครงการ ) และป้อนชื่อสำหรับโครงการ Firebase ของคุณ (เช่น " Firebase-Flutter-Codelab")
- คลิกผ่านตัวเลือกการสร้างโครงการ ยอมรับข้อกำหนดของ Firebase หากได้รับแจ้ง ข้ามการตั้งค่า Google Analytics เนื่องจากคุณจะไม่ใช้ Analytics สำหรับแอปนี้
หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับโครงการ Firebase โปรดดู ทำความเข้าใจโครงการ Firebase
แอปที่คุณกำลังสร้างใช้ผลิตภัณฑ์ Firebase สองรายการที่มีให้สำหรับแอป Flutter:
- การตรวจสอบสิทธิ์ Firebase เพื่อให้ผู้ใช้ลงชื่อเข้าใช้แอปของคุณได้
- Cloud Firestore เพื่อบันทึกข้อมูลที่มีโครงสร้างบนคลาวด์และรับการแจ้งเตือนทันทีเมื่อข้อมูลมีการเปลี่ยนแปลง
ผลิตภัณฑ์ทั้งสองนี้จำเป็นต้องมีการกำหนดค่าพิเศษหรือต้องเปิดใช้งานโดยใช้คอนโซล Firebase
เปิดใช้งาน Cloud Firestore
แอป Flutter ใช้ Cloud Firestore เพื่อบันทึกรายการบันทึกประจำวัน
เปิดใช้งาน Cloud Firestore:
- ในส่วน Build ของคอนโซล Firebase ให้คลิก Cloud Firestore
- คลิก สร้างฐานข้อมูล
- เลือกตัวเลือก เริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดชอบเกี่ยวกับกฎความปลอดภัย โหมดทดสอบช่วยให้มั่นใจได้ว่าคุณสามารถเขียนลงในฐานข้อมูลได้อย่างอิสระในระหว่างการพัฒนา คลิก ถัดไป
- เลือกตำแหน่งสำหรับฐานข้อมูลของคุณ (คุณสามารถใช้ค่าเริ่มต้นได้) โปรดทราบว่าสถานที่นี้ไม่สามารถเปลี่ยนแปลงได้ในภายหลัง
- คลิก เปิดใช้งาน
3. ตั้งค่าแอพ Flutter
คุณจะต้องดาวน์โหลดโค้ดเริ่มต้น และติดตั้ง Firebase CLI ก่อนที่เราจะเริ่ม
รับรหัสเริ่มต้น
โคลน ที่เก็บ GitHub จากบรรทัดคำสั่ง:
git clone https://github.com/flutter/codelabs.git flutter-codelabs
หรือหากคุณติดตั้งเครื่องมือ cli ของ GitHub :
gh repo clone flutter/codelabs flutter-codelabs
โค้ดตัวอย่างควรถูกโคลนลงในไดเร็กทอรี flutter-codelabs
ซึ่งมีโค้ดสำหรับคอลเล็กชันของ codelabs รหัสสำหรับ codelab นี้อยู่ใน flutter-codelabs/firebase-emulator-suite
โครงสร้างไดเร็กทอรีภายใต้ flutter-codelabs/firebase-emulator-suite
เป็นสองโปรเจ็กต์ Flutter สิ่งหนึ่งเรียกว่า complete
ซึ่งคุณสามารถใช้อ้างอิงได้หากต้องการข้ามไปข้างหน้า หรืออ้างอิงโยงโค้ดของคุณเอง อีกโครงการหนึ่งเรียกว่า start
รหัสที่คุณต้องการเริ่มต้นด้วยอยู่ในไดเรกทอรี flutter-codelabs/firebase-emulator-suite/start
เปิดหรือนำเข้าไดเร็กทอรีนั้นไปยัง IDE ที่คุณต้องการ
cd flutter-codelabs/firebase-emulator-suite/start
ติดตั้ง Firebase CLI
Firebase CLI มีเครื่องมือสำหรับจัดการโปรเจ็กต์ Firebase ของคุณ CLI จำเป็นต้องใช้ Emulator Suite ดังนั้นคุณจะต้องติดตั้ง
มีหลายวิธีในการติดตั้ง CLI วิธีที่ง่ายที่สุด หากคุณใช้ MacOS หรือ Linux คือการรันคำสั่งนี้จากเทอร์มินัลของคุณ:
curl -sL https://firebase.tools | bash
หลังจากติดตั้ง CLI คุณต้องตรวจสอบสิทธิ์กับ Firebase
- เข้าสู่ระบบ Firebase โดยใช้บัญชี Google ของคุณโดยเรียกใช้คำสั่งต่อไปนี้:
firebase login
- คำสั่งนี้จะเชื่อมต่อเครื่องในเครื่องของคุณกับ Firebase และให้สิทธิ์คุณในการเข้าถึงโปรเจ็กต์ Firebase ของคุณ
- ทดสอบว่าติดตั้ง CLI อย่างถูกต้องและเข้าถึงบัญชีของคุณได้โดยแสดงรายการโปรเจ็กต์ Firebase ของคุณ รันคำสั่งต่อไปนี้:
firebase projects:list
- รายการที่แสดงควรเหมือนกับโครงการ Firebase ที่แสดงอยู่ใน คอนโซล Firebase คุณควรเห็นอย่างน้อย firebase-flutter-codelab
ติดตั้ง FlutterFire CLI
FlutterFire CLI สร้างขึ้นบน Firebase CLI และทำให้การรวมโปรเจ็กต์ Firebase เข้ากับแอป Flutter ของคุณง่ายขึ้น
ขั้นแรก ให้ติดตั้ง CLI:
dart pub global activate flutterfire_cli
ตรวจสอบให้แน่ใจว่าได้ติดตั้ง CLI แล้ว รันคำสั่งต่อไปนี้ภายในไดเร็กทอรีโปรเจ็กต์ Flutter และตรวจสอบให้แน่ใจว่า CLI ส่งออกเมนูวิธีใช้
flutterfire --help
ใช้ Firebase CLI และ FlutterFire CLI เพื่อเพิ่มโปรเจ็กต์ Firebase ของคุณไปยังแอป Flutter
เมื่อติดตั้ง CLI ทั้งสองแล้ว คุณสามารถตั้งค่าผลิตภัณฑ์ Firebase แต่ละรายการ (เช่น Firestore) ดาวน์โหลดโปรแกรมจำลอง และเพิ่ม Firebase ลงในแอป Flutter ของคุณด้วยคำสั่งเทอร์มินัลเพียงไม่กี่คำสั่ง
ขั้นแรก ให้ตั้งค่า Firebase ให้เสร็จสิ้นโดยเรียกใช้สิ่งต่อไปนี้:
firebase init
คำสั่งนี้จะนำคุณไปสู่ชุดคำถามที่จำเป็นในการตั้งค่าโปรเจ็กต์ของคุณ ภาพหน้าจอเหล่านี้แสดงขั้นตอน:
- เมื่อได้รับแจ้งให้เลือกคุณสมบัติ ให้เลือก "Firestore" และ "Emulators" (ไม่มีตัวเลือกการรับรองความถูกต้อง เนื่องจากไม่ได้ใช้การกำหนดค่าที่สามารถแก้ไขได้จากไฟล์โครงการ Flutter ของคุณ)
- จากนั้นเลือก "ใช้โครงการที่มีอยู่" เมื่อได้รับแจ้ง
- ตอนนี้ เลือกโปรเจ็กต์ที่คุณสร้างในขั้นตอนก่อนหน้า: flutter-firebase-codelab
- ถัดไป คุณจะถูกถามคำถามเกี่ยวกับการตั้งชื่อไฟล์ที่จะถูกสร้างขึ้น ฉันแนะนำให้กด "Enter" สำหรับแต่ละคำถามเพื่อเลือกค่าเริ่มต้น
- สุดท้ายนี้ คุณจะต้องกำหนดค่าอีมูเลเตอร์ เลือก Firestore และ Authentication จากรายการ จากนั้นกด "Enter" เพื่อถามคำถามแต่ละข้อเกี่ยวกับพอร์ตเฉพาะที่จะใช้สำหรับโปรแกรมจำลองแต่ละตัว คุณควรเลือกค่าเริ่มต้น ใช่ เมื่อถูกถามว่าคุณต้องการใช้ Emulator UI หรือไม่
ในตอนท้ายของกระบวนการ คุณจะเห็นผลลัพธ์ที่ดูเหมือนภาพหน้าจอต่อไปนี้
สำคัญ : ผลลัพธ์ของคุณอาจแตกต่างจากของฉันเล็กน้อย ดังที่เห็นในภาพหน้าจอด้านล่าง เนื่องจากคำถามสุดท้ายจะมีค่าเริ่มต้นเป็น "ไม่" หากคุณได้ดาวน์โหลดโปรแกรมจำลองไว้แล้ว
กำหนดค่า FlutterFire
จากนั้น คุณสามารถใช้ FlutterFire เพื่อสร้างโค้ด Dart ที่จำเป็นเพื่อใช้ Firebase ในแอป Flutter ของคุณ
flutterfire configure
เมื่อเรียกใช้คำสั่งนี้ คุณจะได้รับแจ้งให้เลือกโปรเจ็กต์ Firebase ที่คุณต้องการใช้ และแพลตฟอร์มที่คุณต้องการตั้งค่า ใน Codelab นี้ ตัวอย่างใช้ Flutter Web แต่คุณสามารถตั้งค่าโปรเจ็กต์ Firebase ให้ใช้ตัวเลือกทั้งหมดได้
ภาพหน้าจอต่อไปนี้แสดงพร้อมท์ที่คุณจะต้องตอบ
ภาพหน้าจอนี้แสดงผลลัพธ์เมื่อสิ้นสุดกระบวนการ หากคุณคุ้นเคยกับ Firebase คุณจะสังเกตเห็นว่าคุณไม่จำเป็นต้องสร้างแอปพลิเคชันในคอนโซล และ FlutterFire CLI ก็ทำเพื่อคุณ
เพิ่มแพ็คเกจ Firebase ให้กับแอพ Flutter
ขั้นตอนการตั้งค่าสุดท้ายคือการเพิ่มแพ็คเกจ Firebase ที่เกี่ยวข้องให้กับโปรเจ็กต์ Flutter ของคุณ ในเทอร์มินัล ตรวจสอบให้แน่ใจว่าคุณอยู่ในรูทของโปรเจ็กต์ Flutter ที่ flutter-codelabs/firebase-emulator-suite/start
จากนั้นรันคำสั่งสามคำสั่งต่อไปนี้:
flutter pub add firebase_core
flutter pub add firebase_auth
flutter pub add cloud_firestore
นี่เป็นแพ็คเกจเดียวที่คุณจะใช้ในแอปพลิเคชันนี้
4. การเปิดใช้งานโปรแกรมจำลอง Firebase
จนถึงตอนนี้ แอป Flutter และโปรเจ็กต์ Firebase ของคุณได้รับการตั้งค่าให้สามารถใช้โปรแกรมจำลองได้ แต่คุณยังคงต้องบอกรหัส Flutter เพื่อเปลี่ยนเส้นทางคำขอ Firebase ขาออกไปยังพอร์ตในเครื่อง
ขั้นแรก เพิ่มรหัสเริ่มต้น Firebase และรหัสการตั้งค่าโปรแกรมจำลองให้กับฟังก์ชัน main
ใน main.dart.
main.โผ
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()); }
โค้ดสองสามบรรทัดแรกจะเริ่มต้น Firebase เกือบเป็นสากล หากคุณกำลังทำงานกับ Firebase ในแอป Flutter คุณต้องเริ่มต้นด้วยการเรียก WidgetsFlutterBinding.ensureInitialized
และ Firebase.initializeApp
หลังจากนั้น โค้ดที่ขึ้นต้นด้วยบรรทัด if (kDebugMode)
บอกให้แอปของคุณกำหนดเป้าหมายไปที่ตัวจำลอง แทนที่จะเป็นโปรเจ็กต์ Firebase ที่ใช้งานจริง kDebugMode
ช่วยให้มั่นใจได้ว่าการกำหนดเป้าหมายโปรแกรมจำลองจะเกิดขึ้นเฉพาะเมื่อคุณอยู่ในสภาพแวดล้อมการพัฒนาเท่านั้น เนื่องจาก kDebugMode
เป็นค่าคงที่ คอมไพเลอร์ Dart จึงทราบที่จะลบบล็อคโค้ดนั้นทั้งหมดในโหมดรีลีส
เริ่มต้นโปรแกรมจำลอง
คุณควรเริ่มโปรแกรมจำลองก่อนที่จะเริ่มแอพ Flutter ขั้นแรก ให้เริ่มต้นโปรแกรมจำลองโดยเรียกใช้สิ่งนี้ในเทอร์มินัล:
firebase emulators:start
คำสั่งนี้บูทอีมูเลเตอร์และเปิดเผยพอร์ต localhost ซึ่งเราสามารถโต้ตอบกับพวกมันได้ เมื่อคุณรันคำสั่งนั้น คุณจะเห็นผลลัพธ์ที่คล้ายกับสิ่งนี้:
เอาต์พุตนี้จะบอกคุณว่าโปรแกรมจำลองใดกำลังทำงานอยู่ และคุณจะไปดูโปรแกรมจำลองได้ที่ไหน ขั้นแรก ตรวจสอบ UI ของโปรแกรมจำลองที่ localhost:4000
นี่คือหน้าแรกของ UI ของโปรแกรมจำลองในเครื่อง โดยจะแสดงรายการโปรแกรมจำลองทั้งหมดที่มีอยู่ และแต่ละรายการจะมีป้ายกำกับสถานะเปิดหรือปิด
5. โปรแกรมจำลอง Firebase Auth
โปรแกรมจำลองแรกที่คุณจะใช้คือโปรแกรมจำลองการรับรองความถูกต้อง เริ่มต้นด้วยโปรแกรมจำลองการตรวจสอบสิทธิ์โดยคลิก "ไปที่โปรแกรมจำลอง" บนการ์ดการตรวจสอบสิทธิ์ใน UI และคุณจะเห็นหน้าเว็บที่มีลักษณะดังนี้:
หน้านี้มีความคล้ายคลึงกับหน้าคอนโซลเว็บ Auth มีตารางแสดงรายการผู้ใช้ เช่น คอนโซลออนไลน์ และให้คุณเพิ่มผู้ใช้ด้วยตนเองได้ ข้อแตกต่างที่สำคัญประการหนึ่งคือตัวเลือกวิธีการตรวจสอบสิทธิ์เดียวที่มีในโปรแกรมจำลองคือผ่านอีเมลและรหัสผ่าน เพียงพอต่อการพัฒนาท้องถิ่น
ถัดไป คุณจะได้อธิบายขั้นตอนการเพิ่มผู้ใช้ลงในโปรแกรมจำลอง Firebase Auth จากนั้นจึงบันทึกผู้ใช้รายนั้นผ่าน Flutter UI
เพิ่มผู้ใช้
คลิกปุ่ม "เพิ่มผู้ใช้" และกรอกแบบฟอร์มพร้อมข้อมูลนี้:
- ชื่อที่แสดง: แดช
- อีเมล์: dash@email.com
- รหัสผ่าน: แดชบอร์ด
ส่งแบบฟอร์มแล้วคุณจะเห็นตารางรวมผู้ใช้ไว้ด้วย ตอนนี้คุณสามารถอัปเดตรหัสเพื่อเข้าสู่ระบบด้วยผู้ใช้รายนั้นได้
logged_out_view.dart
รหัสเดียวในวิดเจ็ต LoggedOutView
ที่ต้องอัปเดตอยู่ในการโทรกลับที่เกิดขึ้นเมื่อผู้ใช้กดปุ่มเข้าสู่ระบบ อัพเดตโค้ดให้มีลักษณะดังนี้:
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'), ), ), ], ), ), ); } }
รหัสที่อัปเดตจะแทนที่สตริง TODO
ด้วยอีเมลและรหัสผ่านที่คุณสร้างในโปรแกรมจำลองการตรวจสอบสิทธิ์ และในบรรทัดถัดไป บรรทัด if(true)
จะถูกแทนที่ด้วยโค้ดที่ตรวจสอบว่า state.user
เป็นโมฆะหรือไม่ รหัสใน AppClass
ให้ความกระจ่างเพิ่มเติมเกี่ยวกับเรื่องนี้
app_state.dart
จำเป็นต้องอัปเดตโค้ดสองส่วนใน AppState
ขั้นแรก ให้สมาชิกคลาส AppState.user เป็นประเภท User
จากแพ็คเกจ firebase_auth
แทนที่จะเป็นประเภท Object
ขั้นที่สอง กรอกวิธี AppState.login
ดังที่แสดงด้านล่าง:
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!'); } } // ... }
คำจำกัดความประเภทสำหรับผู้ใช้ตอนนี้คือ User?
. คลาส User
นั้นมาจาก Firebase Auth และให้ข้อมูลที่จำเป็น เช่น User.displayName
ซึ่งจะกล่าวถึงในอีกสักครู่
นี่เป็นรหัสพื้นฐานที่จำเป็นในการเข้าสู่ระบบผู้ใช้ด้วยอีเมลและรหัสผ่านใน Firebase Auth โดยจะเรียก FirebaseAuth เพื่อลงชื่อเข้าใช้ ซึ่งจะส่งคืนอ็อบเจ็กต์ Future<UserCredential>
เมื่ออนาคตสิ้นสุดลง รหัสนี้จะตรวจสอบว่ามี User
แนบอยู่กับ UserCredential
หรือไม่ หากมีผู้ใช้อยู่บนออบเจ็กต์หนังสือรับรอง แสดงว่าผู้ใช้เข้าสู่ระบบสำเร็จแล้ว และสามารถตั้งค่าคุณสมบัติ AppState.user
ได้ หากไม่มี แสดงว่าเกิดข้อผิดพลาด และจะพิมพ์ออกมา
โปรดทราบว่าบรรทัดโค้ดเดียวในวิธีนี้ที่เฉพาะเจาะจงสำหรับแอปนี้ (แทนที่จะเป็นโค้ด FirebaseAuth ทั่วไป) คือการเรียกไปยังเมธอด _listenForEntries
ซึ่งจะกล่าวถึงในขั้นตอนถัดไป
สิ่งที่ต้องทำ: ไอคอนการดำเนินการ – โหลดแอปของคุณซ้ำ จากนั้นกดปุ่มเข้าสู่ระบบเมื่อแสดงผล ซึ่งจะทำให้แอปนำทางไปยังหน้าที่ระบุว่า "ยินดีต้อนรับกลับมา บุคคล!" ที่ด้านบน. การตรวจสอบสิทธิ์ต้องใช้งานได้ เนื่องจากอนุญาตให้คุณไปที่หน้านี้ได้ แต่ต้องมีการอัปเดตเล็กน้อยใน logged_in_view.dart
เพื่อแสดงชื่อจริงของผู้ใช้
logged_in_view.dart
เปลี่ยนบรรทัดแรกในเมธอด 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( // ...
ตอนนี้ บรรทัดนี้จะดึง displayName
จากคุณสมบัติ User
บนออบเจ็กต์ AppState
displayName
นี้ถูกตั้งค่าในโปรแกรมจำลองเมื่อคุณกำหนดผู้ใช้รายแรกของคุณ ตอนนี้แอปของคุณควรแสดงข้อความ "ยินดีต้อนรับกลับมา Dash!" เมื่อคุณเข้าสู่ระบบ แทนที่จะเป็น TODO
6. อ่านและเขียนข้อมูลไปยังโปรแกรมจำลอง Firestore
ขั้นแรก ให้ตรวจสอบโปรแกรมจำลอง Firestore บนหน้าแรกของ Emulator UI ( localhost:4000
) คลิก "ไปที่โปรแกรมจำลอง" บนการ์ด Firestore มันควรมีลักษณะเช่นนี้:
โปรแกรมจำลอง:
คอนโซล Firebase:
หากคุณมีประสบการณ์กับ Firestore คุณจะสังเกตเห็นว่าหน้านี้มีลักษณะคล้ายกับหน้า Firestore คอนโซล Firebase มีความแตกต่างที่น่าสังเกตบางประการ
- คุณสามารถล้างข้อมูลทั้งหมดได้ด้วยการแตะปุ่มเดียว สิ่งนี้อาจเป็นอันตรายต่อข้อมูลการผลิต แต่มีประโยชน์สำหรับการวนซ้ำอย่างรวดเร็ว! หากคุณกำลังทำงานในโปรเจ็กต์ใหม่และโมเดลข้อมูลของคุณเปลี่ยนแปลง เป็นเรื่องง่ายที่จะล้างออก
- มีแท็บ "คำขอ" แท็บนี้อนุญาตให้คุณดูคำขอขาเข้าที่ทำกับโปรแกรมจำลองนี้ ฉันจะหารือเกี่ยวกับแท็บนี้โดยละเอียดเพิ่มเติมในอีกสักครู่
- ไม่มีแท็บสำหรับกฎ ดัชนี หรือการใช้งาน มีเครื่องมือ (จะกล่าวถึงในหัวข้อถัดไป) ที่ช่วยเขียนกฎความปลอดภัย แต่คุณไม่สามารถตั้งกฎความปลอดภัยสำหรับโปรแกรมจำลองในเครื่องได้
โดยสรุปรายการดังกล่าว Firestore เวอร์ชันนี้มีเครื่องมือเพิ่มเติมที่มีประโยชน์ในระหว่างการพัฒนา และลบเครื่องมือที่จำเป็นในการผลิต
เขียนถึง Firestore
ก่อนที่จะหารือเกี่ยวกับแท็บ 'คำขอ' ในโปรแกรมจำลอง ให้ส่งคำขอก่อน สิ่งนี้ต้องมีการอัปเดตรหัส เริ่มต้นด้วยการต่อแบบฟอร์มในแอปเพื่อเขียน Entry
รายการใหม่ไปยัง Firestore
ขั้นตอนระดับสูงในการส่ง Entry
คือ:
- ผู้ใช้กรอกแบบฟอร์มแล้วกดปุ่ม
Submit
- UI เรียก
AppState.writeEntryToFirebase
-
AppState.writeEntryToFirebase
เพิ่มรายการลงใน Firebase
ไม่จำเป็นต้องเปลี่ยนแปลงรหัสใดที่เกี่ยวข้องกับขั้นตอนที่ 1 หรือ 2 รหัสเดียวที่ต้องเพิ่มสำหรับขั้นตอนที่ 3 จะถูกเพิ่มในคลาส AppState
ทำการเปลี่ยนแปลงต่อไปนี้เป็น 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, }); } // ... }
โค้ดในเมธอด writeEntryToFirebase ดึงการอ้างอิงถึงคอลเลกชันชื่อ "Entries" ใน Firestore จากนั้นจะเพิ่มรายการใหม่ซึ่งจะต้องเป็นประเภท Map<String, String>
ในกรณีนี้ ไม่มีคอลเล็กชัน "รายการ" ใน Firestore ดังนั้น Firestore จึงสร้างขึ้นมา
เมื่อเพิ่มโค้ดดังกล่าวแล้ว ให้โหลดซ้ำหรือรีสตาร์ทแอปของคุณ เข้าสู่ระบบ และนำทางไปยังมุมมอง EntryForm
คุณสามารถกรอกแบบฟอร์มด้วย Strings
อะไรก็ได้ที่คุณต้องการ (ฟิลด์ Date จะใช้สตริงใดๆ เนื่องจากถูกทำให้ง่ายขึ้นสำหรับ codelab นี้ ฟิลด์นี้ไม่มีการตรวจสอบที่เข้มงวดหรือสนใจเกี่ยวกับออบเจ็กต์ DateTime
แต่อย่างใด)
กดส่งแบบฟอร์ม จะไม่มีอะไรเกิดขึ้นในแอป แต่คุณสามารถดูรายการใหม่ของคุณได้ใน UI ของโปรแกรมจำลอง
แท็บคำขอในโปรแกรมจำลอง Firestore
ใน UI ให้ไปที่โปรแกรมจำลอง Firestore และดูที่แท็บ "ข้อมูล" คุณจะเห็นว่าขณะนี้มีคอลเลกชันที่รากของฐานข้อมูลของคุณที่เรียกว่า "รายการ" ซึ่งควรมีเอกสารที่มีข้อมูลเดียวกันกับที่คุณกรอกลงในแบบฟอร์ม
นั่นเป็นการยืนยันว่า AppState.writeEntryToFirestore
ทำงาน และตอนนี้คุณสามารถสำรวจคำขอเพิ่มเติมได้ในแท็บคำขอ คลิกแท็บนั้นทันที
คำขอโปรแกรมจำลอง Firestore
ที่นี่ คุณควรเห็นรายการที่มีลักษณะดังนี้:
คุณสามารถคลิกเข้าไปในรายการเหล่านั้นและดูข้อมูลที่เป็นประโยชน์ได้ไม่น้อย คลิกที่รายการ CREATE
ที่สอดคล้องกับคำขอของคุณเพื่อสร้างรายการบันทึกประจำวันใหม่ คุณจะเห็นตารางใหม่ที่มีลักษณะดังนี้:
ตามที่กล่าวไว้ โปรแกรมจำลอง Firestore มีเครื่องมือในการพัฒนากฎความปลอดภัยของแอปของคุณ มุมมองนี้แสดงให้เห็นว่าคำขอนี้ผ่านบรรทัดใดในกฎความปลอดภัยของคุณ (หรือล้มเหลว หากเป็นเช่นนั้น) ในแอปที่แข็งแกร่งยิ่งขึ้น กฎความปลอดภัยสามารถขยายได้และมีการตรวจสอบการอนุญาตหลายครั้ง มุมมองนี้ใช้เพื่อช่วยเขียนและดีบักกฎการอนุญาตเหล่านั้น
นอกจากนี้ยังมอบวิธีง่ายๆ ในการตรวจสอบคำขอทุกชิ้น รวมถึงข้อมูลเมตาและข้อมูลการตรวจสอบสิทธิ์ ข้อมูลนี้ใช้เพื่อเขียนกฎการให้สิทธิ์ที่ซับซ้อน
อ่านจาก Firestore
Firestore ใช้การซิงโครไนซ์ข้อมูลเพื่อส่งข้อมูลที่อัปเดตไปยังอุปกรณ์ที่เชื่อมต่อ ในโค้ด Flutter คุณสามารถฟัง (หรือสมัคร) คอลเลกชันและเอกสารของ Firestore และโค้ดของคุณจะได้รับแจ้งทุกครั้งที่ข้อมูลมีการเปลี่ยนแปลง ในแอพนี้ การฟังการอัปเดต Firestore ทำได้ในวิธีที่เรียกว่า AppState._listenForEntries
รหัสนี้ทำงานร่วมกับ StreamController
และ Stream
ชื่อ AppState._entriesStreamController
และ AppState.entries
ตามลำดับ รหัสนั้นเขียนไว้แล้ว เช่นเดียวกับรหัสทั้งหมดที่จำเป็นใน UI เพื่อแสดงข้อมูลจาก Firestore
อัปเดตเมธอด _listenForEntries
ให้ตรงกับโค้ดด้านล่าง:
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); }); } // ... }
รหัสนี้จะฟังคอลเลกชัน "รายการ" ใน Firestore เมื่อ Firestore แจ้งเตือนไคลเอ็นต์นี้ว่ามีข้อมูลใหม่ มันจะส่งข้อมูลนั้นและโค้ดใน _listenForEntries
จะเปลี่ยนเอกสารย่อยทั้งหมดเป็นวัตถุที่แอปของเราสามารถใช้ได้ ( Entry
) จากนั้นจะเพิ่มรายการเหล่านั้นลงใน StreamController
ชื่อ _entriesStreamController
(ซึ่ง UI กำลังฟังอยู่) รหัสนี้เป็นเพียงการอัปเดตที่จำเป็นเท่านั้น
สุดท้ายนี้ อย่าลืมว่าเมธอด AppState.logIn
ทำการเรียก _listenForEntries
ซึ่งจะเริ่มกระบวนการฟังหลังจากที่ผู้ใช้เข้าสู่ระบบแล้ว
// ... 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!'); } } // ...
ตอนนี้เรียกใช้แอป มันควรมีลักษณะเช่นนี้:
7. ส่งออกและนำเข้าข้อมูลลงในโปรแกรมจำลอง
โปรแกรมจำลอง Firebase รองรับการนำเข้าและส่งออกข้อมูล การใช้การนำเข้าและส่งออกช่วยให้คุณสามารถดำเนินการพัฒนาต่อไปด้วยข้อมูลเดียวกันเมื่อคุณหยุดพักจากการพัฒนาแล้วดำเนินการต่อ คุณยังสามารถคอมมิตไฟล์ข้อมูลไปที่ git ได้ และนักพัฒนารายอื่นๆ ที่คุณร่วมงานด้วยก็จะมีข้อมูลเดียวกันที่จะใช้งานด้วย
ส่งออกข้อมูลโปรแกรมจำลอง
ขั้นแรก ให้ส่งออกข้อมูลโปรแกรมจำลองที่คุณมีอยู่แล้ว ในขณะที่โปรแกรมจำลองยังคงทำงานอยู่ ให้เปิดหน้าต่างเทอร์มินัลใหม่แล้วป้อนคำสั่งต่อไปนี้:
firebase emulators:export ./emulators_data
.emulators_data
เป็นอาร์กิวเมนต์ที่บอก Firebase ว่าจะส่งออกข้อมูลไปที่ใด หากไม่มีไดเร็กทอรีก็จะถูกสร้างขึ้น คุณสามารถใช้ชื่อใดก็ได้ที่คุณต้องการสำหรับไดเรกทอรีนั้น
เมื่อคุณรันคำสั่งนี้ คุณจะเห็นเอาต์พุตนี้ในเทอร์มินัลที่คุณรันคำสั่ง:
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
และหากคุณสลับไปที่หน้าต่างเทอร์มินัลที่โปรแกรมจำลองทำงานอยู่ คุณจะเห็นผลลัพธ์นี้:
i emulators: Received export request. Exporting data to /Users/ewindmill/Repos/codelabs/firebase-emulator-suite/complete/emulators_data. ✔ emulators: Export complete.
และสุดท้าย หากคุณดูในไดเร็กทอรีโปรเจ็กต์ของคุณ คุณจะเห็นไดเร็กทอรีชื่อ ./emulators_data
ซึ่งมีไฟล์ JSON
รวมถึงไฟล์ข้อมูลเมตาอื่นๆ พร้อมด้วยข้อมูลที่คุณบันทึกไว้
นำเข้าข้อมูลโปรแกรมจำลอง
ตอนนี้คุณสามารถนำเข้าข้อมูลนั้นเป็นส่วนหนึ่งของเวิร์กโฟลว์การพัฒนาของคุณ และเริ่มต้นจากจุดที่คุณค้างไว้ได้
ขั้นแรก ให้หยุดโปรแกรมจำลองหากกำลังทำงานอยู่โดยกด CTRL+C
ในเทอร์มินัลของคุณ
จากนั้น รันคำสั่ง emulators:start
ที่คุณเห็นแล้ว แต่มีแฟล็กบอกว่าข้อมูลใดที่จะนำเข้า:
firebase emulators:start --import ./emulators_data
เมื่ออีมูเลเตอร์ทำงานแล้ว ให้ไปที่ UI ของอีมูเลเตอร์ที่ localhost:4000
และคุณจะเห็นข้อมูลเดียวกับที่คุณเคยใช้งานก่อนหน้านี้
ส่งออกข้อมูลโดยอัตโนมัติเมื่อปิดโปรแกรมจำลอง
คุณยังสามารถส่งออกข้อมูลได้โดยอัตโนมัติเมื่อคุณออกจากโปรแกรมจำลอง แทนที่จะต้องจำส่งออกข้อมูลเมื่อสิ้นสุดเซสชันการพัฒนาทุกครั้ง
เมื่อคุณเริ่มโปรแกรมจำลอง ให้รันคำสั่ง emulators:start
พร้อมกับแฟล็กเพิ่มเติมอีกสองรายการ
firebase emulators:start --import ./emulators_data --export-on-exit
เอาล่ะ! ตอนนี้ข้อมูลของคุณจะถูกบันทึกและโหลดซ้ำทุกครั้งที่คุณทำงานกับโปรแกรมจำลองสำหรับโปรเจ็กต์นี้ คุณยังสามารถระบุไดเร็กทอรีอื่นเป็นอาร์กิวเมนต์ให้กับ –export-on-exit flag
ได้ แต่จะใช้ค่าเริ่มต้นเป็นไดเร็กทอรีที่ส่งไปยัง –import
คุณสามารถใช้ตัวเลือกเหล่านี้ผสมกันแบบใดก็ได้เช่นกัน นี่คือ หมายเหตุจากเอกสาร : สามารถระบุ firebase emulators:start --export-on-exit=./saved-data
หากใช้ --import
เส้นทางการส่งออกจะมีค่าเริ่มต้นเหมือนกัน ตัวอย่างเช่น: firebase emulators:start --import=./data-path --export-on-exit
สุดท้าย หากต้องการ ให้ส่งเส้นทางไดเร็กทอรีที่แตกต่างกันไปยังแฟล็ก --import
และ --export-on-exit
8. ขอแสดงความยินดี!
คุณได้เริ่มต้นใช้งาน Firebase emulator และ Flutter เรียบร้อยแล้ว คุณสามารถค้นหาโค้ดที่เสร็จสมบูรณ์แล้วสำหรับ Codelab นี้ได้ในไดเร็กทอรี "สมบูรณ์" บน github: Flutter Codelabs
สิ่งที่เราได้กล่าวถึง
- การตั้งค่าแอพ Flutter เพื่อใช้ Firebase
- การตั้งค่าโครงการ Firebase
- FlutterFire CLI
- Firebase CLI
- โปรแกรมจำลองการรับรองความถูกต้องของ Firebase
- โปรแกรมจำลอง Firebase Firestore
- การนำเข้าและส่งออกข้อมูลโปรแกรมจำลอง
ขั้นตอนถัดไป
- เรียนรู้เพิ่มเติมเกี่ยวกับการใช้ Firestore และการรับรองความถูกต้องใน Flutter: ทำความรู้จักกับ Firebase สำหรับ Flutter Codelab
- สำรวจเครื่องมือ Firebase อื่นๆ ที่มีโปรแกรมจำลอง:
- การจัดเก็บเมฆ
- ฟังก์ชั่นคลาวด์
- ฐานข้อมูลเรียลไทม์
- สำรวจ FlutterFire UI เพื่อเพิ่ม Google Authentication ให้กับแอปของคุณอย่างรวดเร็ว
เรียนรู้เพิ่มเติม
- ไซต์ Firebase: firebase.google.com
- เว็บไซต์กระพือ: flutter.dev
- วิดเจ็ต FlutterFire Firebase Flutter: firebase.flutter.dev
- ช่อง YouTube ของ Firebase
- ช่องยูทูปกระพือ
สปาร์กี้ภูมิใจในตัวคุณ!