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

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

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

เว็บแอป Fresh Eats

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

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

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

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

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

  • วิธีใช้ Firebase กับเราเตอร์แอป Next.js และการแสดงผลฝั่งเซิร์ฟเวอร์
  • วิธีคงรูปภาพใน Cloud Storage สำหรับ 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. คุณไม่จำเป็นต้องใช้ Google Analytics ใน Codelab ดังนั้นให้สลับตัวเลือกเปิดใช้ Google Analytics สำหรับโปรเจ็กต์นี้
  5. คลิกสร้างโปรเจ็กต์
  6. รอให้โปรเจ็กต์จัดสรร แล้วคลิกต่อไป
  7. ในโปรเจ็กต์ Firebase ให้ไปที่การตั้งค่าโปรเจ็กต์ โปรดจดรหัสโปรเจ็กต์ไว้เนื่องจากคุณจะต้องใช้ในภายหลัง ตัวระบุที่ไม่ซ้ำกันนี้เป็นวิธีระบุโปรเจ็กต์ (เช่น ใน Firebase CLI)

อัปเกรดแผนการตั้งราคา Firebase

หากต้องการใช้โฮสติ้งแอป โปรเจ็กต์ Firebase จะต้องใช้แผนการตั้งราคา Blaze ซึ่งหมายความว่าโปรเจ็กต์ดังกล่าวเชื่อมโยงกับบัญชีสำหรับการเรียกเก็บเงินใน Cloud

ทำตามขั้นตอนต่อไปนี้เพื่ออัปเกรดโปรเจ็กต์เป็นแพ็กเกจ 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. คลิกสร้างฐานข้อมูล > ถัดไป > เริ่มต้นในโหมดทดสอบ > ถัดไป
    ใน Codelab นี้จะเพิ่มกฎความปลอดภัยเพื่อรักษาความปลอดภัยให้ข้อมูล โปรดไม่เผยแพร่หรือเปิดเผยแอปต่อสาธารณะโดยไม่เพิ่มกฎความปลอดภัยสำหรับฐานข้อมูล
  3. ใช้ตำแหน่งเริ่มต้นหรือเลือกตำแหน่งที่ต้องการ
    สำหรับแอปจริง คุณควรเลือกตำแหน่งที่อยู่ใกล้กับผู้ใช้มากที่สุด โปรดทราบว่าตำแหน่งนี้ไม่สามารถเปลี่ยนแปลงได้ในภายหลัง และจะเป็นสถานที่ของที่เก็บข้อมูล Cloud Storage เริ่มต้นโดยอัตโนมัติด้วย (ขั้นตอนถัดไป)
  4. คลิกเสร็จ

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

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

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

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

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

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

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

คำอธิบาย

src/components

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

src/lib

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

src/lib/firebase

โค้ดสำหรับ Firebase และการกำหนดค่า Firebase โดยเฉพาะ

public

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

src/app

การกำหนดเส้นทางด้วยเราเตอร์แอป 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

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

ในตอนท้ายของส่วนนี้ คุณจะมีแบ็กเอนด์ของ App Hosting ที่เชื่อมต่อกับที่เก็บใน 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. ไปที่หน้า App Hosting ในคอนโซล Firebase

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

  1. คลิก "เริ่มต้นใช้งาน" เพื่อเริ่มขั้นตอนการสร้างแบ็กเอนด์ กำหนดค่าแบ็กเอนด์ดังนี้
  2. ทำตามข้อความแจ้งในขั้นตอนแรกเพื่อเชื่อมต่อที่เก็บ GitHub ที่คุณสร้างไว้ก่อนหน้านี้
  3. ตั้งค่าการทำให้ใช้งานได้:
    1. เก็บไดเรกทอรีรากไว้เป็น /
    2. ตั้งค่า Branch แบบเรียลไทม์เป็น main
    3. เปิดใช้การเปิดตัวอัตโนมัติ
  4. ตั้งชื่อแบ็กเอนด์เป็น friendlyeats-codelab
  5. ใน "สร้างหรือเชื่อมโยงเว็บแอป Firebase" ให้เลือกเว็บแอปที่กำหนดค่าไว้ก่อนหน้านี้จากเมนูแบบเลื่อนลง "เลือกเว็บแอป Firebase ที่มีอยู่"
  6. คลิก "เสร็จสิ้นและทำให้ใช้งานได้" หลังจากผ่านไปสักครู่ ระบบจะนำคุณไปยังหน้าใหม่ที่คุณจะดูสถานะแบ็กเอนด์ของ App Hosting ใหม่ได้
  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);
  }
}

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

Firebase API

คำอธิบาย

GoogleAuthProvider

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

signInWithPopup

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

auth.signOut

นำผู้ใช้ออกจากระบบ

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

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

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

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

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

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

  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 Server Action มี API ความสะดวกในการเข้าถึงข้อมูลแบบฟอร์ม เช่น data.get("text") เพื่อรับค่าข้อความจากเพย์โหลดการส่งแบบฟอร์ม

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

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

11. บทสรุป

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

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