ผสานรวม Firebase กับแอป Next.js

1. ก่อนเริ่มต้น

ใน Codelab นี้ คุณจะได้เรียนรู้วิธีผสานรวม Firebase กับเว็บแอป Next.js ชื่อ Friendly Eats ซึ่งเป็นเว็บไซต์รีวิวร้านอาหาร

เว็บแอป Friendly Eats

เว็บแอปที่เสร็จสมบูรณ์จะมีฟีเจอร์ที่มีประโยชน์ซึ่งแสดงให้เห็นว่า Firebase ช่วยคุณสร้างแอป Next.js ได้อย่างไร ฟีเจอร์เหล่านี้ ได้แก่

  • การบิลด์และทำให้ใช้งานได้โดยอัตโนมัติ: โค้ดแล็บนี้ใช้โฮสติ้งแอป Firebase เพื่อบิลด์และทำให้โค้ด Next.js ใช้งานได้โดยอัตโนมัติทุกครั้งที่คุณพุชไปยังสาขาที่กําหนดค่าไว้
  • การลงชื่อเข้าใช้และออกจากระบบ: เว็บแอปที่เสร็จสมบูรณ์จะช่วยให้คุณลงชื่อเข้าใช้ด้วย Google และออกจากระบบได้ การจัดการการเข้าสู่ระบบของผู้ใช้และการคงสถานะจะดำเนินการผ่าน Firebase Authentication โดยสมบูรณ์
  • รูปภาพ: เว็บแอปที่เสร็จสมบูรณ์จะอนุญาตให้ผู้ใช้ที่ลงชื่อเข้าใช้อัปโหลดรูปภาพร้านอาหาร ระบบจะจัดเก็บชิ้นงานรูปภาพไว้ใน Cloud Storage for Firebase Firebase JavaScript SDK จะระบุ URL สาธารณะสำหรับรูปภาพที่อัปโหลด จากนั้นระบบจะจัดเก็บ URL สาธารณะนี้ไว้ในเอกสารร้านอาหารที่เกี่ยวข้องใน Cloud Firestore
  • รีวิว: เว็บแอปที่สมบูรณ์ช่วยให้ผู้ใช้ที่ลงชื่อเข้าใช้สามารถโพสต์รีวิวร้านอาหารได้ ซึ่งประกอบด้วยการให้ดาวและข้อความที่เป็นข้อความ ระบบจะจัดเก็บข้อมูลการตรวจสอบไว้ใน Cloud Firestore
  • ตัวกรอง: เว็บแอปที่เสร็จสมบูรณ์ช่วยให้ผู้ใช้ที่ลงชื่อเข้าใช้สามารถกรองรายการร้านอาหารตามหมวดหมู่ สถานที่ตั้ง และราคา นอกจากนี้ คุณยังปรับแต่งวิธีการจัดเรียงที่ใช้ได้ด้วย ระบบจะเข้าถึงข้อมูลจาก Cloud Firestore และใช้การค้นหา Firestore ตามตัวกรองที่ใช้

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

  • บัญชี GitHub
  • ความรู้เกี่ยวกับ Next.js และ JavaScript

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

  • วิธีใช้ Firebase กับ App Router ของ Next.js และการแสดงผลฝั่งเซิร์ฟเวอร์
  • วิธีเก็บรูปภาพไว้ใน Cloud Storage for Firebase
  • วิธีอ่านและเขียนข้อมูลในฐานข้อมูล Cloud Firestore
  • วิธีใช้ฟีเจอร์ลงชื่อเข้าใช้ด้วย Google กับ Firebase JavaScript SDK

สิ่งที่ต้องมี

  • Git
  • Node.js เวอร์ชันเสถียรล่าสุด
  • เบราว์เซอร์ที่คุณเลือก เช่น Google Chrome
  • สภาพแวดล้อมการพัฒนาที่มีเครื่องมือแก้ไขโค้ดและเทอร์มินัล
  • บัญชี Google สำหรับการสร้างและจัดการโปรเจ็กต์ Firebase
  • ความสามารถในการอัปเกรดโปรเจ็กต์ Firebase เป็นแพ็กเกจราคา Blaze

2. ตั้งค่าสภาพแวดล้อมการพัฒนาซอฟต์แวร์และที่เก็บ GitHub

Codelab นี้ให้โค้ดเริ่มต้นของแอปและใช้ Firebase CLI

สร้างที่เก็บ GitHub

ดูแหล่งที่มาของ Codelab ได้ที่ https://github.com/firebase/friendlyeats-web ที่เก็บมีโปรเจ็กต์ตัวอย่างสำหรับแพลตฟอร์มหลายแพลตฟอร์ม แต่โค้ดแล็บนี้ใช้เฉพาะไดเรกทอรี nextjs-start โปรดสังเกตไดเรกทอรีต่อไปนี้

* `nextjs-start`: contains the starter code upon which you build.
* `nextjs-end`: contains the solution code for the finished web app.

คัดลอกโฟลเดอร์ nextjs-start ไปยังที่เก็บของคุณเองโดยทำดังนี้

  1. ใช้เทอร์มินัลเพื่อสร้างโฟลเดอร์ใหม่ในคอมพิวเตอร์และเปลี่ยนเป็นไดเรกทอรีใหม่:
    mkdir codelab-friendlyeats-web
    
    cd codelab-friendlyeats-web
    
  2. ใช้แพ็กเกจ npm giget เพื่อดึงข้อมูลเฉพาะโฟลเดอร์ nextjs-start
    npx giget@latest gh:firebase/friendlyeats-web/nextjs-start#master . --install
    
  3. ติดตามการเปลี่ยนแปลงในเครื่องด้วย git
    git init
    
    git commit -a -m "codelab starting point"
    
    git branch -M main
    
  4. สร้างที่เก็บ GitHub ใหม่: https://github.com/new ตั้งชื่อตามต้องการ
    1. GitHub จะแสดง URL ของที่เก็บใหม่ซึ่งมีลักษณะเป็น https://github.com//.git หรือ git@github.com:/.git คัดลอก URL นี้
  5. พุชการเปลี่ยนแปลงในเครื่องไปยังที่เก็บ GitHub ใหม่ เรียกใช้คำสั่งต่อไปนี้โดยแทนที่ตัวยึดตําแหน่ง ด้วย URL ของที่เก็บ
    git remote add origin <your-repository-url>
    
    git push -u origin main
    
  6. ตอนนี้คุณควรเห็นโค้ดเริ่มต้นในที่เก็บ GitHub

ติดตั้งหรืออัปเดต Firebase CLI

เรียกใช้คําสั่งต่อไปนี้เพื่อยืนยันว่าคุณได้ติดตั้ง Firebase CLI แล้ว และเป็นเวอร์ชัน 13.9.0 ขึ้นไป

firebase --version

หากเห็นเวอร์ชันที่ต่ำกว่าหรือไม่ได้ติดตั้ง Firebase CLI ให้เรียกใช้คำสั่งติดตั้ง ดังนี้

npm install -g firebase-tools@latest

หากติดตั้ง Firebase CLI ไม่ได้เนื่องจากข้อผิดพลาดเกี่ยวกับสิทธิ์ โปรดดูเอกสารประกอบ npm หรือใช้ตัวเลือกการติดตั้งอื่น

เข้าสู่ระบบ Firebase

  1. เรียกใช้คำสั่งต่อไปนี้เพื่อเข้าสู่ระบบ Firebase CLI
    firebase login
    
  2. ป้อน Y หรือ N โดยขึ้นอยู่กับว่าคุณต้องการให้ Firebase รวบรวมข้อมูลหรือไม่
  3. ในเบราว์เซอร์ ให้เลือกบัญชี Google แล้วคลิกอนุญาต

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

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

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

  1. ในคอนโซล Firebase ให้คลิกเพิ่มโปรเจ็กต์
  2. ในกล่องข้อความป้อนชื่อโปรเจ็กต์ ให้ป้อน FriendlyEats Codelab (หรือชื่อโปรเจ็กต์ที่ต้องการ) แล้วคลิกดำเนินการต่อ
  3. ในโมดัลยืนยันแพ็กเกจการเรียกเก็บเงิน Firebase ให้ตรวจสอบว่าแพ็กเกจเป็น Blaze แล้วคลิกยืนยันแพ็กเกจ
  4. สําหรับโค้ดแล็บนี้ คุณไม่จําเป็นต้องใช้ Google Analytics ดังนั้นให้ปิดตัวเลือกเปิดใช้ Google Analytics สําหรับโปรเจ็กต์นี้
  5. คลิกสร้างโปรเจ็กต์
  6. รอให้ระบบจัดสรรโปรเจ็กต์ แล้วคลิกต่อไป
  7. ในโปรเจ็กต์ Firebase ให้ไปที่การตั้งค่าโปรเจ็กต์ จดรหัสโปรเจ็กต์ไว้เนื่องจากคุณจะต้องใช้ในภายหลัง ตัวระบุที่ไม่ซ้ำกันนี้จะเป็นวิธีระบุโปรเจ็กต์ของคุณ (เช่น ใน Firebase CLI)

อัปเกรดแพ็กเกจราคาของ Firebase

หากต้องการใช้โฮสติ้งแอป Firebase และพื้นที่เก็บข้อมูลระบบคลาวด์สำหรับ Firebase โปรเจ็กต์ Firebase ของคุณต้องใช้แพ็กเกจราคาแบบจ่ายเมื่อใช้ (Blaze) ซึ่งหมายความว่าโปรเจ็กต์จะลิงก์กับบัญชีการเรียกเก็บเงินระบบคลาวด์

หากต้องการอัปเกรดโปรเจ็กต์เป็นแพ็กเกจ Blaze ให้ทำตามขั้นตอนต่อไปนี้

  1. ในคอนโซล Firebase ให้เลือกอัปเกรดแพ็กเกจ
  2. เลือกแพ็กเกจ Blaze ทำตามวิธีการบนหน้าจอเพื่อลิงก์บัญชีสำหรับการเรียกเก็บเงินใน Cloud กับโปรเจ็กต์
    หากจำเป็นต้องสร้างบัญชีสำหรับการเรียกเก็บเงินใน Cloud เป็นส่วนหนึ่งของการอัปเกรดนี้ คุณอาจต้องกลับไปที่ขั้นตอนการอัปเกรดในคอนโซล Firebase เพื่อดำเนินการอัปเกรดให้เสร็จสมบูรณ์

เพิ่มเว็บแอปลงในโปรเจ็กต์ Firebase

  1. ไปที่ภาพรวมโปรเจ็กต์ในโปรเจ็กต์ Firebase แล้วคลิก e41f2efdd9539c31.png เว็บ

    หากลงทะเบียนแอปในโปรเจ็กต์ไว้แล้ว ให้คลิกเพิ่มแอปเพื่อดูไอคอนเว็บ
  2. ในกล่องข้อความชื่อเล่นของแอป ให้ป้อนชื่อเล่นของแอปที่จำง่าย เช่น My Next.js app
  3. ยกเลิกการเลือกช่องทำเครื่องหมายตั้งค่าโฮสติ้งของ Firebase สำหรับแอปนี้ด้วย
  4. คลิกลงทะเบียนแอป > ถัดไป > ถัดไป > ไปที่คอนโซล

ตั้งค่าบริการ Firebase ในคอนโซล Firebase

ตั้งค่าการตรวจสอบสิทธิ์

  1. ในคอนโซล Firebase ให้ไปที่การตรวจสอบสิทธิ์
  2. คลิกเริ่มต้นใช้งาน
  3. ในคอลัมน์ผู้ให้บริการเพิ่มเติม ให้คลิก Google > เปิดใช้
  4. ในกล่องข้อความชื่อที่แสดงต่อสาธารณะสำหรับโปรเจ็กต์ ให้ป้อนชื่อที่จำง่าย เช่น My Next.js app
  5. เลือกอีเมลของคุณจากเมนูแบบเลื่อนลงอีเมลการสนับสนุนสำหรับโปรเจ็กต์
  6. คลิกบันทึก

ตั้งค่า Cloud Firestore

  1. ในแผงด้านซ้ายของคอนโซล Firebase ให้ขยายสร้าง แล้วเลือกฐานข้อมูล Firestore
  2. คลิกสร้างฐานข้อมูล
  3. ตั้งค่ารหัสฐานข้อมูลเป็น (default)
  4. เลือกตำแหน่งสำหรับฐานข้อมูล แล้วคลิกถัดไป
    สำหรับแอปจริง คุณควรเลือกตำแหน่งที่อยู่ใกล้กับผู้ใช้
  5. คลิกเริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดเกี่ยวกับกฎการรักษาความปลอดภัย
    ในภายหลังในโค้ดแล็บนี้ คุณจะเพิ่มกฎการรักษาความปลอดภัยเพื่อรักษาความปลอดภัยให้ข้อมูล อย่าเผยแพร่หรือแสดงแอปต่อสาธารณะโดยไม่เพิ่มกฎความปลอดภัยสําหรับฐานข้อมูล
  6. คลิกสร้าง

ตั้งค่า Cloud Storage for Firebase

  1. ในแผงด้านซ้ายของคอนโซล Firebase ให้ขยายบิลด์ แล้วเลือกพื้นที่เก็บข้อมูล
  2. คลิกเริ่มต้นใช้งาน
  3. เลือกตำแหน่งสำหรับที่เก็บข้อมูล Storage เริ่มต้น
    ที่เก็บข้อมูลใน US-WEST1, US-CENTRAL1 และ US-EAST1 สามารถใช้แพ็กเกจ"ฟรีตลอด" สำหรับ Google Cloud Storage ที่เก็บข้อมูลในตำแหน่งอื่นๆ ทั้งหมดจะเป็นไปตามราคาและการใช้งาน Google Cloud Storage
  4. คลิกเริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดเกี่ยวกับกฎการรักษาความปลอดภัย
    ในภายหลังในโค้ดแล็บนี้ คุณจะต้องเพิ่มกฎการรักษาความปลอดภัยเพื่อรักษาความปลอดภัยให้ข้อมูล อย่าเผยแพร่หรือแสดงแอปต่อสาธารณะโดยไม่เพิ่มกฎความปลอดภัยสำหรับที่เก็บข้อมูล
  5. คลิกสร้าง

4. ตรวจสอบโค้ดฐานเริ่มต้น

ในส่วนนี้ คุณจะได้ดูส่วนต่างๆ ของโค้ดฐานเริ่มต้นของแอปที่จะเพิ่มฟังก์ชันการทำงานในโค้ดแล็บนี้

โครงสร้างโฟลเดอร์และไฟล์

ตารางต่อไปนี้แสดงภาพรวมของโครงสร้างโฟลเดอร์และไฟล์ของแอป

โฟลเดอร์และไฟล์

คำอธิบาย

src/components

คอมโพเนนต์ React สำหรับตัวกรอง ส่วนหัว รายละเอียดร้านอาหาร และรีวิว

src/lib

ฟังก์ชันยูทิลิตีที่ไม่จําเป็นต้องเชื่อมโยงกับ React หรือ Next.js

src/lib/firebase

โค้ดเฉพาะของ Firebase และการกำหนดค่า Firebase

public

ชิ้นงานแบบคงที่ในเว็บแอป เช่น ไอคอน

src/app

การกำหนดเส้นทางด้วย App Router ของ Next.js

src/app/restaurant

แฮนเดิลเส้นทาง API

package.json และ package-lock.json

ทรัพยากร Dependency ของโปรเจ็กต์ด้วย npm

next.config.js

การกําหนดค่าเฉพาะ Next.js (เปิดใช้การดําเนินการของเซิร์ฟเวอร์)

jsconfig.json

การกําหนดค่าบริการภาษา JavaScript

คอมโพเนนต์เซิร์ฟเวอร์และไคลเอ็นต์

แอปเป็นเว็บแอป Next.js ที่ใช้ App Router ระบบจะใช้การแสดงผลฝั่งเซิร์ฟเวอร์ทั่วทั้งแอป เช่น ไฟล์ src/app/page.js เป็นคอมโพเนนต์เซิร์ฟเวอร์ที่รับผิดชอบหน้าหลัก ไฟล์ src/components/RestaurantListings.jsx คือคอมโพเนนต์ไคลเอ็นต์ที่ระบุโดยคำสั่ง "use client" ที่ส่วนต้นของไฟล์

นำเข้าใบแจ้งยอด

คุณอาจเห็นคำสั่งการนําเข้าดังต่อไปนี้

import RatingPicker from "@/src/components/RatingPicker.jsx";

แอปใช้สัญลักษณ์ @ เพื่อหลีกเลี่ยงเส้นทางการนําเข้าแบบสัมพัทธ์ที่ยุ่งยาก และทําได้โดยใช้เส้นทางแทน

API สำหรับ Firebase โดยเฉพาะ

โค้ด Firebase API ทั้งหมดจะรวมอยู่ในไดเรกทอรี src/lib/firebase จากนั้นคอมโพเนนต์ React แต่ละรายการจะนําเข้าฟังก์ชันที่รวมไว้จากไดเรกทอรี src/lib/firebase แทนที่จะนําเข้าฟังก์ชัน Firebase โดยตรง

ข้อมูลจำลอง

ข้อมูลร้านอาหารจำลองและรีวิวจะอยู่ในไฟล์ src/lib/randomData.js ระบบจะรวบรวมข้อมูลจากไฟล์นั้นไว้ในโค้ดในไฟล์ src/lib/fakeRestaurants.js

5. สร้างแบ็กเอนด์ของ App Hosting

ในส่วนนี้ คุณจะต้องตั้งค่าแบ็กเอนด์ของ App Hosting เพื่อดูสาขาในที่เก็บ Git

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

ติดตั้งใช้งานกฎความปลอดภัย

โค้ดมีชุดกฎความปลอดภัยสำหรับ Firestore และ Cloud Storage สำหรับ Firebase อยู่แล้ว หลังจากติดตั้งใช้งานกฎความปลอดภัยแล้ว ข้อมูลในฐานข้อมูลและที่เก็บข้อมูลจะได้รับการปกป้องจากการละเมิดได้ดียิ่งขึ้น

  1. ในเทอร์มินัล ให้กําหนดค่า CLI เพื่อใช้โปรเจ็กต์ Firebase ที่สร้างไว้ก่อนหน้านี้
    firebase use --add
    
    เมื่อระบบแจ้งให้ป้อนอีเมลแทน ให้ป้อน friendlyeats-codelab
  2. หากต้องการใช้กฎความปลอดภัยเหล่านี้ ให้เรียกใช้คําสั่งนี้ในเทอร์มินัล
    firebase deploy --only firestore:rules,storage
    
  3. หากระบบถาม "Cloud Storage for Firebase needs an IAM Role to use cross-service rules. Grant the new role?" ให้กด Enter เพื่อเลือกใช่

เพิ่มการกําหนดค่า Firebase ลงในโค้ดเว็บแอป

  1. ในคอนโซล Firebase ให้ไปที่การตั้งค่าโปรเจ็กต์
  2. ในแผงการตั้งค่าและการกําหนดค่า SDK ให้คลิก "เพิ่มแอป" แล้วคลิกไอคอนวงเล็บโค้ด เพื่อลงทะเบียนเว็บแอปใหม่
  3. เมื่อสิ้นสุดขั้นตอนการสร้างเว็บแอป ให้คัดลอกตัวแปร firebaseConfig รวมถึงคัดลอกพร็อพเพอร์ตี้และค่าของตัวแปร
  4. เปิดไฟล์ apphosting.yaml ในเครื่องมือแก้ไขโค้ด แล้วกรอกค่าตัวแปรสภาพแวดล้อมด้วยค่าการกําหนดค่าจากคอนโซล Firebase
  5. ในไฟล์ ให้แทนที่พร็อพเพอร์ตี้ที่มีอยู่ด้วยพร็อพเพอร์ตี้ที่คุณคัดลอกมา
  6. บันทึกไฟล์

สร้างแบ็กเอนด์

  1. ไปที่หน้าโฮสติ้งแอปในคอนโซล Firebase

สถานะเริ่มต้นของคอนโซลโฮสติ้งแอปที่มีปุ่ม &quot;เริ่มต้นใช้งาน&quot;

  1. คลิก "เริ่มต้นใช้งาน" เพื่อเริ่มขั้นตอนการสร้างแบ็กเอนด์ กำหนดค่าแบ็กเอนด์ดังนี้
  2. ทำตามข้อความแจ้งในขั้นตอนแรกเพื่อเชื่อมต่อที่เก็บ GitHub ที่สร้างไว้ก่อนหน้านี้
  3. ตั้งค่าการทำให้ใช้งานได้
    1. คงไดเรกทอรีรูทเป็น /
    2. ตั้งค่าสาขาที่ใช้งานอยู่เป็น main
    3. เปิดใช้การเปิดตัวอัตโนมัติ
  4. ตั้งชื่อแบ็กเอนด์ friendlyeats-codelab
  5. ในส่วน "สร้างหรือเชื่อมโยงเว็บแอป Firebase" ให้เลือกเว็บแอปที่คุณกําหนดค่าไว้ก่อนหน้านี้จากเมนูแบบเลื่อนลง "เลือกเว็บแอป Firebase ที่มีอยู่"
  6. คลิก "เสร็จสิ้นและทำให้ใช้งานได้" หลังจากผ่านไปสักครู่ ระบบจะนำคุณไปยังหน้าใหม่ที่คุณสามารถดูสถานะของแบ็กเอนด์โฮสติ้งแอปใหม่ได้
  7. เมื่อการเปิดตัวเสร็จสมบูรณ์แล้ว ให้คลิกโดเมนที่ไม่มีค่าใช้จ่ายในส่วน "โดเมน" การดำเนินการนี้อาจใช้เวลา 2-3 นาทีจึงจะเริ่มทํางานเนื่องจากการนำไปใช้ DNS

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

6. เพิ่มการตรวจสอบสิทธิ์ในเว็บแอป

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

ใช้ฟังก์ชันการลงชื่อเข้าใช้และออกจากระบบ

  1. ในไฟล์ src/lib/firebase/auth.js ให้แทนที่ฟังก์ชัน onAuthStateChanged, signInWithGoogle และ signOut ด้วยโค้ดต่อไปนี้
export function onAuthStateChanged(cb) {
	return _onAuthStateChanged(auth, cb);
}

export async function signInWithGoogle() {
  const provider = new GoogleAuthProvider();

  try {
    await signInWithPopup(auth, provider);
  } catch (error) {
    console.error("Error signing in with Google", error);
  }
}

export async function signOut() {
  try {
    return auth.signOut();
  } catch (error) {
    console.error("Error signing out with Google", error);
  }
}

โค้ดนี้ใช้ Firebase API ต่อไปนี้

Firebase API

คำอธิบาย

GoogleAuthProvider

สร้างอินสแตนซ์ผู้ให้บริการการตรวจสอบสิทธิ์ของ Google

signInWithPopup

เริ่มขั้นตอนการตรวจสอบสิทธิ์แบบใช้กล่องโต้ตอบ

auth.signOut

ออกจากระบบของผู้ใช้

ในไฟล์ src/components/Header.jsx โค้ดเรียกใช้ฟังก์ชัน signInWithGoogle และ signOut อยู่แล้ว

  1. สร้างการคอมมิตที่มีข้อความการคอมมิต "การเพิ่มการตรวจสอบสิทธิ์ด้วย Google" แล้วพุชไปยังที่เก็บ GitHub 1. เปิดหน้าการโฮสต์แอปในคอนโซล Firebase แล้วรอให้การเปิดตัวใหม่เสร็จสมบูรณ์
  2. ในเว็บแอป ให้รีเฟรชหน้าเว็บแล้วคลิกลงชื่อเข้าใช้ด้วย Google เว็บแอปไม่อัปเดต จึงไม่ทราบแน่ชัดว่าการลงชื่อเข้าใช้สำเร็จหรือไม่

ส่งสถานะการตรวจสอบสิทธิ์ไปยังเซิร์ฟเวอร์

เราจะใช้ Service Worker เพื่อส่งผ่านสถานะการตรวจสอบสิทธิ์ไปยังเซิร์ฟเวอร์ แทนที่ฟังก์ชัน fetchWithFirebaseHeaders และ getAuthIdToken ด้วยโค้ดต่อไปนี้

async function fetchWithFirebaseHeaders(request) {
  const app = initializeApp(firebaseConfig);
  const auth = getAuth(app);
  const installations = getInstallations(app);
  const headers = new Headers(request.headers);
  const [authIdToken, installationToken] = await Promise.all([
    getAuthIdToken(auth),
    getToken(installations),
  ]);
  headers.append("Firebase-Instance-ID-Token", installationToken);
  if (authIdToken) headers.append("Authorization", `Bearer ${authIdToken}`);
  const newRequest = new Request(request, { headers });
  return await fetch(newRequest);
}

async function getAuthIdToken(auth) {
  await auth.authStateReady();
  if (!auth.currentUser) return;
  return await getIdToken(auth.currentUser);
}

อ่านสถานะการตรวจสอบสิทธิ์ในเซิร์ฟเวอร์

เราจะใช้ FirebaseServerApp เพื่อมิเรอร์สถานะการตรวจสอบสิทธิ์ของไคลเอ็นต์ในเซิร์ฟเวอร์

เปิด src/lib/firebase/serverApp.js แล้วแทนที่ฟังก์ชัน getAuthenticatedAppForUser ดังนี้

export async function getAuthenticatedAppForUser() {
  const idToken = headers().get("Authorization")?.split("Bearer ")[1];
  console.log('firebaseConfig', JSON.stringify(firebaseConfig));
  const firebaseServerApp = initializeServerApp(
    firebaseConfig,
    idToken
      ? {
          authIdToken: idToken,
        }
      : {}
  );

  const auth = getAuth(firebaseServerApp);
  await auth.authStateReady();

  return { firebaseServerApp, currentUser: auth.currentUser };
}

สมัครรับข้อมูลการเปลี่ยนแปลงการตรวจสอบสิทธิ์

หากต้องการสมัครรับข้อมูลเกี่ยวกับการเปลี่ยนแปลงการตรวจสอบสิทธิ์ ให้ทำตามขั้นตอนต่อไปนี้

  1. ไปที่ไฟล์ src/components/Header.jsx
  2. แทนที่ฟังก์ชัน useUserSession ด้วยโค้ดต่อไปนี้
function useUserSession(initialUser) {
	// The initialUser comes from the server via a server component
	const [user, setUser] = useState(initialUser);
	const router = useRouter();

	// Register the service worker that sends auth state back to server
	// The service worker is built with npm run build-service-worker
	useEffect(() => {
		if ("serviceWorker" in navigator) {
			const serializedFirebaseConfig = encodeURIComponent(JSON.stringify(firebaseConfig));
			const serviceWorkerUrl = `/auth-service-worker.js?firebaseConfig=${serializedFirebaseConfig}`
		
		  navigator.serviceWorker
			.register(serviceWorkerUrl)
			.then((registration) => console.log("scope is: ", registration.scope));
		}
	  }, []);

	useEffect(() => {
		const unsubscribe = onAuthStateChanged((authUser) => {
			setUser(authUser)
		})

		return () => unsubscribe()
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, []);

	useEffect(() => {
		onAuthStateChanged((authUser) => {
			if (user === undefined) return

			// refresh when user changed to ease testing
			if (user?.email !== authUser?.email) {
				router.refresh()
			}
		})
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [user])

	return user;
}

โค้ดนี้ใช้ฮุก state ของ React เพื่ออัปเดตผู้ใช้เมื่อฟังก์ชัน onAuthStateChanged ระบุว่ามีการเปลี่ยนแปลงสถานะการตรวจสอบสิทธิ์

ยืนยันการเปลี่ยนแปลง

เลย์เอาต์รูทในไฟล์ src/app/layout.js จะแสดงผลส่วนหัวและส่งผู้ใช้ (หากมี) เป็นพร็อพ

<Header initialUser={currentUser?.toJSON()} />

ซึ่งหมายความว่าคอมโพเนนต์ <Header> จะแสดงผลข้อมูลผู้ใช้ (หากมี) ในระหว่างรันไทม์เซิร์ฟเวอร์ หากมีการอัปเดตการตรวจสอบสิทธิ์ระหว่างวงจรชีวิตของหน้าเว็บหลังจากการโหลดหน้าเว็บครั้งแรก ตัวแฮนเดิล onAuthStateChanged จะจัดการกับการตรวจสอบสิทธิ์เหล่านั้น

ตอนนี้ถึงเวลาเปิดตัวบิลด์ใหม่และยืนยันสิ่งที่คุณสร้างแล้ว

  1. สร้างการคอมมิตที่มีข้อความการคอมมิต "แสดงสถานะการลงชื่อเข้าใช้" แล้วพุชไปยังที่เก็บ GitHub
  2. เปิดหน้าการโฮสต์แอปในคอนโซล Firebase แล้วรอให้การเปิดตัวใหม่เสร็จสมบูรณ์
  3. ตรวจสอบลักษณะการทํางานใหม่ของการตรวจสอบสิทธิ์
    1. รีเฟรชเว็บแอปในเบราว์เซอร์ แล้วชื่อที่แสดงจะปรากฏในส่วนหัว
    2. โปรดออกจากระบบและลงชื่อเข้าใช้อีกครั้ง หน้าเว็บจะอัปเดตแบบเรียลไทม์โดยไม่ต้องรีเฟรชหน้าเว็บ คุณทำขั้นตอนนี้ซ้ำกับผู้ใช้คนอื่นๆ ได้
    3. ไม่บังคับ: คลิกขวาที่เว็บแอป เลือกดูซอร์สโค้ดของหน้าเว็บ แล้วค้นหาชื่อที่แสดง ซึ่งจะปรากฏในแหล่งที่มาของ HTML ดิบซึ่งส่งคืนจากเซิร์ฟเวอร์

7. ดูข้อมูลร้านอาหาร

เว็บแอปมีข้อมูลจำลองสำหรับร้านอาหารและรีวิว

เพิ่มร้านอาหารอย่างน้อย 1 แห่ง

หากต้องการแทรกข้อมูลร้านอาหารจำลองลงในฐานข้อมูล Cloud Firestore ในพื้นที่ ให้ทำตามขั้นตอนต่อไปนี้

  1. ในเว็บแอป ให้เลือก 2cf67d488d8e6332.png > เพิ่มร้านอาหารตัวอย่าง
  2. ในคอนโซล Firebase ในหน้าฐานข้อมูล Firestore ให้เลือก restaurants คุณจะเห็นเอกสารระดับบนสุดในคอลเล็กชันร้านอาหาร ซึ่งแต่ละรายการแสดงถึงร้านอาหาร
  3. คลิกเอกสาร 2-3 รายการเพื่อสำรวจพร็อพเพอร์ตี้ของเอกสารร้านอาหาร

แสดงรายการร้านอาหาร

ตอนนี้ฐานข้อมูล Cloud Firestore ของคุณมีร้านอาหารที่เว็บแอป Next.js แสดงได้

หากต้องการกําหนดโค้ดการดึงข้อมูล ให้ทําตามขั้นตอนต่อไปนี้

  1. ในไฟล์ src/app/page.js ให้ค้นหาคอมโพเนนต์เซิร์ฟเวอร์ <Home /> และตรวจสอบการเรียกใช้ฟังก์ชัน getRestaurants ซึ่งดึงข้อมูลรายการร้านอาหารที่รันไทม์เซิร์ฟเวอร์ คุณใช้ฟังก์ชัน getRestaurants ในขั้นตอนต่อไปนี้
  2. ในไฟล์ src/lib/firebase/firestore.js ให้แทนที่ฟังก์ชัน applyQueryFilters และ getRestaurants ด้วยโค้ดต่อไปนี้
function applyQueryFilters(q, { category, city, price, sort }) {
	if (category) {
		q = query(q, where("category", "==", category));
	}
	if (city) {
		q = query(q, where("city", "==", city));
	}
	if (price) {
		q = query(q, where("price", "==", price.length));
	}
	if (sort === "Rating" || !sort) {
		q = query(q, orderBy("avgRating", "desc"));
	} else if (sort === "Review") {
		q = query(q, orderBy("numRatings", "desc"));
	}
	return q;
}

export async function getRestaurants(db = db, filters = {}) {
	let q = query(collection(db, "restaurants"));

	q = applyQueryFilters(q, filters);
	const results = await getDocs(q);
	return results.docs.map(doc => {
		return {
			id: doc.id,
			...doc.data(),
			// Only plain objects can be passed to Client Components from Server Components
			timestamp: doc.data().timestamp.toDate(),
		};
	});
}
  1. สร้างการคอมมิตที่มีข้อความการคอมมิต "อ่านรายการร้านอาหารจาก Firestore" แล้วพุชไปยังที่เก็บ GitHub
  2. เปิดหน้าการโฮสต์แอปในคอนโซล Firebase แล้วรอให้การเปิดตัวใหม่เสร็จสมบูรณ์
  3. รีเฟรชหน้าเว็บในเว็บแอป รูปภาพร้านอาหารจะปรากฏเป็นการ์ดในหน้า

ยืนยันว่าข้อมูลร้านอาหารโหลดเมื่อรันไทม์เซิร์ฟเวอร์

เมื่อใช้เฟรมเวิร์ก Next.js คุณอาจไม่แน่ใจว่าระบบโหลดข้อมูลเมื่อใดในรันไทม์เซิร์ฟเวอร์หรือรันไทม์ฝั่งไคลเอ็นต์

ทำตามขั้นตอนต่อไปนี้เพื่อยืนยันว่าข้อมูลร้านอาหารโหลดเมื่อรันไทม์เซิร์ฟเวอร์

  1. ในเว็บแอป ให้เปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์และปิดใช้ JavaScript

ปิดใช้ JavaScript ในเครื่องมือสำหรับนักพัฒนาเว็บ

  1. รีเฟรชเว็บแอป ข้อมูลร้านอาหารจะยังคงโหลดอยู่ ระบบจะแสดงข้อมูลร้านอาหารในการตอบกลับของเซิร์ฟเวอร์ เมื่อเปิดใช้ JavaScript ระบบจะสร้างข้อมูลร้านอาหารผ่านโค้ด JavaScript ฝั่งไคลเอ็นต์
  2. ในเครื่องมือสำหรับนักพัฒนาเว็บ ให้เปิดใช้ JavaScript อีกครั้ง

คอยฟังการอัปเดตร้านอาหารด้วยเครื่องมือรับฟังภาพรวมของ Cloud Firestore

ในส่วนก่อนหน้านี้ คุณได้ดูวิธีที่ชุดร้านอาหารเริ่มต้นโหลดจากไฟล์ src/app/page.js ไฟล์ src/app/page.js เป็นคอมโพเนนต์เซิร์ฟเวอร์และจะแสดงผลบนเซิร์ฟเวอร์ รวมถึงโค้ดการดึงข้อมูล Firebase

ไฟล์ src/components/RestaurantListings.jsx เป็นคอมโพเนนต์ไคลเอ็นต์และสามารถกําหนดค่าให้ไฮเดรตมาร์กอัปที่แสดงผลจากเซิร์ฟเวอร์ได้

หากต้องการกำหนดค่าไฟล์ src/components/RestaurantListings.jsx เพื่อไฮเดรตมาร์กอัปที่แสดงผลจากเซิร์ฟเวอร์ ให้ทำตามขั้นตอนต่อไปนี้

  1. ในไฟล์ src/components/RestaurantListings.jsx ให้ดูโค้ดต่อไปนี้ซึ่งเขียนให้คุณแล้ว
useEffect(() => {
        const unsubscribe = getRestaurantsSnapshot(data => {
                setRestaurants(data);
        }, filters);

        return () => {
                unsubscribe();
        };
}, [filters]);

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

  1. ในไฟล์ src/lib/firebase/firestore.js ให้แทนที่ฟังก์ชัน getRestaurantsSnapshot() ด้วยโค้ดต่อไปนี้
export function getRestaurantsSnapshot(cb, filters = {}) {
	if (typeof cb !== "function") {
		console.log("Error: The callback parameter is not a function");
		return;
	}

	let q = query(collection(db, "restaurants"));
	q = applyQueryFilters(q, filters);

	const unsubscribe = onSnapshot(q, querySnapshot => {
		const results = querySnapshot.docs.map(doc => {
			return {
				id: doc.id,
				...doc.data(),
				// Only plain objects can be passed to Client Components from Server Components
				timestamp: doc.data().timestamp.toDate(),
			};
		});

		cb(results);
	});

	return unsubscribe;
}

ตอนนี้การเปลี่ยนแปลงที่ทำผ่านหน้าฐานข้อมูล Firestore จะแสดงในเว็บแอปแบบเรียลไทม์

  1. สร้างการคอมมิตที่มีข้อความการคอมมิต "ฟังการอัปเดตร้านอาหารแบบเรียลไทม์" แล้วพุชไปยังที่เก็บ GitHub
  2. เปิดหน้าการโฮสต์แอปในคอนโซล Firebase แล้วรอให้การเปิดตัวใหม่เสร็จสมบูรณ์
  3. ในเว็บแอป ให้เลือก 27ca5d1e8ed8adfe.png > เพิ่มร้านอาหารตัวอย่าง หากใช้ฟังก์ชันภาพรวมอย่างถูกต้อง ร้านอาหารจะปรากฏแบบเรียลไทม์โดยไม่ต้องรีเฟรชหน้าเว็บ

8. บันทึกรีวิวที่ผู้ใช้ส่งจากเว็บแอป

  1. ในไฟล์ src/lib/firebase/firestore.js ให้แทนที่ฟังก์ชัน updateWithRating() ด้วยโค้ดต่อไปนี้
const updateWithRating = async (
	transaction,
	docRef,
	newRatingDocument,
	review
) => {
	const restaurant = await transaction.get(docRef);
	const data = restaurant.data();
	const newNumRatings = data?.numRatings ? data.numRatings + 1 : 1;
	const newSumRating = (data?.sumRating || 0) + Number(review.rating);
	const newAverage = newSumRating / newNumRatings;

	transaction.update(docRef, {
		numRatings: newNumRatings,
		sumRating: newSumRating,
		avgRating: newAverage,
	});

	transaction.set(newRatingDocument, {
		...review,
		timestamp: Timestamp.fromDate(new Date()),
	});
};

โค้ดนี้จะแทรกเอกสาร Firestore ใหม่ซึ่งแสดงการตรวจสอบใหม่ โค้ดยังอัปเดตเอกสาร Firestore ที่มีอยู่ซึ่งแสดงถึงร้านอาหารด้วยตัวเลขที่อัปเดตสำหรับจำนวนการให้คะแนนและคะแนนเฉลี่ยที่คำนวณแล้ว

  1. แทนที่ฟังก์ชัน addReviewToRestaurant() ด้วยโค้ดต่อไปนี้
export async function addReviewToRestaurant(db, restaurantId, review) {
	if (!restaurantId) {
		throw new Error("No restaurant ID has been provided.");
	}

	if (!review) {
		throw new Error("A valid review has not been provided.");
	}

	try {
		const docRef = doc(collection(db, "restaurants"), restaurantId);
		const newRatingDocument = doc(
			collection(db, `restaurants/${restaurantId}/ratings`)
		);

		// corrected line
		await runTransaction(db, transaction =>
			updateWithRating(transaction, docRef, newRatingDocument, review)
		);
	} catch (error) {
		console.error(
			"There was an error adding the rating to the restaurant",
			error
		);
		throw error;
	}
}

ใช้การดําเนินการของเซิร์ฟเวอร์ Next.js

การดำเนินการของเซิร์ฟเวอร์ Next.js มี API ที่สะดวกในการเข้าถึงข้อมูลแบบฟอร์ม เช่น data.get("text") เพื่อรับค่าข้อความจากเพย์โหลดการส่งแบบฟอร์ม

หากต้องการใช้ Next.js Server Action เพื่อประมวลผลการส่งแบบฟอร์มการตรวจสอบ ให้ทำตามขั้นตอนต่อไปนี้

  1. ในไฟล์ src/components/ReviewDialog.jsx ให้ค้นหาแอตทริบิวต์ action ในองค์ประกอบ <form>
<form action={handleReviewFormSubmission}>

ค่าแอตทริบิวต์ action หมายถึงฟังก์ชันที่คุณติดตั้งใช้งานในขั้นตอนถัดไป

  1. ในไฟล์ src/app/actions.js ให้แทนที่ฟังก์ชัน handleReviewFormSubmission() ด้วยโค้ดต่อไปนี้
// This is a next.js server action, which is an alpha feature, so
// use with caution.
// https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions
export async function handleReviewFormSubmission(data) {
        const { app } = await getAuthenticatedAppForUser();
        const db = getFirestore(app);

        await addReviewToRestaurant(db, data.get("restaurantId"), {
                text: data.get("text"),
                rating: data.get("rating"),

                // This came from a hidden form field.
                userId: data.get("userId"),
        });
}

เพิ่มรีวิวสำหรับร้านอาหาร

คุณได้ติดตั้งใช้งานการรองรับการส่งรีวิวแล้ว ตอนนี้คุณจึงยืนยันได้ว่ารีวิวของคุณแทรกลงใน Cloud Firestore อย่างถูกต้องแล้ว

หากต้องการเพิ่มรีวิวและยืนยันว่ารีวิวนั้นแทรกลงใน Cloud Firestore แล้ว ให้ทำตามขั้นตอนต่อไปนี้

  1. สร้างการคอมมิตที่มีข้อความการคอมมิต "อนุญาตให้ผู้ใช้ส่งรีวิวร้านอาหาร" และพุชไปยังที่เก็บ GitHub
  2. เปิดหน้าการโฮสต์แอปในคอนโซล Firebase แล้วรอให้การเปิดตัวใหม่เสร็จสมบูรณ์
  3. รีเฟรชเว็บแอป แล้วเลือกร้านอาหารจากหน้าแรก
  4. คลิก 3e19beef78bb0d0e.png ในหน้าของร้านอาหาร
  5. เลือกการให้ดาว
  6. เขียนรีวิว
  7. คลิกส่ง รีวิวของคุณจะปรากฏที่ด้านบนของรายการรีวิว
  8. ใน Cloud Firestore ให้ค้นหาเอกสารของร้านอาหารที่คุณตรวจสอบแล้วในแผงเพิ่มเอกสาร แล้วเลือกเอกสารนั้น
  9. ในแผงเริ่มคอลเล็กชัน ให้เลือกการให้คะแนน
  10. ในแผงเพิ่มเอกสาร ให้ค้นหาเอกสารที่ต้องการตรวจสอบเพื่อยืนยันว่าระบบแทรกเอกสารดังกล่าวตามที่คาดไว้

เอกสารในโปรแกรมจำลอง Firestore

9. บันทึกไฟล์ที่ผู้ใช้อัปโหลดจากเว็บแอป

ในส่วนนี้ คุณจะเพิ่มฟังก์ชันการทำงานเพื่อให้คุณแทนที่รูปภาพที่เชื่อมโยงกับร้านอาหารได้เมื่อเข้าสู่ระบบ คุณอัปโหลดรูปภาพไปยัง Firebase Storage และอัปเดต URL รูปภาพในเอกสาร Cloud Firestore ที่แสดงถึงร้านอาหาร

หากต้องการบันทึกไฟล์ที่ผู้ใช้อัปโหลดจากเว็บแอป ให้ทำตามขั้นตอนต่อไปนี้

  1. ในไฟล์ src/components/Restaurant.jsx ให้สังเกตโค้ดที่ทำงานเมื่อผู้ใช้อัปโหลดไฟล์
async function handleRestaurantImage(target) {
        const image = target.files ? target.files[0] : null;
        if (!image) {
                return;
        }

        const imageURL = await updateRestaurantImage(id, image);
        setRestaurant({ ...restaurant, photo: imageURL });
}

คุณไม่จำเป็นต้องทำการเปลี่ยนแปลงใดๆ แต่จะใช้ลักษณะการทํางานของฟังก์ชัน updateRestaurantImage() ในขั้นตอนต่อไปนี้ได้

  1. ในไฟล์ src/lib/firebase/storage.js ให้แทนที่ฟังก์ชัน updateRestaurantImage() และ uploadImage() ด้วยโค้ดต่อไปนี้
export async function updateRestaurantImage(restaurantId, image) {
	try {
		if (!restaurantId)
			throw new Error("No restaurant ID has been provided.");

		if (!image || !image.name)
			throw new Error("A valid image has not been provided.");

		const publicImageUrl = await uploadImage(restaurantId, image);
		await updateRestaurantImageReference(restaurantId, publicImageUrl);

		return publicImageUrl;
	} catch (error) {
		console.error("Error processing request:", error);
	}
}

async function uploadImage(restaurantId, image) {
	const filePath = `images/${restaurantId}/${image.name}`;
	const newImageRef = ref(storage, filePath);
	await uploadBytesResumable(newImageRef, image);

	return await getDownloadURL(newImageRef);
}

เราได้ติดตั้งใช้งานฟังก์ชัน updateRestaurantImageReference() ให้คุณแล้ว ฟังก์ชันนี้จะอัปเดตเอกสารร้านอาหารที่มีอยู่ใน Cloud Firestore ด้วย URL รูปภาพที่อัปเดตแล้ว

ยืนยันฟังก์ชันการอัปโหลดรูปภาพ

หากต้องการยืนยันว่ารูปภาพอัปโหลดตามที่คาดไว้ ให้ทำตามขั้นตอนต่อไปนี้

  1. สร้างการคอมมิตที่มีข้อความการคอมมิต "อนุญาตให้ผู้ใช้เปลี่ยนรูปภาพของร้านอาหารแต่ละแห่ง" แล้วพุชไปยังที่เก็บ GitHub
  2. เปิดหน้าการโฮสต์แอปในคอนโซล Firebase แล้วรอให้การเปิดตัวใหม่เสร็จสมบูรณ์
  3. ในเว็บแอป ให้ตรวจสอบว่าคุณเข้าสู่ระบบแล้วและเลือกร้านอาหาร
  4. คลิก 7067eb41fea41ff0.png แล้วอัปโหลดรูปภาพจากระบบไฟล์ รูปภาพจะออกจากสภาพแวดล้อมในเครื่องและอัปโหลดไปยัง Cloud Storage รูปภาพจะปรากฏทันทีหลังจากที่คุณอัปโหลด
  5. ไปที่ Cloud Storage for Firebase
  6. ไปที่โฟลเดอร์ที่แสดงถึงร้านอาหาร รูปภาพที่คุณอัปโหลดอยู่ในโฟลเดอร์

6cf3f9e2303c931c.png

10. สรุปรีวิวร้านอาหารด้วย Generative AI

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

จัดเก็บคีย์ Gemini API ใน Secret Manager ของ Cloud

  1. หากต้องการใช้ Gemini API คุณจะต้องมีคีย์ API สร้างคีย์ใน Google AI Studio
  2. โฮสติ้งแอปผสานรวมกับ Cloud Secret Manager เพื่อช่วยให้คุณจัดเก็บค่าที่มีความละเอียดอ่อน เช่น คีย์ API ได้อย่างปลอดภัย
    1. ในเทอร์มินัล ให้เรียกใช้คําสั่งต่อไปนี้เพื่อสร้างข้อมูลลับใหม่
    firebase apphosting:secrets:set gemini-api-key
    
    1. เมื่อระบบแจ้งให้ป้อนค่าลับ ให้คัดลอกและวางคีย์ Gemini API จาก Google AI Studio
    2. เมื่อระบบถามว่าควรเพิ่มข้อมูลลับใหม่ลงใน apphosting.yaml หรือไม่ ให้ป้อน Y เพื่อยอมรับ

ตอนนี้คีย์ Gemini API ของคุณจัดเก็บอย่างปลอดภัยในเครื่องมือจัดการข้อมูลลับของ Cloud และเข้าถึงแบ็กเอนด์ของ App Hosting ได้

ใช้คอมโพเนนต์สรุปรีวิว

  1. ใน src/components/Reviews/ReviewSummary.jsx ให้แทนที่ฟังก์ชัน GeminiSummary ด้วยโค้ดต่อไปนี้
    export async function GeminiSummary({ restaurantId }) {
        const { firebaseServerApp } = await getAuthenticatedAppForUser();
        const reviews = await getReviewsByRestaurantId(
            getFirestore(firebaseServerApp),
            restaurantId
        );
    
        const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
        const model = genAI.getGenerativeModel({ model: "gemini-pro"});
    
        const reviewSeparator = "@";
        const prompt = `
            Based on the following restaurant reviews, 
            where each review is separated by a '${reviewSeparator}' character, 
            create a one-sentence summary of what people think of the restaurant. 
    
            Here are the reviews: ${reviews.map(review => review.text).join(reviewSeparator)}
        `;
    
        try {
            const result = await model.generateContent(prompt);
            const response = await result.response;
            const text = response.text();
    
            return (
                <div className="restaurant__review_summary">
                    <p>{text}</p>
                    <p>✨ Summarized with Gemini</p>
                </div>
            );
        } catch (e) {
            console.error(e);
            return <p>Error contacting Gemini</p>;
        }
    }
    
  2. สร้างการคอมมิตที่มีข้อความการคอมมิต "ใช้ AI เพื่อสรุปรีวิว" แล้วพุชไปยังที่เก็บ GitHub
  3. เปิดหน้าการโฮสต์แอปในคอนโซล Firebase แล้วรอให้การเปิดตัวใหม่เสร็จสมบูรณ์
  4. เปิดหน้าสำหรับร้านอาหาร คุณควรเห็นสรุปแบบ 1 ประโยคของรีวิวทั้งหมดในหน้านี้ที่ด้านบน
  5. เพิ่มรีวิวใหม่และรีเฟรชหน้าเว็บ คุณควรเห็นการเปลี่ยนแปลงในสรุป

11. บทสรุป

ยินดีด้วย คุณได้เรียนรู้วิธีใช้ Firebase เพื่อเพิ่มฟีเจอร์และฟังก์ชันการทำงานลงในแอป Next.js โดยเฉพาะอย่างยิ่ง คุณได้ใช้สิ่งต่อไปนี้

  • โฮสติ้งแอป Firebase เพื่อสร้างและติดตั้งใช้งานโค้ด Next.js โดยอัตโนมัติทุกครั้งที่คุณพุชไปยังสาขาที่กําหนดค่าไว้
  • การตรวจสอบสิทธิ์ Firebase เพื่อเปิดใช้ฟังก์ชันการลงชื่อเข้าใช้และออกจากระบบ
  • Cloud Firestore สำหรับข้อมูลร้านอาหารและข้อมูลรีวิวร้านอาหาร
  • Cloud Storage for Firebase สำหรับรูปภาพร้านอาหาร

ดูข้อมูลเพิ่มเติม