1. قبل از شروع
در این کد لبه، شما Firebase Data Connect را با یک پایگاه داده Cloud SQL ادغام خواهید کرد تا یک برنامه وب بررسی فیلم بسازید. برنامه تکمیلشده نشان میدهد که Firebase Data Connect چگونه فرآیند ساخت برنامههای مبتنی بر SQL را ساده میکند. این ویژگی ها را شامل می شود:
- احراز هویت: احراز هویت سفارشی را برای جستارها و جهشهای برنامه خود اجرا کنید، مطمئن شوید که فقط کاربران مجاز میتوانند با دادههای شما تعامل داشته باشند.
- طرحواره GraphQL: ساختارهای داده خود را با استفاده از طرحواره GraphQL منعطف و متناسب با نیازهای یک برنامه وب بررسی فیلم ایجاد و مدیریت کنید.
- پرسشها و جهشهای SQL: دادهها را در Cloud SQL با استفاده از کوئریها و جهشهای ارائهشده توسط GraphQL بازیابی، بهروزرسانی و مدیریت کنید.
- جستجوی پیشرفته با تطابق جزئی رشته: از فیلترها و گزینههای جستجو برای یافتن فیلمها بر اساس زمینههایی مانند عنوان، توضیحات یا برچسبها استفاده کنید.
- (اختیاری) ادغام جستجوی برداری: قابلیت جستجوی محتوا را با استفاده از جستجوی برداری Firebase Data Connect اضافه کنید تا یک تجربه کاربری غنی بر اساس ورودی و ترجیحات ارائه دهید.
پیش نیازها
شما به درک اولیه جاوا اسکریپت نیاز دارید.
چیزی که یاد خواهید گرفت
- Firebase Data Connect را با شبیه سازهای محلی تنظیم کنید.
- با استفاده از Data Connect و GraphQL یک طرح داده طراحی کنید.
- پرس و جوها و جهش های مختلف را برای یک برنامه بررسی فیلم بنویسید و آزمایش کنید.
- بیاموزید که Firebase Data Connect چگونه SDK را در برنامه تولید و استفاده می کند.
- طرحواره خود را مستقر کنید و پایگاه داده را به طور موثر مدیریت کنید.
آنچه شما نیاز دارید
- Git
- کد ویژوال استودیو
- Node.js را با استفاده از nvm-windows (ویندوز) یا nvm (macOS/Linux) نصب کنید.
- اگر قبلاً این کار را نکردهاید، یک پروژه Firebase در کنسول Firebase ایجاد کنید
- (اختیاری) برای جستجوی برداری، پروژه خود را به طرح قیمت گذاری Blaze ارتقا دهید
2. محیط توسعه خود را تنظیم کنید
این مرحله از Codelab شما را از طریق راهاندازی محیطی راهنمایی میکند تا با استفاده از 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 متصل کنید. در افزونه موارد زیر را انجام دهید:
- روی دکمه ورود کلیک کنید.
- روی Connect a Firebase Project کلیک کنید و پروژه Firebase خود را انتخاب کنید.
- شبیه سازهای Firebase را با استفاده از پسوند Firebase Data Connect VS Code راه اندازی کنید:
روی Start Emulators کلیک کنید و سپس تأیید کنید که شبیه سازها در ترمینال در حال اجرا هستند.
3. پایگاه کد استارتر را مرور کنید
در این بخش، بخشهای کلیدی پایگاه کد شروع برنامه را بررسی خواهید کرد. در حالی که برنامه برخی از عملکردها را از دست داده است، درک ساختار کلی مفید است.
ساختار پوشه و فایل
بخشهای فرعی زیر نمای کلی از پوشه و ساختار فایل برنامه را ارائه میدهند.
دایرکتوری dataconnect/
شامل پیکربندیهای Firebase Data Connect، رابطها (که کوئریها و جهشها را تعریف میکنند)، و فایلهای طرحواره.
-
schema/schema.gql
: طرح واره GraphQL را تعریف می کند -
connector/queries.gql
: پرس و جوهای مورد نیاز در برنامه شما -
connector/mutations.gql
: جهش های مورد نیاز در برنامه شما -
connector/connector.yaml
: فایل پیکربندی برای تولید SDK
دایرکتوری app/src/
شامل منطق برنامه و تعامل با Firebase Data Connect است.
-
firebase.ts
: پیکربندی برای اتصال به یک برنامه Firebase در پروژه Firebase شما. -
lib/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
یک رابطه یک به یک با نوع 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
}
نکات کلیدی:
- فیلم! @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!.
- نقش: نقش بازیگر را در فیلم تعریف می کند (به عنوان مثال، "اصلی" یا "پشتیبانی").
جدول 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!
}
نکات کلیدی:
- فیلم: به نوع فیلم اشاره می کند، به طور ضمنی یک کلید خارجی
movieId: UUID!
. - user: به نوع کاربر ارجاع می دهد، به طور ضمنی یک
userId: UUID!
.
جدول Review
را تنظیم کنید
نوع Review
نشاندهنده نهاد بازبینی است و انواع User
و Movie
را در یک رابطه چند به چند به هم پیوند میدهد (یک کاربر میتواند نظرات زیادی بگذارد و هر فیلم میتواند نقدهای زیادی داشته باشد).
قطعه کد را کپی کرده و در فایل 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")
}
نکات کلیدی:
- کاربر: به کاربری ارجاع می دهد که نظر را ترک کرده است.
- فیلم: به فیلم در حال بازبینی ارجاع می دهد.
- reviewDate: به طور خودکار روی زمانی تنظیم می شود که بررسی با استفاده از
@default(expr: "request.time")
ایجاد می شود.
فیلدها و پیش فرض های تولید شده به صورت خودکار
این طرح از عباراتی مانند @default(expr: "uuidV4()")
برای تولید خودکار شناسه ها و مُهرهای زمانی منحصر به فرد استفاده می کند. به عنوان مثال، فیلد id
در انواع Movie
و Review
به طور خودکار با یک UUID پر می شود که یک رکورد جدید ایجاد شود.
اکنون که طرحواره تعریف شده است، برنامه فیلم شما یک پایه محکم برای ساختار داده و روابط خود دارد!
5. بهترین و آخرین فیلم ها را بازیابی کنید
در این بخش، داده های فیلم ساختگی را در شبیه سازهای محلی وارد می کنید، سپس کانکتورها (پرس و جوها) و کد TypeScript را برای فراخوانی این کانکتورها در برنامه وب پیاده سازی می کنید. در پایان، برنامه شما میتواند به صورت پویا فیلمهای دارای رتبه برتر و جدید را مستقیماً از پایگاه داده دریافت و نمایش دهد.
درج اطلاعات ساختگی، بازیگر و بازبینی
- در VSCode،
dataconnect/moviedata_insert.gql
باز کنید . اطمینان حاصل کنید که شبیه سازها در افزونه Firebase Data Connect در حال اجرا هستند. - شما باید یک دکمه Run (محلی) را در بالای فایل ببینید. روی این کلیک کنید تا داده های فیلم ساختگی را در پایگاه داده خود وارد کنید.
- پایانه اجرای Data Connect Execution را بررسی کنید تا تأیید کنید که داده ها با موفقیت اضافه شده اند.
کانکتور را پیاده سازی کنید
-
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 } }
- روی دکمه Run (محلی) کلیک کنید تا پرس و جو در برابر پایگاه داده محلی شما اجرا شود. همچنین می توانید قبل از اجرا، متغیرهای پرس و جو را در قسمت تنظیمات وارد کنید.
نکات کلیدی:
-
movies()
: فیلد پرس و جو GraphQL برای واکشی داده های فیلم از پایگاه داده. -
orderByRating
: پارامتری برای مرتبسازی فیلمها بر اساس رتبه (صعودی/نزولی). -
orderByReleaseYear
: پارامتری برای مرتبسازی فیلمها بر اساس سال انتشار (صعودی/نزولی). -
limit
: تعداد فیلم های برگشتی را محدود می کند.
پرس و جوها را در برنامه وب ادغام کنید
در این قسمت از نرم افزار کد، از پرس و جوهای تعریف شده در بخش قبلی در برنامه وب خود استفاده خواهید کرد. شبیهسازهای Firebase Data Connect بر اساس اطلاعات موجود در فایلهای .gql
(به طور خاص، schema.gql
، queries.gql
، mutations.gql
) و فایل connector.yaml
SDK تولید میکنند. این SDK ها را می توان مستقیماً در برنامه شما فراخوانی کرد.
- در
MovieService
(app/src/lib/MovieService.tsx
)، عبارت import را در بالا لغو نظر کنید : تابع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
: تابعی است که به طور خودکار ایجاد می شود که querylistMovies
را برای بازیابی لیستی از فیلم ها فراخوانی می کند. این شامل گزینه هایی برای مرتب سازی بر اساس رتبه بندی یا سال انتشار و محدود کردن تعداد نتایج است. -
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"}
- روی Run (محلی) برای
GetMovieById
کلیک کنید تا جزئیات مربوط به "پارادوکس کوانتومی" (فیلم ساختگی که شناسه فوق به آن مربوط می شود) بازیابی شود.
پرس و جوها را در برنامه وب ادغام کنید
- در
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 پیاده سازی خواهید کرد. همچنین از دادههای Firebase Authentication برای بازیابی یا اضافه کردن مستقیم دادههای کاربر در 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 Authentication بازیابی می شود و دسترسی ایمن به داده های خاص کاربر را تضمین می کند. - فیلدهای
_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
را برای ایجاد یا به روز رسانی اطلاعات کاربر در پایگاه داده فراخوانی می کند. -
handleGetCurrentUser
: نمایه کاربر فعلی را با استفاده از جستارgetCurrentUser
، که نظرات و فیلم های مورد علاقه کاربر را بازیابی می کند، واکشی می کند.
آن را در عمل ببینید
اکنون روی دکمه "ورود با گوگل" در نوار ناوبری کلیک کنید. می توانید با استفاده از شبیه ساز Firebase Authentication وارد شوید. پس از ورود به سیستم، روی "نمایه من" کلیک کنید. در حال حاضر خالی خواهد بود، اما شما پایه و اساس مدیریت داده های خاص کاربر را در برنامه خود تنظیم کرده اید.
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 Authentication ارائه می شود و اطمینان حاصل می کند که فقط به داده های کاربر تأیید شده دسترسی یا اصلاح می شود.
بررسی کنید که آیا یک فیلم مورد علاقه است
-
queries.gql
درdataconnect/movie-connector/
باز کنید . - برای بررسی اینکه آیا یک فیلم مورد علاقه است، عبارت زیر را اضافه کنید :
query GetIfFavoritedMovie($movieId: UUID!) @auth(level: USER) { favorite_movie(key: { userId_expr: "auth.uid", movieId: $movieId }) { movieId } }
نکات کلیدی:
-
auth.uid
: با استفاده از احراز هویت Firebase دسترسی ایمن به داده های خاص کاربر را تضمین می کند. -
favorite_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
andhandleDeleteFavoritedMovie
: از جهش ها برای افزودن یا حذف یک فیلم از موارد دلخواه کاربر به صورت ایمن استفاده کنید. -
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
operator: چندین شرط را در یک جستار واحد ترکیب میکند و به جستجو اجازه میدهد با چندین فیلد مانندreleaseYear
،rating
وgenre
فیلتر شود. -
contains
عملگر: منطبق متن جزئی را در فیلدها جستجو می کند. در این جستار، به دنبال موارد منطبق درtitle
،description
،name
، یاreviewText
میگردد. -
where
clause: شرایط فیلتر کردن داده ها را مشخص می کند. هر بخش (فیلم، بازیگران، نقدها) از یک بند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. اختیاری: استقرار در Cloud (صورتحساب مورد نیاز است)
اکنون که از طریق تکرار توسعه محلی کار کرده اید، زمان آن رسیده است که طرح، داده ها و پرس و جوهای خود را در سرور مستقر کنید. این را می توان با استفاده از پسوند Firebase Data Connect VS Code یا Firebase CLI انجام داد.
طرح قیمت گذاری Firebase خود را ارتقا دهید
برای ادغام Firebase Data Connect با Cloud SQL برای PostgreSQL، پروژه Firebase شما باید در طرح قیمتگذاری (Blaze) باشد، به این معنی که به یک حساب Cloud Billing مرتبط است.
- حساب Cloud Billing به یک روش پرداخت مانند کارت اعتباری نیاز دارد.
- اگر تازه وارد Firebase و Google Cloud هستید، بررسی کنید که آیا واجد شرایط دریافت اعتبار 300 دلاری و یک حساب آزمایشی رایگان Cloud Billing هستید یا خیر.
- اگر این نرمافزار کد را بهعنوان بخشی از یک رویداد انجام میدهید، از سازماندهنده خود بپرسید که آیا اعتبارات Cloud موجود است یا خیر.
برای ارتقای پروژه خود به پلن Blaze، مراحل زیر را دنبال کنید:
- در کنسول Firebase، برنامه خود را ارتقا دهید.
- طرح Blaze را انتخاب کنید. دستورالعمل های روی صفحه را دنبال کنید تا یک حساب Cloud Billing را به پروژه خود پیوند دهید.
اگر به عنوان بخشی از این ارتقاء نیاز به ایجاد یک حساب Cloud Billing داشتید، ممکن است لازم باشد برای تکمیل ارتقاء به جریان ارتقاء در کنسول Firebase برگردید.
برنامه وب خود را به پروژه Firebase خود وصل کنید
- برنامه وب خود را با استفاده از کنسول Firebase در پروژه Firebase خود ثبت کنید:
- پروژه خود را باز کنید و سپس روی افزودن برنامه کلیک کنید.
- فعلاً تنظیمات و پیکربندی SDK را نادیده بگیرید، اما مطمئن شوید که شی
firebaseConfig
ایجاد شده را کپی کنید .
-
firebaseConfig
موجود درapp/src/lib/firebase.tsx
را با پیکربندی که به تازگی از کنسول Firebase کپی کرده اید، جایگزین کنید .const 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 خود تنظیم کنید
- با Google Sign-In، احراز هویت Firebase را تنظیم کنید.
- (اختیاری) به دامنه ها برای احراز هویت Firebase با استفاده از کنسول Firebase (به عنوان مثال،
http://127.0.0.1
) اجازه دهید.- در تنظیمات احراز هویت ، به دامنه های مجاز بروید.
- روی «افزودن دامنه» کلیک کنید و دامنه محلی خود را در لیست قرار دهید.
با Firebase CLI مستقر شود
- در
dataconnect/dataconnect.yaml
، مطمئن شوید که ID نمونه، پایگاه داده و شناسه سرویس شما با پروژه شما مطابقت دارند: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 شما برای نمونه PostgreSQL با طرح و داده های مستقر نهایی به روز می شود. می توانید وضعیت را در کنسول Firebase نظارت کنید.
اکنون باید بتوانید برنامه خود را به صورت زنده در your-project.web.app/
ببینید. علاوه بر این، میتوانید روی Run (Production) در پنل 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
و vector با کلیک بر روی "Deploy to Production" با استفاده از برنامه افزودنی Firebase Data Connect VS Code اجرا کنید.
پایگاه داده را با جاسازی ها پر کنید
- پوشه
dataconnect
را در VS Code باز کنید . - روی Run(local) در
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 اضافه کنید.