1. ก่อนเริ่มต้น
ในโค้ดแล็บนี้ คุณจะได้ผสานรวม Firebase Data Connect กับฐานข้อมูล Cloud SQL เพื่อสร้างเว็บแอปรีวิวภาพยนตร์ แอปที่เสร็จสมบูรณ์จะแสดงให้เห็นว่า Firebase Data Connect ช่วยให้การสร้างแอปพลิเคชันที่ทำงานด้วย SQL ง่ายขึ้นเพียงใด ซึ่งประกอบด้วยฟีเจอร์ต่อไปนี้
- การตรวจสอบสิทธิ์: ใช้การตรวจสอบสิทธิ์ที่กำหนดเองสำหรับการค้นหาและการดัดแปลงของแอป เพื่อให้มั่นใจว่ามีเพียงผู้ใช้ที่ได้รับอนุญาตเท่านั้นที่โต้ตอบกับข้อมูลของคุณได้
- สคีมา GraphQL: สร้างและจัดการโครงสร้างข้อมูลโดยใช้สคีมา GraphQL ที่ยืดหยุ่นซึ่งปรับให้เหมาะกับความต้องการของเว็บแอปรีวิวภาพยนตร์
- การค้นหาและการดัดแปลง SQL: ดึงข้อมูล อัปเดต และจัดการข้อมูลใน Cloud SQL โดยใช้การค้นหาและการดัดแปลงที่ทำงานด้วย GraphQL
- การค้นหาขั้นสูงที่มีการจับคู่สตริงบางส่วน: ใช้ตัวกรองและตัวเลือกการค้นหาเพื่อค้นหาภาพยนตร์ตามช่องต่างๆ เช่น ชื่อ คำอธิบาย หรือแท็ก
- (ไม่บังคับ) การผสานรวมการค้นหาด้วยเวกเตอร์: เพิ่มฟังก์ชันการค้นหาเนื้อหาโดยใช้การค้นหาด้วยเวกเตอร์ของ Firebase Data Connect เพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่สมบูรณ์ตามข้อมูลและค่ากําหนด
ข้อกำหนดเบื้องต้น
คุณต้องมีความเข้าใจพื้นฐานเกี่ยวกับ JavaScript
สิ่งที่คุณจะได้เรียนรู้
- ตั้งค่า Firebase Data Connect ด้วยโปรแกรมจำลองในเครื่อง
- ออกแบบสคีมาข้อมูลโดยใช้ Data Connect และ GraphQL
- เขียนและทดสอบการค้นหาและการกลายพันธุ์ต่างๆ สําหรับแอปรีวิวภาพยนตร์
- ดูวิธีที่ Firebase Data Connect สร้างและใช้ SDK ในแอป
- ติดตั้งใช้งานสคีมาและจัดการฐานข้อมูลอย่างมีประสิทธิภาพ
สิ่งที่ต้องมี
- Git
- โค้ด Visual Studio
- ติดตั้ง Node.js โดยใช้ nvm-windows (Windows) หรือ nvm (macOS/Linux)
- สร้างโปรเจ็กต์ Firebase ในคอนโซล Firebase หากยังไม่ได้สร้าง
- (ไม่บังคับ) สําหรับการค้นหาเวกเตอร์ ให้อัปเกรดโปรเจ็กต์เป็นแพ็กเกจราคา Blaze แบบชําระตามการใช้งานจริง
2. ตั้งค่าสภาพแวดล้อมการพัฒนา
ระยะนี้ของโค้ดแล็บจะแนะนำการตั้งค่าสภาพแวดล้อมเพื่อเริ่มสร้างแอปรีวิวภาพยนตร์โดยใช้ Firebase Data Connect
- โคลนที่เก็บโปรเจ็กต์และติดตั้งไลบรารีที่จำเป็น
git clone https://github.com/firebaseextended/codelab-dataconnect-web cd codelab-dataconnect-web cd ./app && npm i npm run dev
- หลังจากเรียกใช้คําสั่งเหล่านี้แล้ว ให้เปิด http://localhost:5173 ในเบราว์เซอร์เพื่อดูเว็บแอปที่ทํางานในเครื่อง หน้านี้เป็นหน้าเว็บสำหรับสร้างแอปรีวิวภาพยนตร์และโต้ตอบกับฟีเจอร์ต่างๆ
- เปิดโฟลเดอร์
codelab-dataconnect-web
ที่โคลนโดยใช้ Visual Studio Code ซึ่งคุณจะกำหนดสคีมา เขียนการค้นหา และทดสอบฟังก์ชันการทำงานของแอป - หากต้องการใช้ฟีเจอร์ Data Connect ให้ติดตั้งส่วนขยาย Firebase Data Connect ใน Visual Studio
หรือจะติดตั้งส่วนขยายจาก Visual Studio Code Marketplace หรือค้นหาภายใน VS Code ก็ได้ - เปิดหรือสร้างโปรเจ็กต์ Firebase ใหม่ในคอนโซล Firebase
- เชื่อมต่อโปรเจ็กต์ Firebase กับส่วนขยาย Firebase Data Connect ใน VSCode ในส่วนขยาย ให้ทําดังนี้
- คลิกปุ่มลงชื่อเข้าใช้
- คลิกเชื่อมต่อโปรเจ็กต์ Firebase แล้วเลือกโปรเจ็กต์ Firebase
- เริ่มโปรแกรมจำลอง Firebase โดยใช้ส่วนขยาย Firebase Data Connect ใน VS Code โดย
คลิกเริ่มโปรแกรมจำลอง แล้วตรวจสอบว่าโปรแกรมจำลองทำงานอยู่ในเทอร์มินัล
3. ตรวจสอบโค้ดฐานเริ่มต้น
ในส่วนนี้ คุณจะได้สำรวจส่วนสําคัญของโค้ดเริ่มต้นของแอป แม้ว่าแอปจะขาดฟังก์ชันบางอย่าง แต่การทำความเข้าใจโครงสร้างโดยรวมก็มีประโยชน์
โครงสร้างโฟลเดอร์และไฟล์
ส่วนย่อยต่อไปนี้แสดงภาพรวมของโครงสร้างโฟลเดอร์และไฟล์ของแอป
ไดเรกทอรี dataconnect/
มีการกำหนดค่า Firebase Data Connect, ตัวเชื่อมต่อ (ซึ่งกำหนดการค้นหาและการดัดแปลง) และไฟล์สคีมา
schema/schema.gql
: กำหนดสคีมา GraphQLconnector/queries.gql
: คําค้นหาที่จําเป็นในแอปconnector/mutations.gql
: การกลายพันธุ์ที่จําเป็นสําหรับแอปconnector/connector.yaml
: ไฟล์การกําหนดค่าสําหรับการสร้าง SDK
ไดเรกทอรี app/src/
มีตรรกะแอปพลิเคชันและการทำงานกับ Firebase Data Connect
firebase.ts
: การกําหนดค่าเพื่อเชื่อมต่อกับแอป Firebase ในโปรเจ็กต์ Firebaselib/dataconnect-sdk/
: มี SDK ที่สร้างขึ้น คุณสามารถแก้ไขตำแหน่งการสร้าง SDK ในไฟล์connector/connector.yaml
และระบบจะสร้าง SDK โดยอัตโนมัติทุกครั้งที่คุณกำหนดการค้นหาหรือการกลายพันธุ์
4. กำหนดสคีมาสำหรับรีวิวภาพยนตร์
ในส่วนนี้ คุณจะต้องกำหนดโครงสร้างและความสัมพันธ์ระหว่างเอนทิตีหลักในแอปพลิเคชันภาพยนตร์ในสคีมา เอนทิตี เช่น Movie
, User
, Actor
และ Review
จะแมปกับตารางฐานข้อมูล โดยมีการสร้างความสัมพันธ์โดยใช้คำสั่ง Firebase Data Connect และคำสั่งสคีมา GraphQL เมื่อติดตั้งใช้งานแล้ว แอปของคุณจะพร้อมจัดการทุกอย่างตั้งแต่การค้นหาภาพยนตร์ที่ได้รับคะแนนสูงสุดและการกรองตามประเภท ไปจนถึงการอนุญาตให้ผู้ใช้แสดงความคิดเห็น ทำเครื่องหมายรายการโปรด สำรวจภาพยนตร์ที่คล้ายกัน หรือค้นหาภาพยนตร์แนะนำตามข้อความที่ป้อนผ่านการค้นหาเวกเตอร์
เอนทิตีหลักและความสัมพันธ์
ประเภท Movie
มีรายละเอียดสำคัญ เช่น ชื่อ ประเภท และแท็ก ซึ่งแอปใช้สำหรับการค้นหาและโปรไฟล์ภาพยนตร์ ประเภท User
จะติดตามการโต้ตอบของผู้ใช้ เช่น รีวิวและรายการโปรด Reviews
เชื่อมต่อผู้ใช้กับภาพยนตร์ โดยให้แอปแสดงการให้คะแนนและความคิดเห็นที่ผู้ใช้สร้างขึ้น
ความสัมพันธ์ระหว่างภาพยนตร์ นักแสดง และผู้ใช้ทำให้แอปมีความน่าสนใจมากขึ้น ตารางการรวม MovieActor
ช่วยแสดงรายละเอียดนักแสดงและผลงานภาพยนตร์ของนักแสดง ประเภท FavoriteMovie
ช่วยให้ผู้ใช้สามารถตั้งค่าภาพยนตร์เป็นรายการโปรด เพื่อให้แอปแสดงรายการโปรดที่ปรับเปลี่ยนในแบบของคุณและไฮไลต์รายการยอดนิยม
ตั้งค่าตาราง Movie
ประเภท Movie
จะกำหนดโครงสร้างหลักสำหรับเอนทิตีภาพยนตร์ ซึ่งรวมถึงช่องต่างๆ เช่น title
, genre
, releaseYear
และ rating
คัดลอกและวางข้อมูลโค้ดลงในไฟล์ dataconnect/schema/schema.gql
type Movie
@table {
id: UUID! @default(expr: "uuidV4()")
title: String!
imageUrl: String!
releaseYear: Int
genre: String
rating: Float
description: String
tags: [String]
}
สรุปประเด็นสำคัญ:
- id: UUID ที่ไม่ซ้ำกันสำหรับภาพยนตร์แต่ละเรื่อง ซึ่งสร้างขึ้นโดยใช้
@default(expr: "uuidV4()")
ตั้งค่าตาราง MovieMetadata
ประเภท MovieMetadata
จะสร้างความสัมพันธ์แบบ 1:1 กับประเภท Movie
ซึ่งรวมถึงข้อมูลเพิ่มเติม เช่น ผู้กำกับภาพยนตร์
คัดลอกและวางข้อมูลโค้ดลงในไฟล์ dataconnect/schema/schema.gql
type MovieMetadata
@table {
# @ref creates a field in the current table (MovieMetadata)
# It is a reference that holds the primary key of the referenced type
# In this case, @ref(fields: "movieId", references: "id") is implied
movie: Movie! @ref
# movieId: UUID <- this is created by the above @ref
director: String
}
สรุปประเด็นสำคัญ:
- Movie! @ref: อ้างอิงประเภท
Movie
ซึ่งจะสร้างความสัมพันธ์ของคีย์ต่างประเทศ
ตั้งค่าตาราง Actor
คัดลอกและวางข้อมูลโค้ดลงในไฟล์ dataconnect/schema/schema.gql
type Actor @table {
id: UUID!
imageUrl: String!
name: String! @col(name: "name", dataType: "varchar(30)")
}
ประเภท Actor
แสดงถึงนักแสดงในฐานข้อมูลภาพยนตร์ โดยที่นักแสดงแต่ละคนอาจเป็นส่วนหนึ่งของภาพยนตร์หลายเรื่อง ซึ่งจะทำให้เกิดความสัมพันธ์แบบหลายต่อหลายรายการ
ตั้งค่าตาราง MovieActor
คัดลอกและวางข้อมูลโค้ดลงในไฟล์ dataconnect/schema/schema.gql
type MovieActor @table(key: ["movie", "actor"]) {
# @ref creates a field in the current table (MovieActor) that holds the primary key of the referenced type
# In this case, @ref(fields: "id") is implied
movie: Movie!
# movieId: UUID! <- this is created by the implied @ref, see: implicit.gql
actor: Actor!
# actorId: UUID! <- this is created by the implied @ref, see: implicit.gql
role: String! # "main" or "supporting"
}
สรุปประเด็นสำคัญ:
- movie: อ้างอิงประเภท Movie โดยจะสร้างคีย์ต่างประเทศ movieId: UUID โดยปริยาย
- actor: อ้างอิงประเภท Actor ซึ่งจะสร้างคีย์ต่างประเทศ actorId: UUID โดยปริยาย
- role: กำหนดบทบาทของนักแสดงในภาพยนตร์ (เช่น "main" หรือ "supporting")
ตั้งค่าตาราง User
ประเภท User
จะกำหนดเอนทิตีผู้ใช้ที่โต้ตอบกับภาพยนตร์ด้วยการเขียนรีวิวหรือตั้งภาพยนตร์เป็นรายการโปรด
คัดลอกและวางข้อมูลโค้ดลงในไฟล์ dataconnect/schema/schema.gql
type User
@table {
id: String! @col(name: "auth_uid")
username: String! @col(dataType: "varchar(50)")
# The following are generated from the @ref in the Review table
# reviews_on_user
# movies_via_Review
}
ตั้งค่าตาราง FavoriteMovie
ประเภท FavoriteMovie
คือตารางการรวมที่จัดการความสัมพันธ์แบบหลายต่อหลายรายการระหว่างผู้ใช้กับภาพยนตร์ที่ชอบ แต่ละตารางจะลิงก์ User
กับ Movie
คัดลอกและวางข้อมูลโค้ดลงในไฟล์ dataconnect/schema/schema.gql
type FavoriteMovie
@table(name: "FavoriteMovies", singular: "favorite_movie", plural: "favorite_movies", key: ["user", "movie"]) {
# @ref is implicit
user: User!
movie: Movie!
}
สรุปประเด็นสำคัญ:
- movie: อ้างอิงประเภท Movie จะสร้างคีย์ต่างประเทศ
movieId: UUID!
โดยปริยาย - user: อ้างอิงประเภทผู้ใช้ สร้างคีย์ต่างประเทศ
userId: UUID!
โดยนัย
ตั้งค่าตาราง Review
ประเภท Review
แสดงถึงเอนทิตีรีวิวและลิงก์ประเภท User
และ Movie
ในความสัมพันธ์แบบหลายต่อหลายรายการ (ผู้ใช้ 1 คนสามารถเขียนรีวิวได้หลายรายการ และภาพยนตร์แต่ละเรื่องมีรีวิวได้หลายรายการ)
คัดลอกและวางข้อมูลโค้ดลงในไฟล์ dataconnect/schema/schema.gql
type Review @table(name: "Reviews", key: ["movie", "user"]) {
id: UUID! @default(expr: "uuidV4()")
user: User!
movie: Movie!
rating: Int
reviewText: String
reviewDate: Date! @default(expr: "request.time")
}
สรุปประเด็นสำคัญ:
- user: อ้างอิงผู้ใช้ที่เขียนรีวิว
- movie: อ้างอิงภาพยนตร์ที่รีวิว
- reviewDate: ตั้งค่าเป็นเวลาที่สร้างรีวิวโดยอัตโนมัติโดยใช้
@default(expr: "request.time")
ฟิลด์และค่าเริ่มต้นที่สร้างขึ้นโดยอัตโนมัติ
สคีมาใช้นิพจน์อย่าง @default(expr: "uuidV4()")
เพื่อสร้างรหัสที่ไม่ซ้ำกันและการประทับเวลาโดยอัตโนมัติ ตัวอย่างเช่น ระบบจะป้อนข้อมูล UUID ลงในช่อง id
ของประเภท Movie
และ Review
โดยอัตโนมัติเมื่อสร้างระเบียนใหม่
เมื่อกําหนดสคีมาแล้ว แอปภาพยนตร์ของคุณจะมีรากฐานที่มั่นคงสําหรับโครงสร้างและความสัมพันธ์ของข้อมูล
5. ดึงข้อมูลภาพยนตร์ยอดนิยมและภาพยนตร์ล่าสุด
ในส่วนนี้ คุณจะแทรกข้อมูลภาพยนตร์จำลองลงในโปรแกรมจำลองในเครื่อง จากนั้นใช้ตัวเชื่อมต่อ (การค้นหา) และโค้ด TypeScript เพื่อเรียกใช้ตัวเชื่อมต่อเหล่านี้ในเว็บแอปพลิเคชัน เมื่อดำเนินการเสร็จสิ้น แอปจะดึงข้อมูลและแสดงภาพยนตร์ยอดนิยมและภาพยนตร์ล่าสุดแบบไดนามิกจากฐานข้อมูลได้โดยตรง
แทรกข้อมูลจำลองของภาพยนตร์ นักแสดง และรีวิว
- ใน VSCode ให้เปิด
dataconnect/moviedata_insert.gql
ตรวจสอบว่าโปรแกรมจําลองในส่วนขยาย Firebase Data Connect ทํางานอยู่ - คุณควรเห็นปุ่มเรียกใช้ (ในเครื่อง) ที่ด้านบนของไฟล์ คลิกเพื่อแทรกข้อมูลภาพยนตร์จำลองลงในฐานข้อมูล
- ตรวจสอบเทอร์มินัลการดำเนินการเชื่อมต่อข้อมูลเพื่อยืนยันว่าเพิ่มข้อมูลเรียบร้อยแล้ว
ติดตั้งใช้งานเครื่องมือเชื่อมต่อ
- เปิด
dataconnect/movie-connector/queries.gql
คุณจะเห็นการค้นหาListMovies
พื้นฐานในความคิดเห็น ดังนี้ ข้อความค้นหานี้จะดึงข้อมูลภาพยนตร์ทั้งหมดและรายละเอียดของภาพยนตร์ (เช่นquery ListMovies @auth(level: PUBLIC) { movies { id title imageUrl releaseYear genre rating tags description } }
id
,title
,releaseYear
) แต่ไม่จัดเรียงภาพยนตร์ - แทนที่การค้นหา
ListMovies
ที่มีอยู่ด้วยการค้นหาต่อไปนี้เพื่อเพิ่มตัวเลือกการจัดเรียงและจํากัด# List subset of fields for movies query ListMovies($orderByRating: OrderDirection, $orderByReleaseYear: OrderDirection, $limit: Int) @auth(level: PUBLIC) { movies( orderBy: [ { rating: $orderByRating }, { releaseYear: $orderByReleaseYear } ] limit: $limit ) { id title imageUrl releaseYear genre rating tags description } }
- คลิกปุ่มเรียกใช้ (ในเครื่อง) เพื่อเรียกใช้การค้นหากับฐานข้อมูลในเครื่อง นอกจากนี้ คุณยังป้อนตัวแปรการค้นหาในแผงการกําหนดค่าก่อนเรียกใช้ได้
สรุปประเด็นสำคัญ:
movies()
: ช่องการค้นหา GraphQL สำหรับการดึงข้อมูลภาพยนตร์จากฐานข้อมูลorderByRating
: พารามิเตอร์สำหรับจัดเรียงภาพยนตร์ตามการจัดประเภท (จากน้อยไปมาก/จากมากไปน้อย)orderByReleaseYear
: พารามิเตอร์สำหรับจัดเรียงภาพยนตร์ตามปีเผยแพร่ (จากน้อยไปมาก/จากมากไปน้อย)limit
: จำกัดจำนวนภาพยนตร์ที่แสดง
ผสานรวมการค้นหาในเว็บแอป
ในส่วนนี้ของโค้ดแล็บ คุณจะใช้การค้นหาที่กําหนดไว้ในส่วนก่อนหน้าในเว็บแอปของคุณ โปรแกรมจําลอง Firebase Data Connect จะสร้าง SDK ตามข้อมูลในไฟล์ .gql
(โดยเฉพาะ schema.gql
, queries.gql
, mutations.gql
) และไฟล์ connector.yaml
คุณเรียกใช้ SDK เหล่านี้ได้โดยตรงในแอปพลิเคชัน
- ใน
MovieService
(app/src/lib/MovieService.tsx
) ให้ยกเลิกการคอมเมนต์คำสั่งการนําเข้าที่ด้านบน ฟังก์ชันimport { listMovies, ListMoviesData, OrderDirection } from "@movie/dataconnect";
listMovies
, ประเภทคำตอบListMoviesData
และ enumOrderDirection
คือ SDK ทั้งหมดที่โปรแกรมจำลอง Firebase Data Connect สร้างขึ้นตามสคีมาและการค้นหาที่คุณกำหนดไว้ก่อนหน้านี้ - แทนที่ฟังก์ชัน
handleGetTopMovies
และhandleGetLatestMovies
ด้วยโค้ดต่อไปนี้// Fetch top-rated movies export const handleGetTopMovies = async ( limit: number ): Promise<ListMoviesData["movies"] | null> => { try { const response = await listMovies({ orderByRating: OrderDirection.DESC, limit, }); return response.data.movies; } catch (error) { console.error("Error fetching top movies:", error); return null; } }; // Fetch latest movies export const handleGetLatestMovies = async ( limit: number ): Promise<ListMoviesData["movies"] | null> => { try { const response = await listMovies({ orderByReleaseYear: OrderDirection.DESC, limit, }); return response.data.movies; } catch (error) { console.error("Error fetching latest movies:", error); return null; } };
สรุปประเด็นสำคัญ:
listMovies
: ฟังก์ชันที่สร้างขึ้นโดยอัตโนมัติซึ่งเรียกใช้การค้นหาlistMovies
เพื่อดึงข้อมูลรายการภาพยนตร์ ซึ่งรวมถึงตัวเลือกการจัดเรียงตามการจัดประเภทหรือปีเผยแพร่ รวมถึงการจำกัดจำนวนผลการค้นหาListMoviesData
: ประเภทผลลัพธ์ที่ใช้แสดงภาพยนตร์ยอดนิยม 10 อันดับแรกและภาพยนตร์ล่าสุดในหน้าแรกของแอป
ดูการใช้งานจริง
โหลดเว็บแอปซ้ำเพื่อดูการค้นหา ตอนนี้หน้าแรกจะแสดงรายการภาพยนตร์แบบไดนามิก โดยดึงข้อมูลจากฐานข้อมูลในเครื่องโดยตรง คุณจะเห็นภาพยนตร์ยอดนิยมและภาพยนตร์ล่าสุดปรากฏขึ้นอย่างราบรื่น ซึ่งแสดงข้อมูลที่คุณเพิ่งตั้งค่า
6. แสดงรายละเอียดภาพยนตร์และนักแสดง
ในส่วนนี้ คุณจะใช้ฟังก์ชันการทำงานเพื่อดึงข้อมูลโดยละเอียดของภาพยนตร์หรือนักแสดงโดยใช้รหัสที่ไม่ซ้ำกัน ซึ่งไม่เพียงแต่จะดึงข้อมูลจากตารางที่เกี่ยวข้องเท่านั้น แต่ยังรวมตารางที่เกี่ยวข้องเพื่อแสดงรายละเอียดที่ครอบคลุม เช่น รีวิวภาพยนตร์และผลงานภาพยนตร์ของนักแสดง
ติดตั้งใช้งานเครื่องมือเชื่อมต่อ
- เปิด
dataconnect/movie-connector/queries.gql
ในโปรเจ็กต์ - เพิ่มข้อความค้นหาต่อไปนี้เพื่อดึงรายละเอียดภาพยนตร์และนักแสดง
# Get movie by id query GetMovieById($id: UUID!) @auth(level: PUBLIC) { movie(id: $id) { id title imageUrl releaseYear genre rating description tags metadata: movieMetadatas_on_movie { director } mainActors: actors_via_MovieActor(where: { role: { eq: "main" } }) { id name imageUrl } supportingActors: actors_via_MovieActor( where: { role: { eq: "supporting" } } ) { id name imageUrl } reviews: reviews_on_movie { id reviewText reviewDate rating user { id username } } } } # Get actor by id query GetActorById($id: UUID!) @auth(level: PUBLIC) { actor(id: $id) { id name imageUrl mainActors: movies_via_MovieActor(where: { role: { eq: "main" } }) { id title genre tags imageUrl } supportingActors: movies_via_MovieActor( where: { role: { eq: "supporting" } } ) { id title genre tags imageUrl } } }
- บันทึกการเปลี่ยนแปลงและตรวจสอบข้อความค้นหา
สรุปประเด็นสำคัญ:
movie()
/actor()
: ช่องการค้นหา GraphQL สำหรับการดึงข้อมูลภาพยนตร์หรือนักแสดงรายการเดียวจากตารางMovies
หรือActors
_on_
: ตัวเลือกนี้ช่วยให้เข้าถึงฟิลด์จากประเภทที่เชื่อมโยงซึ่งมีความสัมพันธ์ของคีย์ต่างประเทศได้โดยตรง เช่นreviews_on_movie
จะดึงข้อมูลรีวิวทั้งหมดที่เกี่ยวข้องกับภาพยนตร์หนึ่งๆ_via_
: ใช้เพื่อไปยังส่วนต่างๆ ของความสัมพันธ์แบบหลายต่อหลายรายการผ่านตารางการรวม เช่นactors_via_MovieActor
เข้าถึงประเภทActor
ผ่านตารางการเข้าร่วมMovieActor
และเงื่อนไขwhere
จะกรองนักแสดงตามบทบาท (เช่น "หลัก" หรือ "สนับสนุน")
ทดสอบการค้นหาโดยป้อนข้อมูลจำลอง
- ในแผงการดําเนินการของ Data Connect คุณสามารถทดสอบการค้นหาได้โดยป้อนรหัสจำลอง เช่น
{"id": "550e8400-e29b-41d4-a716-446655440000"}
- คลิกเรียกใช้ (ในเครื่อง) สำหรับ
GetMovieById
เพื่อเรียกข้อมูลเกี่ยวกับ "Quantum Paradox" (ภาพยนตร์จำลองที่รหัสข้างต้นเกี่ยวข้อง)
ผสานรวมการค้นหาในเว็บแอป
- ใน
MovieService
(app/src/lib/MovieService.tsx
) ให้ยกเลิกการคอมเมนต์การนําเข้าต่อไปนี้import { getMovieById, GetMovieByIdData } from "@movie/dataconnect"; import { GetActorByIdData, getActorById } from "@movie/dataconnect";
- แทนที่ฟังก์ชัน
handleGetMovieById
และhandleGetActorById
ด้วยโค้ดต่อไปนี้// Fetch movie details by ID export const handleGetMovieById = async ( movieId: string ) => { try { const response = await getMovieById({ id: movieId }); if (response.data.movie) { return response.data.movie; } return null; } catch (error) { console.error("Error fetching movie:", error); return null; } }; // Calling generated SDK for GetActorById export const handleGetActorById = async ( actorId: string ): Promise<GetActorByIdData["actor"] | null> => { try { const response = await getActorById({ id: actorId }); if (response.data.actor) { return response.data.actor; } return null; } catch (error) { console.error("Error fetching actor:", error); return null; } };
สรุปประเด็นสำคัญ:
getMovieById
/getActorById
: ฟังก์ชันเหล่านี้สร้างขึ้นโดยอัตโนมัติซึ่งเรียกใช้การค้นหาที่คุณกำหนดไว้ เพื่อดึงข้อมูลโดยละเอียดสำหรับภาพยนตร์หรือนักแสดงที่เฉพาะเจาะจงGetMovieByIdData
/GetActorByIdData
: ประเภทผลลัพธ์เหล่านี้ใช้เพื่อแสดงรายละเอียดภาพยนตร์และนักแสดงในแอป
ดูการใช้งานจริง
จากนั้นไปที่หน้าแรกของเว็บแอป คลิกภาพยนตร์เพื่อดูรายละเอียดทั้งหมด รวมถึงนักแสดงและรีวิว ซึ่งเป็นข้อมูลที่ดึงมาจากตารางที่เกี่ยวข้อง ในทำนองเดียวกัน การคลิกที่นักแสดงจะแสดงภาพยนตร์ที่นักแสดงคนนั้นแสดง
7. จัดการการตรวจสอบสิทธิ์ของผู้ใช้
ในส่วนนี้ คุณจะใช้ฟังก์ชันการลงชื่อเข้าใช้และออกจากระบบของผู้ใช้โดยใช้ Firebase Authentication นอกจากนี้ คุณจะใช้ข้อมูลการตรวจสอบสิทธิ์ Firebase เพื่อดึงข้อมูลหรืออัปเดตข้อมูลผู้ใช้ใน Firebase DataConnect โดยตรงได้ ซึ่งช่วยให้มั่นใจได้ว่าการจัดการผู้ใช้ภายในแอปจะปลอดภัย
ติดตั้งใช้งานเครื่องมือเชื่อมต่อ
- เปิด
mutations.gql
ในdataconnect/movie-connector/
- เพิ่มการดัดแปลงต่อไปนี้เพื่อสร้างหรืออัปเดตผู้ใช้ที่ตรวจสอบสิทธิ์ในปัจจุบัน
# Create or update the current authenticated user mutation UpsertUser($username: String!) @auth(level: USER) { user_upsert( data: { id_expr: "auth.uid" username: $username } ) }
สรุปประเด็นสำคัญ:
id_expr: "auth.uid"
: ตัวเลือกนี้ใช้auth.uid
ซึ่งมาจาก Firebase Authentication โดยตรง ไม่ใช่จากผู้ใช้หรือแอป ซึ่งจะเพิ่มความปลอดภัยอีกชั้นโดยการจัดการรหัสผู้ใช้อย่างปลอดภัยและอัตโนมัติ
ดึงข้อมูลผู้ใช้ปัจจุบัน
- เปิด
queries.gql
ในdataconnect/movie-connector/
- เพิ่มข้อความค้นหาต่อไปนี้เพื่อดึงข้อมูลผู้ใช้ปัจจุบัน
# Get user by ID query GetCurrentUser @auth(level: USER) { user(key: { id_expr: "auth.uid" }) { id username reviews: reviews_on_user { id rating reviewDate reviewText movie { id title } } favoriteMovies: favorite_movies_on_user { movie { id title genre imageUrl releaseYear rating description tags metadata: movieMetadatas_on_movie { director } } } } }
สรุปประเด็นสำคัญ:
auth.uid
: ระบบจะดึงข้อมูลนี้มาจากการตรวจสอบสิทธิ์ Firebase โดยตรง เพื่อให้เข้าถึงข้อมูลที่เจาะจงผู้ใช้ได้อย่างปลอดภัย- ฟิลด์
_on_
: ฟิลด์เหล่านี้แสดงตารางที่เข้าร่วมreviews_on_user
: ดึงข้อมูลรีวิวทั้งหมดที่เกี่ยวข้องกับผู้ใช้ ซึ่งรวมถึงid
และtitle
ของภาพยนตร์favorite_movies_on_user
: ดึงข้อมูลภาพยนตร์ทั้งหมดที่ผู้ใช้ทำเครื่องหมายว่าชื่นชอบ รวมถึงข้อมูลโดยละเอียด เช่นgenre
,releaseYear
,rating
และmetadata
ผสานรวมการค้นหาในเว็บแอป
- ใน
MovieService
(app/src/lib/MovieService.tsx
) ให้ยกเลิกการคอมเมนต์การนําเข้าต่อไปนี้import { upsertUser } from "@movie/dataconnect"; import { getCurrentUser, GetCurrentUserData } from "@movie/dataconnect";
- แทนที่ฟังก์ชัน
handleAuthStateChange
และhandleGetCurrentUser
ด้วยโค้ดต่อไปนี้// Handle user authentication state changes and upsert user export const handleAuthStateChange = ( auth: any, setUser: (user: User | null) => void ) => { return onAuthStateChanged(auth, async (user) => { if (user) { setUser(user); const username = user.email?.split("@")[0] || "anon"; await upsertUser({ username }); } else { setUser(null); } }); }; // Fetch current user profile export const handleGetCurrentUser = async (): Promise< GetCurrentUserData["user"] | null > => { try { const response = await getCurrentUser(); return response.data.user; } catch (error) { console.error("Error fetching user profile:", error); return null; } };
สรุปประเด็นสำคัญ:
handleAuthStateChange
: ฟังการเปลี่ยนแปลงสถานะการตรวจสอบสิทธิ์ เมื่อผู้ใช้ลงชื่อเข้าใช้ ระบบจะตั้งค่าข้อมูลของผู้ใช้และเรียกใช้upsertUser
mutation เพื่อสร้างหรืออัปเดตข้อมูลของผู้ใช้ในฐานข้อมูลhandleGetCurrentUser
: ดึงข้อมูลโปรไฟล์ของผู้ใช้ปัจจุบันโดยใช้การค้นหาgetCurrentUser
ซึ่งจะดึงข้อมูลรีวิวและภาพยนตร์โปรดของผู้ใช้
ดูการใช้งานจริง
จากนั้นคลิกปุ่ม "ลงชื่อเข้าใช้ด้วย Google" ในแถบนําทาง คุณสามารถลงชื่อเข้าใช้โดยใช้โปรแกรมจำลองการตรวจสอบสิทธิ์ Firebase หลังจากลงชื่อเข้าใช้แล้ว ให้คลิก "โปรไฟล์ของฉัน" ขณะนี้ส่วนนี้จะว่างเปล่า แต่คุณได้สร้างรากฐานสําหรับการจัดการข้อมูลที่เจาะจงผู้ใช้ในแอปแล้ว
8. ใช้การโต้ตอบของผู้ใช้
ในส่วนนี้ของโค้ดแล็บ คุณจะใช้การโต้ตอบของผู้ใช้ในแอปรีวิวภาพยนตร์ โดยเฉพาะอย่างยิ่งการอนุญาตให้ผู้ใช้จัดการภาพยนตร์ที่ชอบ รวมถึงเขียนหรือลบรีวิว
อนุญาตให้ผู้ใช้ตั้งค่าภาพยนตร์เป็นรายการโปรด
ในส่วนนี้ คุณจะต้องตั้งค่าฐานข้อมูลเพื่อให้ผู้ใช้เพิ่มภาพยนตร์ที่ชอบได้
ติดตั้งใช้งานเครื่องมือเชื่อมต่อ
- เปิด
mutations.gql
ในdataconnect/movie-connector/
- เพิ่มการกลายพันธุ์ต่อไปนี้เพื่อจัดการกับการทำให้ภาพยนตร์เป็นรายการโปรด
# Add a movie to the user's favorites list mutation AddFavoritedMovie($movieId: UUID!) @auth(level: USER) { favorite_movie_upsert(data: { userId_expr: "auth.uid", movieId: $movieId }) } # Remove a movie from the user's favorites list mutation DeleteFavoritedMovie($movieId: UUID!) @auth(level: USER) { favorite_movie_delete(key: { userId_expr: "auth.uid", movieId: $movieId }) }
สรุปประเด็นสำคัญ:
userId_expr: "auth.uid"
: ใช้auth.uid
ซึ่งการตรวจสอบสิทธิ์ Firebase จัดหาให้โดยตรง เพื่อให้มั่นใจว่าจะมีเพียงข้อมูลของผู้ใช้ที่ตรวจสอบสิทธิ์เท่านั้นที่เข้าถึงหรือแก้ไขได้
ตรวจสอบว่าภาพยนตร์เป็นรายการโปรดหรือไม่
- เปิด
queries.gql
ในdataconnect/movie-connector/
- เพิ่มการค้นหาต่อไปนี้เพื่อตรวจสอบว่าภาพยนตร์เป็นรายการโปรดหรือไม่
query GetIfFavoritedMovie($movieId: UUID!) @auth(level: USER) { favorite_movie(key: { userId_expr: "auth.uid", movieId: $movieId }) { movieId } }
สรุปประเด็นสำคัญ:
auth.uid
: ช่วยให้เข้าถึงข้อมูลที่เจาะจงผู้ใช้ได้อย่างปลอดภัยโดยใช้การตรวจสอบสิทธิ์ Firebasefavorite_movie
: ตรวจสอบตารางการเข้าร่วมfavorite_movies
เพื่อดูว่าผู้ใช้ปัจจุบันได้ทำเครื่องหมายภาพยนตร์ที่เฉพาะเจาะจงว่าเป็นรายการโปรดหรือไม่
ผสานรวมการค้นหาในเว็บแอป
- ใน
MovieService
(app/src/lib/MovieService.tsx
) ให้ยกเลิกการคอมเมนต์การนําเข้าต่อไปนี้import { addFavoritedMovie, deleteFavoritedMovie, getIfFavoritedMovie } from "@movie/dataconnect";
- แทนที่ฟังก์ชัน
handleAddFavoritedMovie
,handleDeleteFavoritedMovie
และhandleGetIfFavoritedMovie
ด้วยโค้ดต่อไปนี้// Add a movie to user's favorites export const handleAddFavoritedMovie = async ( movieId: string ): Promise<void> => { try { await addFavoritedMovie({ movieId }); } catch (error) { console.error("Error adding movie to favorites:", error); throw error; } }; // Remove a movie from user's favorites export const handleDeleteFavoritedMovie = async ( movieId: string ): Promise<void> => { try { await deleteFavoritedMovie({ movieId }); } catch (error) { console.error("Error removing movie from favorites:", error); throw error; } }; // Check if the movie is favorited by the user export const handleGetIfFavoritedMovie = async ( movieId: string ): Promise<boolean> => { try { const response = await getIfFavoritedMovie({ movieId }); return !!response.data.favorite_movie; } catch (error) { console.error("Error checking if movie is favorited:", error); return false; } };
สรุปประเด็นสำคัญ:
handleAddFavoritedMovie
และhandleDeleteFavoritedMovie
: ใช้การดัดแปลงเพื่อเพิ่มหรือนำภาพยนตร์ออกจากรายการโปรดของผู้ใช้อย่างปลอดภัยhandleGetIfFavoritedMovie
: ใช้การค้นหาgetIfFavoritedMovie
เพื่อตรวจสอบว่าผู้ใช้ได้ทำเครื่องหมายภาพยนตร์ว่าเป็นรายการโปรดหรือไม่
ดูการใช้งานจริง
ตอนนี้คุณเพิ่มภาพยนตร์หรือรายการทีวีที่ชอบหรือไม่ชอบได้แล้วโดยคลิกไอคอนหัวใจในการ์ดภาพยนตร์และหน้ารายละเอียดภาพยนตร์ นอกจากนี้ คุณยังดูภาพยนตร์ที่ชอบในหน้าโปรไฟล์ได้ด้วย
อนุญาตให้ผู้ใช้เขียนหรือลบรีวิว
ถัดไป คุณจะใช้ส่วนสำหรับจัดการรีวิวของผู้ใช้ในแอป
ติดตั้งใช้งานเครื่องมือเชื่อมต่อ
ใน mutations.gql
(dataconnect/movie-connector/mutations.gql
): เพิ่มการกลายพันธุ์ต่อไปนี้
# Add a review for a movie
mutation AddReview($movieId: UUID!, $rating: Int!, $reviewText: String!)
@auth(level: USER) {
review_insert(
data: {
userId_expr: "auth.uid"
movieId: $movieId
rating: $rating
reviewText: $reviewText
reviewDate_date: { today: true }
}
)
}
# Delete a user's review for a movie
mutation DeleteReview($movieId: UUID!) @auth(level: USER) {
review_delete(key: { userId_expr: "auth.uid", movieId: $movieId })
}
สรุปประเด็นสำคัญ:
userId_expr: "auth.uid"
: ตรวจสอบว่ารีวิวเชื่อมโยงกับผู้ใช้ที่ตรวจสอบสิทธิ์แล้วreviewDate_date: { today: true }
: สร้างวันที่ปัจจุบันของการตรวจสอบโดยอัตโนมัติโดยใช้ DataConnect จึงไม่จำเป็นต้องป้อนข้อมูลด้วยตนเอง
ผสานรวมการค้นหาในเว็บแอป
- ใน
MovieService
(app/src/lib/MovieService.tsx
) ให้ยกเลิกการคอมเมนต์การนําเข้าต่อไปนี้import { addReview, deleteReview } from "@movie/dataconnect";
- แทนที่ฟังก์ชัน
handleAddReview
และhandleDeleteReview
ด้วยโค้ดต่อไปนี้// Add a review to a movie export const handleAddReview = async ( movieId: string, rating: number, reviewText: string ): Promise<void> => { try { await addReview({ movieId, rating, reviewText }); } catch (error) { console.error("Error adding review:", error); throw error; } }; // Delete a review from a movie export const handleDeleteReview = async (movieId: string): Promise<void> => { try { await deleteReview({ movieId }); } catch (error) { console.error("Error deleting review:", error); throw error; } };
สรุปประเด็นสำคัญ:
handleAddReview
: เรียกใช้การดัดแปลงaddReview
เพื่อเพิ่มรีวิวสำหรับภาพยนตร์ที่ระบุ โดยลิงก์รีวิวกับผู้ใช้ที่ตรวจสอบสิทธิ์อย่างปลอดภัยhandleDeleteReview
: ใช้การดัดแปลงdeleteReview
เพื่อนำรีวิวภาพยนตร์ของผู้ใช้ที่ตรวจสอบสิทธิ์ออก
ดูการใช้งานจริง
ตอนนี้ผู้ใช้สามารถเขียนรีวิวภาพยนตร์ในหน้ารายละเอียดภาพยนตร์ได้แล้ว นอกจากนี้ ผู้ใช้ยังดูและลบรีวิวของตนเองในหน้าโปรไฟล์ได้ด้วย ซึ่งช่วยให้ผู้ใช้ควบคุมการโต้ตอบกับแอปได้อย่างเต็มรูปแบบ
9. ตัวกรองขั้นสูงและการจับคู่ข้อความบางส่วน
ในส่วนนี้ คุณจะใช้ความสามารถในการค้นหาขั้นสูง ซึ่งช่วยให้ผู้ใช้ค้นหาภาพยนตร์ตามการจัดประเภทและปีที่เผยแพร่ที่หลากหลาย กรองตามประเภทและแท็ก ทำการจับคู่ข้อความบางส่วนในชื่อหรือคำอธิบาย และแม้แต่รวมตัวกรองหลายรายการเข้าด้วยกันเพื่อให้ได้ผลลัพธ์ที่แม่นยำยิ่งขึ้น
ติดตั้งใช้งานเครื่องมือเชื่อมต่อ
- เปิด
queries.gql
ในdataconnect/movie-connector/
- เพิ่มข้อความค้นหาต่อไปนี้เพื่อรองรับความสามารถในการค้นหาที่หลากหลาย
# Search for movies, actors, and reviews query SearchAll( $input: String $minYear: Int! $maxYear: Int! $minRating: Float! $maxRating: Float! $genre: String! ) @auth(level: PUBLIC) { moviesMatchingTitle: movies( where: { _and: [ { releaseYear: { ge: $minYear } } { releaseYear: { le: $maxYear } } { rating: { ge: $minRating } } { rating: { le: $maxRating } } { genre: { contains: $genre } } { title: { contains: $input } } ] } ) { id title genre rating imageUrl } moviesMatchingDescription: movies( where: { _and: [ { releaseYear: { ge: $minYear } } { releaseYear: { le: $maxYear } } { rating: { ge: $minRating } } { rating: { le: $maxRating } } { genre: { contains: $genre } } { description: { contains: $input } } ] } ) { id title genre rating imageUrl } actorsMatchingName: actors(where: { name: { contains: $input } }) { id name imageUrl } reviewsMatchingText: reviews(where: { reviewText: { contains: $input } }) { id rating reviewText reviewDate movie { id title } user { id username } } }
สรุปประเด็นสำคัญ:
- โอเปอเรเตอร์
_and
: รวมเงื่อนไขหลายรายการในการค้นหารายการเดียว ซึ่งช่วยให้กรองการค้นหาตามฟิลด์ต่างๆ ได้ เช่นreleaseYear
,rating
และgenre
- โอเปอเรเตอร์
contains
: ค้นหาข้อความที่ตรงกันบางส่วนภายในช่อง ในข้อความค้นหานี้ ระบบจะค้นหารายการที่ตรงกันภายในtitle
,description
,name
หรือreviewText
- ประโยค
where
: ระบุเงื่อนไขในการกรองข้อมูล ส่วนแต่ละส่วน (ภาพยนตร์ นักแสดง รีวิว) ใช้ประโยคwhere
เพื่อกำหนดเกณฑ์ที่เฉพาะเจาะจงสำหรับการค้นหา
ผสานรวมการค้นหาในเว็บแอป
- ใน
MovieService
(app/src/lib/MovieService.tsx
) ให้ยกเลิกการคอมเมนต์การนําเข้าต่อไปนี้import { searchAll, SearchAllData } from "@movie/dataconnect";
- แทนที่ฟังก์ชัน
handleSearchAll
ด้วยโค้ดต่อไปนี้// Function to perform the search using the query and filters export const handleSearchAll = async ( searchQuery: string, minYear: number, maxYear: number, minRating: number, maxRating: number, genre: string ): Promise<SearchAllData | null> => { try { const response = await searchAll({ input: searchQuery, minYear, maxYear, minRating, maxRating, genre, }); return response.data; } catch (error) { console.error("Error performing search:", error); return null; } };
สรุปประเด็นสำคัญ:
handleSearchAll
: ฟังก์ชันนี้ใช้การค้นหาsearchAll
เพื่อค้นหาตามข้อมูลที่ผู้ใช้ป้อน โดยกรองผลการค้นหาตามพารามิเตอร์ต่างๆ เช่น ปี การให้คะแนน ประเภท และการจับคู่ข้อความบางส่วน
ดูการใช้งานจริง
ไปที่หน้า "การค้นหาขั้นสูง" จากแถบนาบในเว็บแอป ตอนนี้คุณสามารถค้นหาภาพยนตร์ นักแสดง และรีวิวได้โดยใช้ตัวกรองและอินพุตต่างๆ เพื่อรับผลการค้นหาที่ละเอียดและปรับให้เหมาะกับคุณ
10. ไม่บังคับ: ติดตั้งใช้งานในระบบคลาวด์ (ต้องมีการเรียกเก็บเงิน)
เมื่อคุณทําซ้ำการพัฒนาซอฟต์แวร์ภายในแล้ว ก็ถึงเวลาที่จะติดตั้งสคีมา ข้อมูล และการค้นหาลงในเซิร์ฟเวอร์ ซึ่งทําได้โดยใช้ส่วนขยาย Firebase Data Connect ใน VS Code หรือ Firebase CLI
อัปเกรดแพ็กเกจราคาของ Firebase
หากต้องการผสานรวม Firebase Data Connect กับ Cloud SQL สําหรับ PostgreSQL โปรเจ็กต์ Firebase ของคุณต้องใช้แพ็กเกจราคาแบบชําระเงินตามการใช้งาน (Blaze) ซึ่งหมายความว่าโปรเจ็กต์จะลิงก์กับบัญชีการเรียกเก็บเงินระบบคลาวด์
- บัญชีการเรียกเก็บเงินระบบคลาวด์ต้องมีวิธีการชำระเงิน เช่น บัตรเครดิต
- หากคุณเพิ่งเริ่มใช้ Firebase และ Google Cloud ให้ตรวจสอบว่าคุณมีสิทธิ์รับเครดิตมูลค่า$300 และบัญชีการเรียกเก็บเงินระบบคลาวด์แบบทดลองใช้ฟรีหรือไม่
- หากคุณทำ Codelab นี้เป็นส่วนหนึ่งของกิจกรรม โปรดสอบถามผู้จัดว่ามีเครดิต Cloud เหลืออยู่ไหม
หากต้องการอัปเกรดโปรเจ็กต์เป็นแพ็กเกจ Blaze ให้ทำตามขั้นตอนต่อไปนี้
- ในคอนโซล Firebase ให้เลือกอัปเกรดแพ็กเกจ
- เลือกแพ็กเกจ Blaze ทำตามวิธีการบนหน้าจอเพื่อลิงก์บัญชีสำหรับการเรียกเก็บเงินใน Cloud กับโปรเจ็กต์
หากจำเป็นต้องสร้างบัญชีสำหรับการเรียกเก็บเงินใน Cloud เป็นส่วนหนึ่งของการอัปเกรดนี้ คุณอาจต้องกลับไปที่ขั้นตอนการอัปเกรดในคอนโซล Firebase เพื่อดำเนินการอัปเกรดให้เสร็จสมบูรณ์
เชื่อมต่อเว็บแอปกับโปรเจ็กต์ Firebase
- ลงทะเบียนเว็บแอปในโปรเจ็กต์ Firebase โดยใช้คอนโซล Firebase
- เปิดโปรเจ็กต์ แล้วคลิกเพิ่มแอป
- ละเว้นการตั้งค่า SDK และการกำหนดค่าในตอนนี้ แต่อย่าลืมคัดลอกออบเจ็กต์
firebaseConfig
ที่สร้างขึ้น
- แทนที่
firebaseConfig
ที่มีอยู่ในส่วนapp/src/lib/firebase.tsx
ด้วยการกำหนดค่าที่คุณเพิ่งคัดลอกมาจากคอนโซล Firebaseconst firebaseConfig = { apiKey: "API_KEY", authDomain: "PROJECT_ID.firebaseapp.com", projectId: "PROJECT_ID", storageBucket: "PROJECT_ID.firebasestorage.app", messagingSenderId: "SENDER_ID", appId: "APP_ID" };
- สร้างเว็บแอป: กลับไปที่ VS Code ในโฟลเดอร์
app
ให้ใช้ Vite เพื่อสร้างเว็บแอปสําหรับการโฮสต์การนําส่ง ดังนี้cd app npm run build
ตั้งค่าการตรวจสอบสิทธิ์ Firebase ในโปรเจ็กต์ Firebase
- ตั้งค่าการตรวจสอบสิทธิ์ Firebase ด้วย Google Sign-In
- (ไม่บังคับ) อนุญาตโดเมนสําหรับการตรวจสอบสิทธิ์ Firebase โดยใช้คอนโซล Firebase (เช่น
http://127.0.0.1
)- ในการตั้งค่าการตรวจสอบสิทธิ์ ให้ไปที่โดเมนที่ได้รับอนุญาต
- คลิก "เพิ่มโดเมน" และใส่โดเมนในเครื่องของคุณไว้ในรายการ
ทำให้ใช้งานได้ด้วย Firebase CLI
- ใน
dataconnect/dataconnect.yaml
ให้ตรวจสอบว่ารหัสอินสแตนซ์ ฐานข้อมูล และรหัสบริการตรงกับโปรเจ็กต์ของคุณspecVersion: "v1alpha" serviceId: "your-service-id" location: "us-central1" schema: source: "./schema" datasource: postgresql: database: "your-database-id" cloudSql: instanceId: "your-instance-id" connectorDirs: ["./movie-connector"]
- ตรวจสอบว่าคุณได้ตั้งค่า Firebase CLI กับโปรเจ็กต์แล้ว โดยทำดังนี้
npm i -g firebase-tools firebase login --reauth firebase use --add
- ในเทอร์มินัล ให้เรียกใช้คําสั่งต่อไปนี้เพื่อทำให้ใช้งานได้
firebase deploy --only dataconnect,hosting
- ใช้คําสั่งนี้เพื่อเปรียบเทียบการเปลี่ยนแปลงสคีมา
firebase dataconnect:sql:diff
- หากยอมรับการเปลี่ยนแปลงได้ ให้ใช้การเปลี่ยนแปลงดังกล่าวโดยทำดังนี้
firebase dataconnect:sql:migrate
อินสแตนซ์ Cloud SQL for PostgreSQL จะอัปเดตด้วยสคีมาและข้อมูลที่ติดตั้งใช้งานแล้วในขั้นสุดท้าย คุณสามารถตรวจสอบสถานะได้ในคอนโซล Firebase
ตอนนี้คุณควรเห็นแอปของคุณเผยแพร่อยู่ที่ your-project.web.app/
นอกจากนี้ คุณยังคลิกเรียกใช้ (เวอร์ชันที่ใช้งานจริง) ในแผง Firebase Data Connect ได้ เช่นเดียวกับที่ทำกับโปรแกรมจำลองในเครื่อง เพื่อเพิ่มข้อมูลลงในสภาพแวดล้อมเวอร์ชันที่ใช้งานจริง
11. ไม่บังคับ: การค้นหาเวกเตอร์ด้วย Firebase Data Connect (ต้องมีการเรียกเก็บเงิน)
ในส่วนนี้ คุณจะเปิดใช้การค้นหาเวกเตอร์ในแอปรีวิวภาพยนตร์โดยใช้ Firebase Data Connect ฟีเจอร์นี้ช่วยให้ค้นหาตามเนื้อหาได้ เช่น ค้นหาภาพยนตร์ที่มีคำอธิบายคล้ายกันโดยใช้การฝังเวกเตอร์
ขั้นตอนนี้กำหนดให้คุณทำขั้นตอนสุดท้ายของโค้ดแล็บนี้ให้เสร็จสมบูรณ์เพื่อนำไปใช้งานใน Google Cloud
อัปเดตสคีมาให้รวมการฝังสําหรับช่อง
ใน dataconnect/schema/schema.gql
ให้เพิ่มช่อง descriptionEmbedding
ลงในตาราง Movie
โดยทำดังนี้
type Movie
# The below parameter values are generated by default with @table, and can be edited manually.
@table {
# implicitly calls @col to generates a column name. ex: @col(name: "movie_id")
id: UUID! @default(expr: "uuidV4()")
title: String!
imageUrl: String!
releaseYear: Int
genre: String
rating: Float
description: String
tags: [String]
descriptionEmbedding: Vector @col(size:768) # Enables vector search
}
สรุปประเด็นสำคัญ:
descriptionEmbedding: Vector @col(size:768)
: ช่องนี้จะจัดเก็บการฝังเชิงความหมายของคำอธิบายภาพยนตร์ ซึ่งช่วยให้ค้นหาเนื้อหาตามเวกเตอร์ในแอปได้
เปิดใช้งาน Vertex AI
- ทำตามคำแนะนำเบื้องต้นเพื่อตั้งค่า Vertex AI API จาก Google Cloud ขั้นตอนนี้เป็นขั้นตอนสําคัญในการสนับสนุนฟังก์ชันการสร้างการฝังและเวกเตอร์การค้นหา
- ทำให้สคีมาใช้งานได้อีกครั้งเพื่อเปิดใช้งาน
pgvector
และการค้นหาเวกเตอร์โดยคลิก "ทำให้ใช้งานได้จริง" โดยใช้ส่วนขยาย Firebase Data Connect ใน VS Code
ป้อนข้อมูลฐานข้อมูลด้วยข้อมูลเชิงลึก
- เปิดโฟลเดอร์
dataconnect
ใน VS Code - คลิกเรียกใช้(ในเครื่อง) ใน
optional_vector_embed.gql
เพื่อป้อนข้อมูลฐานข้อมูลด้วยข้อมูลเชิงลึกของภาพยนตร์
เพิ่มคำค้นหาเวกเตอร์
ใน dataconnect/movie-connector/queries.gql
ให้เพิ่มข้อความค้นหาต่อไปนี้เพื่อทำการค้นหาเวกเตอร์
# Search movie descriptions using L2 similarity with Vertex AI
query SearchMovieDescriptionUsingL2Similarity($query: String!)
@auth(level: PUBLIC) {
movies_descriptionEmbedding_similarity(
compare_embed: { model: "textembedding-gecko@003", text: $query }
method: L2
within: 2
limit: 5
) {
id
title
description
tags
rating
imageUrl
}
}
สรุปประเด็นสำคัญ:
compare_embed
: ระบุรูปแบบการฝัง (textembedding-gecko@003
) และข้อความอินพุต ($query
) สำหรับการเปรียบเทียบmethod
: ระบุวิธีการวัดความคล้ายคลึง (L2
) ซึ่งแสดงถึงระยะทางแบบยูคลิดwithin
: จำกัดการค้นหาไว้ที่ภาพยนตร์ที่มีระยะ L2 ไม่เกิน 2 โดยเน้นที่เนื้อหาที่ตรงกันมากlimit
: จำกัดจำนวนผลลัพธ์ที่แสดงผลเป็น 5 รายการ
ใช้ฟังก์ชันการค้นหาเวกเตอร์ในแอป
เมื่อตั้งค่าสคีมาและคําค้นหาแล้ว ให้ผสานรวมการค้นหาเวกเตอร์เข้ากับเลเยอร์บริการของแอป ขั้นตอนนี้ช่วยให้คุณเรียกใช้คำค้นหาจากเว็บแอปได้
- ใน
app/src/lib/
MovieService.ts
ให้ยกเลิกการคอมเมนต์การนําเข้าต่อไปนี้จาก SDK ซึ่งจะทํางานเหมือนกับการค้นหาอื่นๆimport { searchMovieDescriptionUsingL2similarity, SearchMovieDescriptionUsingL2similarityData, } from "@movie/dataconnect";
- เพิ่มฟังก์ชันต่อไปนี้เพื่อผสานรวมการค้นหาที่อิงตามเวกเตอร์ไว้ในแอป
// Perform vector-based search for movies based on description export const searchMoviesByDescription = async ( query: string ): Promise< | SearchMovieDescriptionUsingL2similarityData["movies_descriptionEmbedding_similarity"] | null > => { try { const response = await searchMovieDescriptionUsingL2similarity({ query }); return response.data.movies_descriptionEmbedding_similarity; } catch (error) { console.error("Error fetching movie descriptions:", error); return null; } };
สรุปประเด็นสำคัญ:
searchMoviesByDescription
: ฟังก์ชันนี้จะเรียกคําค้นหาsearchMovieDescriptionUsingL2similarity
โดยส่งข้อความที่ป้อนเพื่อค้นหาเนื้อหาตามเวกเตอร์
ดูการใช้งานจริง
ไปที่ส่วน "การค้นหาเวกเตอร์" ในแถบนําทาง แล้วพิมพ์วลีอย่าง "โรแมนติกและทันสมัย" คุณจะเห็นรายการภาพยนตร์ที่ตรงกับเนื้อหาที่คุณค้นหา หรือไปที่หน้ารายละเอียดภาพยนตร์ของภาพยนตร์เรื่องใดก็ได้ แล้วดูส่วนภาพยนตร์ที่คล้ายกันซึ่งอยู่ด้านล่างของหน้า
12. บทสรุป
ยินดีด้วย คุณควรใช้เว็บแอปได้แล้ว หากต้องการเล่นกับข้อมูลภาพยนตร์ของคุณเอง ไม่ต้องกังวล เพียงแทรกข้อมูลของคุณเองโดยใช้ส่วนขยาย Firebase Data Connect โดยเลียนแบบไฟล์ _insert.gql
หรือเพิ่มผ่านแผงการดำเนินการของ Data Connect ใน VS Code