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

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

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

เว็บแอป friendly Eats

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

  • การบิลด์และทำให้ใช้งานได้โดยอัตโนมัติ: โค้ดแล็บนี้ใช้โฮสติ้งแอป Firebase เพื่อบิลด์และทำให้โค้ด Next.js ใช้งานได้โดยอัตโนมัติทุกครั้งที่คุณพุชไปยังสาขาที่กําหนดค่าไว้
  • ลงชื่อเข้าใช้และออกจากระบบ: เว็บแอปที่สมบูรณ์ช่วยให้คุณสามารถลงชื่อเข้าใช้ด้วย Google และออกจากระบบได้ การเข้าสู่ระบบและการคงอยู่ของผู้ใช้จะจัดการผ่านการตรวจสอบสิทธิ์ของ Firebase ทั้งหมด
  • รูปภาพ: เว็บแอปที่เสร็จสมบูรณ์จะอนุญาตให้ผู้ใช้ที่ลงชื่อเข้าใช้อัปโหลดรูปภาพร้านอาหาร ระบบจะจัดเก็บชิ้นงานรูปภาพไว้ใน 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 ที่เก็บนี้มีโปรเจ็กต์ตัวอย่างสำหรับหลายแพลตฟอร์ม แต่ Codelab นี้ใช้เฉพาะไดเรกทอรี 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. ใช้แพ็กเกจ giget npm เพื่อดึงข้อมูลเฉพาะโฟลเดอร์ 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 และเป็น v13.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. สำหรับ Codelab นี้ คุณไม่จำเป็นต้องใช้ 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 ให้ขยาย Build แล้วเลือกฐานข้อมูล Firestore
  2. คลิกสร้างฐานข้อมูล
  3. ตั้งค่ารหัสฐานข้อมูลเป็น (default)
  4. เลือกตำแหน่งสำหรับฐานข้อมูล แล้วคลิกถัดไป
    สำหรับแอปจริง คุณควรเลือกตำแหน่งที่อยู่ใกล้กับผู้ใช้
  5. คลิกเริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดเกี่ยวกับกฎความปลอดภัย
    จากนั้นคุณจะเพิ่มกฎความปลอดภัยเพื่อรักษาความปลอดภัยให้ข้อมูลได้ใน Codelab นี้ อย่าเผยแพร่หรือแสดงแอปต่อสาธารณะโดยไม่เพิ่มกฎความปลอดภัยสําหรับฐานข้อมูล
  6. คลิกสร้าง

ตั้งค่า Cloud Storage สำหรับ Firebase

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

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

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

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

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

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

คำอธิบาย

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 ที่ใช้เราเตอร์ของแอป ระบบจะใช้การแสดงผลของเซิร์ฟเวอร์ตลอดทั้งแอป ตัวอย่างเช่น ไฟล์ 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

ในส่วนนี้ คุณจะได้ตั้งค่าแบ็กเอนด์ของโฮสติ้งแอปเพื่อดู Branch ในที่เก็บ 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. คลิกเอกสารบางรายการเพื่อสำรวจคุณสมบัติของเอกสารร้านอาหาร

แสดงรายชื่อร้านอาหาร

ตอนนี้ฐานข้อมูล 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 อีกครั้งในเครื่องมือสำหรับนักพัฒนาเว็บ

ฟังข้อมูลอัปเดตเกี่ยวกับร้านอาหารด้วย Listener ของสแนปชอต 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() ที่คุณติดตั้งใช้งานในขั้นตอนก่อนหน้า แต่ฟังก์ชันสแนปชอตนี้มีกลไก Callback สำหรับให้เรียกใช้ Callback ทุกครั้งที่มีการเปลี่ยนแปลงคอลเล็กชันของร้านอาหาร

  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 Database จะแสดงในเว็บแอปแบบเรียลไทม์แล้ว

  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 แล้วอัปเดต 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 สำหรับ 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 Secret Manager และแบ็กเอนด์สำหรับการโฮสต์แอปจะเข้าถึงคีย์ดังกล่าวได้

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

  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. เปิดหน้าสำหรับร้านอาหาร คุณจะเห็นสรุปของรีวิวทั้งหมดในหน้านั้นเป็นประโยคสั้นๆ เพียงประโยคเดียว
  5. เพิ่มรีวิวใหม่และรีเฟรชหน้าเว็บ จากนั้นคุณจะเห็นการเปลี่ยนแปลงสรุป

11. บทสรุป

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

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

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