เพิ่มโฟลว์การตรวจสอบสิทธิ์ผู้ใช้ให้กับแอป Flutter โดยใช้ FirebaseUI

1. ก่อนที่คุณจะเริ่ม

ใน Codelab นี้ คุณจะได้เรียนรู้วิธีเพิ่ม Firebase Authentication ให้กับแอป Flutter ของคุณโดยใช้แพ็คเกจ FlutterFire UI ด้วยแพ็คเกจนี้ คุณจะเพิ่มทั้งการตรวจสอบอีเมล/รหัสผ่าน และการตรวจสอบการลงชื่อเข้าใช้ Google ให้กับแอป Flutter คุณยังจะได้เรียนรู้วิธีตั้งค่าโปรเจ็กต์ Firebase และใช้ FlutterFire CLI เพื่อเริ่มต้น Firebase ในแอป Flutter ของคุณ

ข้อกำหนดเบื้องต้น

Codelab นี้ถือว่าคุณมีประสบการณ์ Flutter มาบ้างแล้ว ถ้าไม่ คุณอาจต้องการเรียนรู้พื้นฐานก่อน ลิงก์ต่อไปนี้มีประโยชน์:

คุณควรมีประสบการณ์ Firebase บ้าง แต่ก็ไม่เป็นไรหากคุณไม่เคยเพิ่ม Firebase ในโครงการ Flutter หากคุณไม่คุ้นเคยกับคอนโซล Firebase หรือคุณเพิ่งเคยใช้ Firebase มาก่อน โปรดดูลิงก์ต่อไปนี้ก่อน:

สิ่งที่คุณจะสร้าง

Codelab นี้แนะนำคุณตลอดการสร้างขั้นตอนการตรวจสอบสิทธิ์สำหรับแอป Flutter โดยใช้ Firebase สำหรับการตรวจสอบสิทธิ์ แอปพลิเคชันจะมีหน้าจอเข้าสู่ระบบ หน้าจอ 'ลงทะเบียน' หน้าจอการกู้คืนรหัสผ่าน และหน้าจอโปรไฟล์ผู้ใช้

6604fc9157f2c6ae.pngeab9509a41074930.pngda49189a5838e0bb.pngb2ccfb3632b77878.png

สิ่งที่คุณจะได้เรียนรู้

Codelab นี้ครอบคลุมถึง:

  • การเพิ่ม Firebase ให้กับแอป Flutter
  • การตั้งค่าคอนโซล Firebase
  • การใช้ Firebase CLI เพื่อเพิ่ม Firebase ให้กับแอปพลิเคชันของคุณ
  • การใช้ FlutterFire CLI เพื่อสร้างการกำหนดค่า Firebase ใน Dart
  • การเพิ่มการรับรองความถูกต้องของ Firebase ให้กับแอป Flutter ของคุณ
  • การตั้งค่าการตรวจสอบสิทธิ์ Firebase ในคอนโซล
  • การเพิ่มการลงชื่อเข้าใช้อีเมลและรหัสผ่านด้วยแพ็คเกจ firebase_ui_auth
  • การเพิ่มการลงทะเบียนผู้ใช้ด้วยแพ็คเกจ firebase_ui_auth
  • เพิ่มข้อความ 'ลืมรหัสผ่าน?' หน้าหนังสือ
  • การเพิ่มการลงชื่อเข้าใช้ Google ด้วย firebase_ui_auth
  • การกำหนดค่าแอปของคุณให้ทำงานร่วมกับผู้ให้บริการลงชื่อเข้าใช้หลายราย
  • การเพิ่มหน้าจอโปรไฟล์ผู้ใช้ลงในแอปพลิเคชันของคุณด้วยแพ็คเกจ firebase_ui_auth

Codelab นี้เกี่ยวข้องโดยเฉพาะกับการเพิ่มระบบการตรวจสอบสิทธิ์ที่มีประสิทธิภาพโดยใช้แพ็คเกจ firebase_ui_auth อย่างที่คุณเห็น แอปทั้งหมดนี้พร้อมฟีเจอร์ทั้งหมดข้างต้น สามารถนำไปใช้งานได้ด้วยโค้ดประมาณ 100 บรรทัด

สิ่งที่คุณต้องการ

  • ความรู้เกี่ยวกับการทำงานของ Flutter และติดตั้ง SDK แล้ว
  • โปรแกรมแก้ไขข้อความ (JetBrains IDE's, Android Studio และ VS Code ได้รับการสนับสนุนโดย Flutter)
  • เบราว์เซอร์ Google Chrome หรือเป้าหมายการพัฒนาอื่น ๆ ที่คุณต้องการสำหรับ Flutter (คำสั่งเทอร์มินัลบางคำสั่งใน Codelab นี้จะถือว่าคุณใช้งานแอปบน Chrome)

2. สร้างและตั้งค่าโปรเจ็กต์ Firebase

งานแรกที่คุณต้องทำให้เสร็จคือการสร้างโปรเจ็กต์ Firebase ในเว็บคอนโซลของ Firebase

สร้างโปรเจ็กต์ Firebase

  1. ลงชื่อเข้าใช้ Firebase
  2. ในคอนโซล Firebase คลิก เพิ่มโปรเจ็กต์ (หรือ สร้างโปรเจ็กต์ ) แล้วป้อนชื่อโปรเจ็กต์ Firebase ของคุณ (เช่น " FlutterFire-UI-Codelab ")

df42a5e3d9584b48.png

  1. คลิกผ่านตัวเลือกการสร้างโครงการ ยอมรับข้อกำหนดของ Firebase หากได้รับแจ้ง ข้ามการตั้งค่า Google Analytics เนื่องจากคุณจะไม่ใช้ Analytics สำหรับแอปนี้

d1fcec48bf251eaa.png

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับโครงการ Firebase โปรดดู ทำความเข้าใจโครงการ Firebase

แอปที่คุณกำลังสร้างใช้ Firebase Authentication เพื่อให้ผู้ใช้สามารถลงชื่อเข้าใช้แอปของคุณได้ นอกจากนี้ยังอนุญาตให้ผู้ใช้ใหม่ลงทะเบียนจากแอปพลิเคชัน Flutter

จำเป็นต้องเปิดใช้งาน การตรวจสอบสิทธิ์ Firebase โดยใช้คอนโซล Firebase และต้องมีการกำหนดค่าพิเศษเมื่อเปิดใช้งาน

เปิดใช้งานการลงชื่อเข้าใช้อีเมลสำหรับการตรวจสอบสิทธิ์ Firebase

หากต้องการอนุญาตให้ผู้ใช้ลงชื่อเข้าใช้เว็บแอป คุณจะต้องใช้วิธีการลงชื่อเข้าใช้ อีเมล/รหัส ผ่านก่อน หลังจากนั้น คุณจะต้องเพิ่มวิธี การลงชื่อเข้าใช้ Google

  1. ในคอนโซล Firebase ให้ขยายเมนู Build ในแผงด้านซ้าย
  2. คลิก การรับรองความถูกต้อง จากนั้นคลิกปุ่ม เริ่มต้น จากนั้นคลิกแท็บ วิธีการลงชื่อเข้าใช้ (หรือ คลิกที่นี่ เพื่อไปที่ แท็บ วิธีการลงชื่อเข้าใช้ โดยตรง)
  3. คลิก อีเมล/รหัสผ่าน ในรายการ ผู้ให้บริการลงชื่อเข้า ใช้ ตั้งสวิตช์ เปิดใช้งาน ไปที่ตำแหน่งเปิด จากนั้นคลิก บันทึก 58e3e3e23c2f16a4.png

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-auth-flutterfire-ui

ไดเร็กทอรี flutter-codelabs/firebase-auth-flutterfire-ui มีสองโปรเจ็กต์ Flutter อันหนึ่งเรียกว่า complete และอีกอันเรียกว่า start ไดเร็กทอรี start มีโปรเจ็กต์ที่ไม่สมบูรณ์ และเป็นที่ที่คุณจะใช้เวลามากที่สุด

cd flutter-codelabs/firebase-auth-flutterfire-ui/start

หากคุณต้องการข้ามไปข้างหน้า หรือดูว่าบางสิ่งควรมีลักษณะอย่างไรเมื่อเสร็จสมบูรณ์ ให้ดูในไดเร็กทอรีที่ชื่อเสร็จสมบูรณ์เพื่อการอ้างอิงโยง

หากคุณต้องการติดตาม Codelab และเพิ่มโค้ดด้วยตนเอง คุณควรเริ่มต้นด้วยแอป Flutter ที่ flutter-codelabs/firebase-auth-flutterfire-ui/start และเพิ่มโค้ดลงในโปรเจ็กต์นั้นทั่วทั้ง Codelab เปิดหรือนำเข้าไดเร็กทอรีนั้นไปยัง IDE ที่คุณต้องการ

ติดตั้ง Firebase CLI

Firebase CLI มีเครื่องมือสำหรับจัดการโปรเจ็กต์ Firebase ของคุณ CLI จำเป็นสำหรับ FlutterFire CLI ซึ่งคุณจะติดตั้งในอีกสักครู่

มีหลายวิธีในการติดตั้ง CLI วิธีที่ง่ายที่สุด หากคุณใช้ MacOS หรือ Linux คือการรันคำสั่งนี้จากเทอร์มินัลของคุณ:

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

หลังจากติดตั้ง CLI คุณต้องตรวจสอบสิทธิ์กับ Firebase

  1. เข้าสู่ระบบ Firebase โดยใช้บัญชี Google ของคุณโดยเรียกใช้คำสั่งต่อไปนี้:
firebase login
  1. คำสั่งนี้จะเชื่อมต่อเครื่องในเครื่องของคุณกับ Firebase และให้สิทธิ์คุณในการเข้าถึงโปรเจ็กต์ Firebase ของคุณ
  1. ทดสอบว่าติดตั้ง CLI อย่างถูกต้องและเข้าถึงบัญชีของคุณได้โดยแสดงรายการโปรเจ็กต์ Firebase ของคุณ รันคำสั่งต่อไปนี้:
firebase projects:list
  1. รายการที่แสดงควรเหมือนกับโครงการ Firebase ที่แสดงอยู่ใน คอนโซล Firebase คุณควรเห็นอย่างน้อย flutterfire-ui-codelab.

ติดตั้ง FlutterFire CLI

FlutterFire CLI เป็นเครื่องมือที่ช่วยให้กระบวนการติดตั้ง Firebase ง่ายขึ้นบนแพลตฟอร์มที่รองรับทั้งหมดในแอป Flutter ของคุณ มันสร้างขึ้นบน Firebase CLI

ขั้นแรก ให้ติดตั้ง CLI:

dart pub global activate flutterfire_cli

ตรวจสอบให้แน่ใจว่าได้ติดตั้ง CLI แล้ว รันคำสั่งต่อไปนี้และตรวจสอบให้แน่ใจว่า CLI ส่งออกเมนูวิธีใช้

flutterfire -—help

เพิ่มโปรเจ็กต์ Firebase ของคุณลงในแอป Flutter

กำหนดค่า FlutterFire

คุณสามารถใช้ FlutterFire เพื่อสร้างโค้ด Dart ที่จำเป็นเพื่อใช้ Firebase ในแอป Flutter ของคุณ

flutterfire configure

เมื่อเรียกใช้คำสั่งนี้ คุณจะได้รับแจ้งให้เลือกโปรเจ็กต์ Firebase ที่คุณต้องการใช้ และแพลตฟอร์มที่คุณต้องการตั้งค่า

ภาพหน้าจอต่อไปนี้แสดงพร้อมท์ที่คุณจะต้องตอบ

  1. เลือกโครงการที่คุณต้องการใช้ ในกรณีนี้ ให้ใช้ flutterfire-ui-codelab 1359cdeb83204baa.png
  2. เลือกแพลตฟอร์มที่คุณต้องการใช้ ใน Codelab นี้ มีขั้นตอนในการกำหนดค่า Firebase Authentication สำหรับ Flutter สำหรับเว็บ, iOS และ Android แต่คุณสามารถตั้งค่าโปรเจ็กต์ Firebase ให้ใช้ตัวเลือกทั้งหมดได้ 301c9534f594f472.png
  3. ภาพหน้าจอนี้แสดงผลลัพธ์เมื่อสิ้นสุดกระบวนการ หากคุณคุ้นเคยกับ Firebase คุณจะสังเกตเห็นว่าคุณไม่จำเป็นต้องสร้างแอปพลิเคชันแพลตฟอร์ม (เช่น แอปพลิเคชัน Android) ในคอนโซล และ FlutterFire CLI ก็ทำเพื่อคุณ 12199a85ade30459.png

เมื่อดำเนินการเสร็จแล้ว ให้ดูที่แอป Flutter ในโปรแกรมแก้ไขข้อความของคุณ FlutterFire CLI ได้สร้างไฟล์ใหม่ชื่อ firebase_options.dart ไฟล์นี้มีคลาสชื่อ FirebaseOptions ซึ่งมีตัวแปรคงที่ที่เก็บการกำหนดค่า Firebase ที่จำเป็นสำหรับแต่ละแพลตฟอร์ม หากคุณเลือกแพลตฟอร์มทั้งหมดเมื่อคุณรัน flutterfire configure คุณจะเห็นค่าคงที่ชื่อ web , android , ios และ macos

firebase_options.dart

import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
   show defaultTargetPlatform, kIsWeb, TargetPlatform;

/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
///   options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
 static FirebaseOptions get currentPlatform {
   if (kIsWeb) {
     return web;
   }
   // ignore: missing_enum_constant_in_switch
   switch (defaultTargetPlatform) {
     case TargetPlatform.android:
       return android;
     case TargetPlatform.iOS:
       return ios;
     case TargetPlatform.macOS:
       return macos;
   }

   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.appspot.com',
   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.appspot.com',
 );

 static const FirebaseOptions ios = FirebaseOptions(
   apiKey: 'AIzaSyBqLWsqFjYAdGyihKTahMRDQMo0N6NVjAs',
   appId: '1:963656261848:ios:d9e01cfe8b675dfcb237ad',
   messagingSenderId: '963656261848',
   projectId: 'flutterfire-ui-codelab',
   storageBucket: 'flutterfire-ui-codelab.appspot.com',
   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.appspot.com',
   iosClientId: '963656261848-v7r3vq1v6haupv0l1mdrmsf56ktnua60.apps.googleusercontent.com',
   iosBundleId: 'com.example.complete',
 );
}

Firebase ใช้คำว่า แอปพลิเคชัน เพื่ออ้างถึงบิวด์เฉพาะสำหรับแพลตฟอร์มเฉพาะในโปรเจ็กต์ Firebase ตัวอย่างเช่น โครงการ Firebase ชื่อ FlutterFire-ui-codelab มีแอปพลิเคชันหลายตัว: หนึ่งรายการสำหรับ Android หนึ่งรายการสำหรับ iOS หนึ่งรายการสำหรับ MacOS และอีกรายการหนึ่งสำหรับเว็บ

วิธี DefaultFirebaseOptions.currentPlatform ใช้ TargetPlatform enum ที่เปิดเผยโดย Flutter เพื่อตรวจจับแพลตฟอร์มที่แอปของคุณทำงานอยู่ จากนั้นส่งคืนค่าการกำหนดค่า Firebase ที่จำเป็นสำหรับแอปพลิเคชัน Firebase ที่ถูกต้อง

เพิ่มแพ็คเกจ Firebase ให้กับแอพ Flutter

ขั้นตอนการตั้งค่าสุดท้ายคือการเพิ่มแพ็คเกจ Firebase ที่เกี่ยวข้องให้กับโปรเจ็กต์ Flutter ของคุณ ไฟล์ firebase_options.dart ควรมีข้อผิดพลาด เนื่องจากต้องใช้แพ็คเกจ Firebase ที่ยังไม่ได้เพิ่ม ในเทอร์มินัล ตรวจสอบให้แน่ใจว่าคุณอยู่ในรูทของโปรเจ็กต์ Flutter ที่ flutter-codelabs/firebase-emulator-suite/start จากนั้นรันคำสั่งสามคำสั่งต่อไปนี้:

flutter pub add firebase_core
flutter pub add firebase_auth
flutter pub add firebase_ui_auth

นี่เป็นแพ็คเกจเดียวที่คุณต้องการ ณ จุดนี้

เริ่มต้น Firebase

เพื่อที่จะใช้แพ็คเกจที่เพิ่มและ DefaultFirebaseOptions.currentPlatform, ให้อัพเดตโค้ดในฟังก์ชัน main ในไฟล์ main.dart

main.โผ

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


 runApp(const MyApp());
}

รหัสนี้ทำสองสิ่ง

  1. WidgetsFlutterBinding.ensureInitialized() บอก Flutter ว่าอย่าเริ่มรันโค้ดวิดเจ็ตแอปพลิเคชันจนกว่าเฟรมเวิร์ก Flutter จะถูกบูทโดยสมบูรณ์ Firebase ใช้ช่องทางแพลตฟอร์มดั้งเดิมซึ่งต้องใช้เฟรมเวิร์กในการทำงาน
  2. Firebase.initializeApp ตั้งค่าการเชื่อมต่อระหว่างแอพ Flutter และโปรเจ็กต์ Firebase ของคุณ DefaultFirebaseOptions.currentPlatform ถูกนำเข้าจากไฟล์ firebase_options.dart ที่เราสร้างขึ้น ค่าคงที่นี้จะตรวจจับแพลตฟอร์มที่คุณใช้งานอยู่ และส่งผ่านคีย์ Firebase ที่เกี่ยวข้อง

4. เพิ่มหน้า Firebase UI Auth เริ่มต้น

Firebase UI สำหรับ Auth มีวิดเจ็ตที่แสดงทั้งหน้าจอในแอปพลิเคชันของคุณ หน้าจอเหล่านี้จัดการขั้นตอนการรับรองความถูกต้องที่แตกต่างกันทั่วทั้งแอปพลิเคชันของคุณ เช่น การลงชื่อเข้าใช้ การลงทะเบียน ลืมรหัสผ่าน โปรไฟล์ผู้ใช้ และอื่นๆ ในการเริ่มต้น ให้เพิ่มหน้า Landing Page ให้กับแอปของคุณซึ่งทำหน้าที่เป็นตัวป้องกันการตรวจสอบสิทธิ์ให้กับแอปพลิเคชันหลัก

วัสดุหรือแอป Cupertino

FlutterFire UI ต้องการให้แอปพลิเคชันของคุณรวมอยู่ใน MaterialApp หรือ CupertinoApp UI จะแสดงความแตกต่างของวิดเจ็ต Material หรือ Cupertino โดยอัตโนมัติ ทั้งนี้ขึ้นอยู่กับตัวเลือกของคุณ สำหรับ Codelab นี้ ให้ใช้ MaterialApp ซึ่งเพิ่มลงในแอปใน app.dart แล้ว

แอพ.โผ

import 'package:flutter/material.dart';
import 'auth_gate.dart';

class MyApp extends StatelessWidget {
 const MyApp({super.key});
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     theme: ThemeData(
       primarySwatch: Colors.blue,
     ),
     home: const AuthGate(),
   );
 }
}

ตรวจสอบสถานะการรับรองความถูกต้อง

ก่อนที่คุณจะสามารถแสดงหน้าจอลงชื่อเข้าใช้ได้ คุณต้องพิจารณาว่าผู้ใช้ได้รับการรับรองความถูกต้องในปัจจุบันหรือไม่ วิธีที่พบบ่อยที่สุดในการตรวจสอบสิ่งนี้คือการฟัง authStateChanges ของ FirebaseAuth โดยใช้ ปลั๊กอิน Firebase Auth

ในตัวอย่างโค้ดด้านบน MaterialApp กำลังสร้างวิดเจ็ต AuthGate ในวิธีการสร้าง (นี่คือวิดเจ็ตแบบกำหนดเอง ซึ่งไม่ได้มาจาก FlutterFire UI)

วิดเจ็ตนั้นจำเป็นต้องได้รับการอัปเดตเพื่อรวมสตรีม authStateChanges

authStateChanges API ส่งคืน Stream พร้อมกับผู้ใช้ปัจจุบัน (หากลงชื่อเข้าใช้) หรือคืนค่าเป็นค่าว่างหากไม่ได้ลงชื่อเข้าใช้ หากต้องการสมัครรับสถานะนี้ในแอปพลิเคชันของเรา คุณสามารถใช้วิดเจ็ต StreamBuilder ของ Flutter และส่งสตรีมไปให้ได้

StreamBuilder เป็นวิดเจ็ตที่สร้างตัวเองตามสแน็ปช็อตข้อมูลล่าสุดจาก สตรีม ที่คุณส่งผ่าน โดยจะสร้างใหม่โดยอัตโนมัติเมื่อ Stream ส่งสแน็ปช็อตใหม่

อัปเดตโค้ดใน auth_gate.dart

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});

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<User?>(
      stream: FirebaseAuth.instance.authStateChanges(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          return SignInScreen(
            providers: [],
          );
        }

        return const HomeScreen();
      },
    );
  }
}
  • StreamBuilder.stream กำลังถูกส่งผ่าน FirebaseAuth.instance.authStateChanged ซึ่งเป็นสตรีมดังกล่าว ซึ่งจะส่งคืนออบเจ็กต์ Firebase User หากผู้ใช้ตรวจสอบสิทธิ์แล้ว (มิฉะนั้นจะคืน null )
  • ถัดไป โค้ดใช้ snapshot.hasData เพื่อตรวจสอบว่าค่าจากสตรีมมีออบเจ็กต์ User หรือไม่
  • หากไม่มี ก็จะส่งคืนวิดเจ็ต SignInScreen ขณะนี้หน้าจอนั้นจะไม่ทำอะไรเลย สิ่งนี้จะได้รับการปรับปรุงในขั้นตอนถัดไป
  • มิฉะนั้นจะส่งคืน HomeScreen ซึ่งเป็นส่วนหลักของแอปพลิเคชันที่สามารถเข้าถึงได้เฉพาะผู้ใช้ที่ได้รับการรับรองความถูกต้องเท่านั้น

SignInScreen เป็นวิดเจ็ตที่มาจากแพ็คเกจ FlutterFire UI นี่จะเป็นจุดเน้นของขั้นตอนถัดไปของ Codelab นี้ เมื่อคุณเรียกใช้แอป ณ จุดนี้ คุณจะเห็นหน้าจอลงชื่อเข้าใช้ว่างเปล่า

5. หน้าจอลงชื่อเข้าใช้

วิดเจ็ต SignInScreen จัดทำโดย FlutterFire UI เพิ่มฟังก์ชันการทำงานต่อไปนี้:

  • อนุญาตให้ผู้ใช้ลงชื่อเข้าใช้
  • หากผู้ใช้ลืมรหัสผ่าน พวกเขาสามารถแตะ "ลืมรหัสผ่าน" และถูกนำไปที่แบบฟอร์มเพื่อรีเซ็ตรหัสผ่าน
  • หากผู้ใช้ยังไม่ได้ลงทะเบียน พวกเขาสามารถแตะ "ลงทะเบียน" และจะถูกพาไปยังแบบฟอร์มอื่นที่อนุญาตให้ผู้ใช้ลงทะเบียนได้

ขอย้ำอีกครั้งว่าต้องใช้โค้ดเพียงไม่กี่บรรทัด เรียกคืนรหัสในวิดเจ็ต AuthGate:

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});

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<User?>(
      stream: FirebaseAuth.instance.authStateChanges(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          return SignInScreen(
            providers: [
              EmailAuthProvider(), // new
            ],
          );
        }

        return const HomeScreen();
      },
    );
  }
}

วิดเจ็ต SignInScreen และอาร์กิวเมนต์ของ providers เป็นโค้ดเดียวที่จำเป็นในการรับฟังก์ชันการทำงานทั้งหมดที่กล่าวมาข้างต้น ตอนนี้คุณควรเห็นหน้าจอลงชื่อเข้าใช้ที่มีการป้อนข้อความ 'อีเมล' และ 'รหัสผ่าน' รวมถึงปุ่ม 'ลงชื่อเข้าใช้'

แม้จะใช้งานได้จริง แต่ก็ขาดสไตล์ วิดเจ็ตจะแสดงพารามิเตอร์เพื่อปรับแต่งรูปลักษณ์ของหน้าจอลงชื่อเข้าใช้ ตัวอย่างเช่น คุณอาจต้องการเพิ่มโลโก้ของบริษัทของคุณ

ปรับแต่งหน้าจอลงชื่อเข้าใช้

headerBuilder

เมื่อใช้อาร์กิวเมนต์ SignInScreen.headerBuilder คุณสามารถเพิ่มวิดเจ็ตใดก็ได้ที่คุณต้องการไว้เหนือแบบฟอร์มลงชื่อเข้าใช้ อัปเดตไฟล์ auth_gate.dart ด้วยรหัสนี้:

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});

 @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'),
               ),
             );
           },
         );
       }

       return const HomeScreen();
     },
   );
 }
}

อาร์กิวเมนต์ headerBuilder ต้องการฟังก์ชันประเภท HeaderBuilder ซึ่งกำหนดไว้ในแพ็คเกจ FlutterFire UI

typedef HeaderBuilder = Widget Function(
 BuildContext context,
 BoxConstraints constraints,
 double shrinkOffset,
);

เนื่องจากเป็นการโทรกลับ จึงเปิดเผยค่าที่คุณสามารถใช้ เช่น BuildContext และ BoxConstraints และกำหนดให้คุณต้องส่งคืนวิดเจ็ต วิดเจ็ตใดก็ตามที่คุณส่งคืนจะแสดงที่ด้านบนของหน้าจอ ในตัวอย่างนี้ โค้ดใหม่จะเพิ่มรูปภาพที่ด้านบนของหน้าจอ ใบสมัครของคุณควรมีลักษณะเช่นนี้

73d7548d91bbd2ab.png

ตัวสร้างคำบรรยาย

หน้าจอลงชื่อเข้าใช้จะแสดงพารามิเตอร์เพิ่มเติมสามตัวที่ช่วยให้คุณปรับแต่งหน้าจอได้: subtitleBuilder , footerBuilder และ sideBuilder

subtitleBuilder แตกต่างออกไปเล็กน้อยตรงที่อาร์กิวเมนต์การเรียกกลับมีการดำเนินการ ซึ่งเป็นประเภท AuthAction AuthAction เป็น enum ที่คุณสามารถใช้เพื่อตรวจสอบว่าหน้าจอที่ผู้ใช้อยู่เป็นหน้าจอ "ลงชื่อเข้าใช้" หรือหน้าจอ "ลงทะเบียน"

อัปเดตโค้ดใน auth_gate.dart เพื่อใช้ subtitleBuilder

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});

 @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('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!'),
             );
           },
         );
       }

       return const HomeScreen();
     },
   );
 }
}

โหลดแอปพลิเคชันซ้ำ และควรมีลักษณะเช่นนี้

อาร์กิวเมนต์ footerBuilder เหมือนกับ subtitleBuilder ไม่เปิดเผย BoxConstraints หรือ shrinkOffset เนื่องจากมีไว้สำหรับข้อความแทนที่จะเป็นรูปภาพ (แม้ว่าคุณจะสามารถเพิ่มวิดเจ็ตใดก็ได้ที่คุณต้องการก็ตาม)

เพิ่มส่วนท้ายลงในหน้าจอลงชื่อเข้าใช้ของคุณด้วยรหัสนี้

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});

 @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('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),
               ),
             );
           },
         );
       }

       return const HomeScreen();
     },
   );
 }}

ตัวสร้างด้านข้าง

อาร์กิวเมนต์ SignInScreen.sidebuilder ยอมรับการโทรกลับ และคราวนี้อาร์กิวเมนต์ของการโทรกลับนั้นคือ BuildContext และ double shrinkOffset วิดเจ็ตที่ sideBuilder ส่งคืนจะแสดงทางด้านซ้ายของแบบฟอร์มลงชื่อเข้าใช้ และเฉพาะบนหน้าจอกว้างเท่านั้น นั่นหมายความว่าวิดเจ็ตจะแสดงบนเดสก์ท็อปและเว็บแอปเท่านั้น

ภายใน FlutterFire UI ใช้เบรกพอยต์เพื่อพิจารณาว่าควรแสดงเนื้อหาส่วนหัว (บนหน้าจอสูง เช่น อุปกรณ์เคลื่อนที่) หรือควรแสดงเนื้อหาด้านข้าง (บนหน้าจอกว้าง เดสก์ท็อป หรือเว็บ) โดยเฉพาะอย่างยิ่ง หากหน้าจอมีความกว้างมากกว่า 800 พิกเซล เนื้อหาของตัวสร้างด้านข้างจะแสดงขึ้น แต่เนื้อหาส่วนหัวจะไม่แสดง หากหน้าจอกว้างน้อยกว่า 800 พิกเซล ก็จะตรงกันข้าม

อัปเดตโค้ดใน auth_gate.dart เพื่อเพิ่มวิดเจ็ต sideBuilder

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});

 @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('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();
     },
   );
 }
}

ตอนนี้แอปของคุณควรมีลักษณะเช่นนี้เมื่อคุณขยายความกว้างของหน้าต่าง (หากคุณใช้ Flutter web หรือ MacOS)

8dc60b4e5d7dd2d0.png

สร้างผู้ใช้

ณ จุดนี้ โค้ดทั้งหมดสำหรับหน้าจอนี้เสร็จสิ้นแล้ว ก่อนที่คุณจะสามารถลงชื่อเข้าใช้ได้ คุณต้องสร้างผู้ใช้ก่อน คุณสามารถทำได้ด้วยหน้าจอ "ลงทะเบียน" หรือคุณสามารถสร้างผู้ใช้ในคอนโซล Firebase

วิธีใช้คอนโซล:

  1. ไปที่ตาราง "ผู้ใช้" ในคอนโซล Firebase
  2. คลิกที่นี่
  3. เลือก 'flutterfire-ui-codelab' (หรือโครงการอื่นหากคุณใช้ชื่ออื่น) คุณจะเห็นตารางนี้:

f038fd9a58ed60d9.png

  1. คลิกปุ่ม "เพิ่มผู้ใช้"

2d78390d4c5dbbfa.png

  1. ป้อนที่อยู่อีเมลและรหัสผ่านสำหรับผู้ใช้ใหม่ นี่อาจเป็นอีเมลและรหัสผ่านปลอม ตามที่ฉันได้ป้อนไว้ในภาพด้านล่าง วิธีนี้จะได้ผล แต่ฟังก์ชัน "ลืมรหัสผ่าน" จะไม่ทำงานหากคุณใช้ที่อยู่อีเมลปลอม

62ba0feb33d54add.png

  1. คลิก "เพิ่มผู้ใช้"

32b236b3ef94d4c7.png

ตอนนี้คุณสามารถกลับไปที่แอปพลิเคชัน Flutter ของคุณและลงชื่อเข้าใช้ผู้ใช้ผ่านหน้าลงชื่อเข้าใช้ได้ แอปของคุณควรมีลักษณะดังนี้:

dd43d260537f3b1a.png

6. หน้าจอโปรไฟล์

FlutterFire UI ยังมีวิดเจ็ต ProfileScreen ซึ่งให้ฟังก์ชันการทำงานมากมายแก่คุณในโค้ดเพียงไม่กี่บรรทัด

เพิ่มวิดเจ็ต ProfileScreen

นำทางไปยังไฟล์ home.dart ในโปรแกรมแก้ไขข้อความของคุณ อัปเดตด้วยรหัสนี้:

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: [
            Image.asset('dash.png'),
            Text(
              'Welcome!',
              style: Theme.of(context).textTheme.displaySmall,
            ),
            const SignOutButton(),
          ],
        ),
      ),
    );
  }
}

รหัสบันทึกย่อใหม่คือการเรียกกลับที่ส่งผ่านไปยัง IconButton.isPressed method. เมื่อกด IconButton นั้น แอปพลิเคชันของคุณจะสร้างเส้นทางที่ไม่ระบุตัวตนใหม่และนำทางไปยังเส้นทางนั้น เส้นทางนั้นจะแสดงวิดเจ็ต ProfileScreen ซึ่งส่งคืนจากการเรียกกลับ MaterialPageRoute.builder

โหลดแอปของคุณซ้ำ และกดไอคอนที่มุมบนขวา (ในแถบแอป) จากนั้นแอปจะแสดงหน้าเว็บดังนี้:

36487fc4ab4f26a7.png

นี่คือ UI มาตรฐานที่จัดทำโดยหน้า FlutterFire UI ปุ่มและช่องข้อความทั้งหมดเชื่อมต่อกับ Firebase Auth และทำงานนอกกรอบ ตัวอย่างเช่น คุณสามารถป้อนชื่อลงในช่องข้อความ "ชื่อ" และ FlutterFire UI จะเรียกใช้เมธอด FirebaseAuth.instance.currentUser?.updateDisplayName ซึ่งจะบันทึกชื่อนั้นใน Firebase

ออกจากระบบ

ในตอนนี้ หากคุณกดปุ่ม "ออกจากระบบ" แอปจะไม่เปลี่ยนแปลง มันจะออกจากระบบ แต่คุณจะไม่ถูกนำทางกลับไปยังวิดเจ็ต AuthGate หากต้องการใช้สิ่งนี้ ให้ใช้พารามิเตอร์ ProfileScreen.actions

ขั้นแรก ให้อัปเดตโค้ดใน home.dart

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: [
            Image.asset('dash.png'),
            Text(
              'Welcome!',
              style: Theme.of(context).textTheme.displaySmall,
            ),
            const SignOutButton(),
          ],
        ),
      ),
    );
  }
}

ตอนนี้ เมื่อคุณสร้างอินสแตนซ์ของ ProfileScreen คุณจะส่งรายการการดำเนินการไปยังอาร์กิวเมนต์ ProfileScreen.actions ด้วย การดำเนินการเหล่านี้เป็นประเภท FlutterFireUiAction มีคลาสที่แตกต่างกันมากมายที่เป็นประเภทย่อยของ FlutterFireUiAction และโดยทั่วไปแล้ว คุณจะใช้คลาสเหล่านี้เพื่อบอกให้แอปของคุณตอบสนองต่อการเปลี่ยนแปลงสถานะการรับรองความถูกต้องที่แตกต่างกัน SignedOutAction เรียกใช้ฟังก์ชันการโทรกลับที่คุณให้ไว้เมื่อสถานะการรับรองความถูกต้องของ Firebase เปลี่ยนเป็นผู้ใช้ปัจจุบันเป็นค่าว่าง

ด้วยการเพิ่มการโทรกลับที่เรียก Navigator.of(context).pop() เมื่อ SignedOutAction ทริกเกอร์ แอปจะนำทางไปยังหน้าก่อนหน้า ในแอปตัวอย่างนี้ มีเส้นทางถาวรเพียงเส้นทางเดียว ซึ่งจะแสดงหน้าลงชื่อเข้าใช้หากไม่มีผู้ใช้ลงชื่อเข้าใช้ และหน้าแรกหากมีผู้ใช้ เนื่องจากสิ่งนี้เกิดขึ้นเมื่อผู้ใช้ออกจากระบบ แอปจึงจะแสดงหน้าลงชื่อเข้าใช้

ปรับแต่งหน้าโปรไฟล์

คล้ายกับหน้าลงชื่อเข้าใช้ หน้าโปรไฟล์สามารถปรับแต่งได้ ประการแรก หน้าปัจจุบันของเราไม่มีทางกลับไปยังหน้าแรกได้เมื่อผู้ใช้อยู่ในหน้าโปรไฟล์แล้ว แก้ไขปัญหานี้โดยให้ AppBar แก่วิดเจ็ต ProfileScreen

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: [
           Image.asset('dash.png'),
           Text(
             'Welcome!',
             style: Theme.of(context).textTheme.displaySmall,
           ),
           const SignOutButton(),
         ],
       ),
     ),
   );
 }
}

อาร์กิวเมนต์ ProfileScreen.appBar ยอมรับวิดเจ็ต AppBar จากแพ็คเกจ Flutter Material ดังนั้นจึงสามารถปฏิบัติได้เหมือนกับ AppBar อื่น ๆ ที่คุณสร้างและส่งผ่านไปยัง Scaffold ในตัวอย่างนี้ ฟังก์ชันเริ่มต้นของการเพิ่มปุ่ม "ย้อนกลับ" โดยอัตโนมัติจะยังคงอยู่ และตอนนี้หน้าจอก็มีชื่อแล้ว

เพิ่มเด็กลงในหน้าจอโปรไฟล์

วิดเจ็ต ProfileScreen ยังมีอาร์กิวเมนต์เผื่อเลือกชื่อลูกๆ อาร์กิวเมนต์นี้ยอมรับรายการวิดเจ็ต และวิดเจ็ตเหล่านั้นจะถูกวางในแนวตั้งภายในวิดเจ็ตคอลัมน์ที่ใช้ภายในเพื่อสร้าง ProfileScreen วิดเจ็ตคอลัมน์นี้ในวิธีการสร้าง ProfileScreen จะวางรายการย่อยที่คุณส่งต่อไว้เหนือปุ่ม "ออกจากระบบ"

อัปเดตโค้ดใน home.dart เพื่อแสดงโลโก้บริษัทที่นี่ คล้ายกับหน้าจอลงชื่อเข้าใช้

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: [
            Image.asset('dash.png'),
            Text(
              'Welcome!',
              style: Theme.of(context).textTheme.displaySmall,
            ),
            const SignOutButton(),
          ],
        ),
      ),
    );
  }
}

โหลดแอปของคุณซ้ำ แล้วคุณจะเห็นสิ่งนี้บนหน้าจอ:

ebe5792b765dbf87.png

7. การลงชื่อเข้าใช้ Google Auth หลายแพลตฟอร์ม

FlutterFire UI ยังมีวิดเจ็ตและฟังก์ชันสำหรับการตรวจสอบสิทธิ์กับผู้ให้บริการบุคคลที่สาม เช่น Google, Twitter, Facebook, Apple และ Github

หากต้องการผสานรวมกับการตรวจสอบสิทธิ์ของ Google ให้ติดตั้งปลั๊กอิน firebase_ui_oauth_google อย่างเป็นทางการและปลั๊กอินดังกล่าวซึ่งจะจัดการขั้นตอนการตรวจสอบสิทธิ์ดั้งเดิม ในเทอร์มินัล นำทางไปยังรูทของโปรเจ็กต์การกระพือของคุณแล้วป้อนคำสั่งต่อไปนี้:

flutter pub add google_sign_in
flutter pub add firebase_ui_oauth_google

เปิดใช้งานผู้ให้บริการลงชื่อเข้าใช้ Google

ถัดไป เปิดใช้งานผู้ให้บริการ Google ใน คอนโซล Firebase :

  1. ไปที่หน้าจอ ผู้ให้บริการลงชื่อเข้าใช้การตรวจสอบสิทธิ์ ในคอนโซล
  2. คลิก "เพิ่มผู้ให้บริการใหม่" 8286fb28be94bf30.png
  3. เลือก "Google" c4e28e6f4974be7f.png
  4. สลับสวิตช์ที่มีป้ายกำกับว่า "เปิดใช้งาน" แล้วกด "บันทึก" e74ff86990763826.png
  5. หากโมดอลปรากฏขึ้นพร้อมกับข้อมูลเกี่ยวกับการดาวน์โหลดไฟล์การกำหนดค่า ให้คลิก "เสร็จสิ้น"
  6. ยืนยันว่าได้เพิ่มผู้ให้บริการลงชื่อเข้าใช้ Google แล้ว 5329ce0543c90d95.png

เพิ่มปุ่มลงชื่อเข้าใช้ Google

เมื่อเปิดใช้งานการลงชื่อเข้าใช้ Google ให้เพิ่มวิดเจ็ตที่จำเป็นในการแสดงปุ่มลงชื่อเข้าใช้ Google ที่เก๋ไก๋ในหน้าลงชื่อเข้าใช้ ไปที่ไฟล์ auth_gate.dart และอัปเดตโค้ดดังต่อไปนี้:

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'; // new
import 'package:flutter/material.dart';

import 'home.dart';

class AuthGate extends StatelessWidget {
 const AuthGate({super.key});

 @override
 Widget build(BuildContext context) {
   return StreamBuilder<User?>(
     stream: FirebaseAuth.instance.authStateChanges(),
     builder: (context, snapshot) {
       if (!snapshot.hasData) {
         return SignInScreen(
           providers: [
             EmailAuthProvider(),
             GoogleProvider(clientId: "YOUR_WEBCLIENT_ID"),  // new
           ],
           headerBuilder: (context, constraints, shrinkOffset) {
             return Padding(
               padding: const EdgeInsets.all(20),
               child: AspectRatio(
                 aspectRatio: 1,
                 child: Image.asset('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();
     },
   );
 }
}

รหัสใหม่เดียวที่นี่คือการเพิ่ม GoogleProvider(clientId: "YOUR_WEBCLIENT_ID") ในการกำหนดค่าวิดเจ็ต SignInScreen

เมื่อเพิ่มแล้ว ให้โหลดแอปของคุณซ้ำ แล้วคุณจะเห็นปุ่มลงชื่อเข้าใช้ Google

aca71a46a011bfb5.png

กำหนดค่าปุ่มลงชื่อเข้าใช้

ปุ่มจะไม่ทำงานหากไม่มีการกำหนดค่าเพิ่มเติม หากคุณกำลังพัฒนาด้วย Flutter Web นี่เป็นขั้นตอนเดียวที่คุณต้องเพิ่มเพื่อให้สิ่งนี้ใช้งานได้ แพลตฟอร์มอื่นๆ จำเป็นต้องมีขั้นตอนเพิ่มเติม ซึ่งจะกล่าวถึงในส่วนนี้เล็กน้อย

  1. ไปที่หน้าผู้ให้บริการการตรวจสอบสิทธิ์ใน คอนโซล Firebase
  2. คลิกที่ผู้ให้บริการ Google 9b3a325c5eca6e49.png
  3. คลิกที่แผงส่วนขยาย "การกำหนดค่า Web SDK"
  4. คัดลอกค่าจาก 'รหัสไคลเอ็นต์ของเว็บ' 711a79f0d931c60f.png
  5. กลับไปที่โปรแกรมแก้ไขข้อความของคุณ และอัปเดตอินสแตนซ์ของ GoogleProvider ในไฟล์ auth_gate.dart โดยส่ง ID นี้ไปยังพารามิเตอร์ที่มีชื่อ clientId
GoogleProvider(
   clientId: "YOUR_WEBCLIENT_ID"
)

เมื่อป้อนรหัสไคลเอ็นต์ของเว็บแล้ว ให้โหลดแอปของคุณอีกครั้ง เมื่อคุณกดปุ่ม "ลงชื่อเข้าใช้ด้วย Google" หน้าต่างใหม่จะปรากฏขึ้น (หากคุณใช้เว็บ) ซึ่งจะนำคุณไปสู่ขั้นตอนการลงชื่อเข้าใช้ Google เริ่มแรกจะมีลักษณะดังนี้:

14e73e3c9de704bb.png

กำหนดค่า iOS

เพื่อให้สิ่งนี้ใช้งานได้บน iOS จึงมีกระบวนการกำหนดค่าเพิ่มเติม

  1. ไปที่หน้าจอการตั้งค่าโครงการใน คอนโซล Firebase จะมีการ์ดที่แสดงรายการแอป Firebase ของคุณที่มีลักษณะดังนี้: fefa674acbf213cc.png
  2. คลิกที่ iOS โปรดทราบว่าชื่อใบสมัครของคุณจะแตกต่างจากของฉัน ที่ฉันบอกว่า "สมบูรณ์" คุณจะพูดว่า "เริ่มต้น" หากคุณใช้โปรเจ็กต์ flutter-codelabs/firebase-auth-flutterfire-ui/start เพื่อติดตามพร้อมกับ codelab นี้
  3. คลิกปุ่มที่ระบุว่า "GoogleServices-Info.plist" เพื่อดาวน์โหลดไฟล์การกำหนดค่าที่จำเป็น f89b3192871dfbe3.png
  4. ลากและวางไฟล์ที่ดาวน์โหลดไปยังไดเร็กทอรีชื่อ . /ios/Runner ในโปรเจ็กต์ Flutter ของคุณ
  5. เปิด Xcode โดยรันคำสั่งเทอร์มินัลต่อไปนี้จากรูทของโปรเจ็กต์ของคุณ:

เปิด iOS/Runner.xcworkspace

  1. คลิกขวาที่ไดเร็กทอรี Runner และเลือก Add Files to "Runner" 858986063a4c5201.png
  2. เลือก GoogleService-Info.plist จากตัวจัดการไฟล์
  3. กลับไปที่โปรแกรมแก้ไขข้อความของคุณ (ซึ่งไม่ใช่ Xcode) เพิ่มแอตทริบิวต์ CFBundleURLTypes ด้านล่างลงในไฟล์ [my_project]/ios/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 -->

หากแอป Flutter ของคุณทำงานใน iOS อยู่แล้ว คุณจะต้องปิดมันอย่างสมบูรณ์แล้วจึงเรียกใช้แอปพลิเคชันอีกครั้ง มิฉะนั้น ให้เรียกใช้แอปใน iOS

8. ขอแสดงความยินดี!

คุณได้เสร็จสิ้น Firebase Auth UI สำหรับ Flutter codelab แล้ว คุณสามารถค้นหาโค้ดที่เสร็จสมบูรณ์แล้วสำหรับ Codelab นี้ได้ในไดเร็กทอรี "สมบูรณ์" บน github: Flutter Codelabs

สิ่งที่เราได้กล่าวถึง

  • การตั้งค่าแอพ Flutter เพื่อใช้ Firebase
  • การตั้งค่าโครงการ Firebase ในคอนโซล Firebase
  • FlutterFire CLI
  • Firebase CLI
  • การใช้การรับรองความถูกต้องของ Firebase
  • การใช้ FlutterFire UI เพื่อจัดการ Firebase auth ในแอป Flutter ของคุณได้อย่างง่ายดาย

ขั้นตอนถัดไป

เรียนรู้เพิ่มเติม

Sparky อยู่ที่นี่เพื่อเฉลิมฉลองกับคุณ!

2a0ad195769368b1.gif