ساخت با Firebase Data Connect

1. قبل از شروع

برنامه FriendlyMovies

در این کد لبه، شما 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 را در برنامه تولید و استفاده می کند.
  • طرحواره خود را مستقر کنید و پایگاه داده را به طور موثر مدیریت کنید.

آنچه شما نیاز دارید

تنظیم محیط توسعه شما

این بخش شما را در راه‌اندازی محیطی راهنمایی می‌کند تا با استفاده از Firebase Data Connect، برنامه بررسی فیلم خود را بسازید.

مرحله 1: مخزن پروژه را شبیه سازی کنید

با شبیه سازی مخزن پروژه و نصب وابستگی های مورد نیاز شروع کنید:

git clone https://github.com/firebaseextended/codelab-dataconnect-web
cd codelab-dataconnect-web
cd ./app && npm i
npm run dev
  1. پس از اجرای این دستورات، http://localhost:5173 را در مرورگر خود باز کنید تا برنامه وب را در حال اجرا به صورت محلی ببینید. این به عنوان قسمت جلویی شما برای ساختن برنامه بررسی فیلم و تعامل با ویژگی های آن عمل می کند.

93f6648a2532c606.png

مرحله 2: پروژه را در Visual Studio Code باز کنید

پوشه codelab-dataconnect-web کلون شده را با استفاده از Visual Studio Code باز کنید . اینجا جایی است که شما طرح خود را تعریف می‌کنید، پرس و جو می‌نویسید و عملکرد برنامه را آزمایش می‌کنید.

مرحله 3: افزونه Firebase Data Connect Visual Studio را نصب کنید

برای استفاده از ویژگی‌های Data Connect، افزونه Firebase Data Connect Visual Studio را نصب کنید. یا: آن را از Visual Studio Code Marketplace نصب کنید یا آن را در VS Code جستجو کنید.

  1. یا: آن را از Visual Studio Code Marketplace نصب کنید یا آن را در VS Code جستجو کنید.

b03ee38c9a81b648.png

مرحله 4: یک پروژه Firebase ایجاد کنید

اگر قبلاً ندارید، به کنسول Firebase بروید تا یک پروژه Firebase جدید ایجاد کنید. سپس در افزونه Firebase Data Connect VSCode:

  • روی دکمه ورود کلیک کنید.
  • روی Connect a Firebase Project کلیک کنید و پروژه ای را که در Firebase Console ایجاد کرده اید انتخاب کنید.

4bb2fbf8f9fac29b.png

مرحله 5: شبیه سازهای Firebase را راه اندازی کنید

در افزونه Firebase Data Connect VSCode، روی Start Emulators کلیک کنید و تأیید کنید که شبیه سازها در ترمینال در حال اجرا هستند.

6d3d95f4cb708db1.png

2. پایگاه کد استارتر را مرور کنید

در این بخش، بخش‌های کلیدی پایگاه کد شروع برنامه را بررسی خواهید کرد. در حالی که برنامه برخی از عملکردها را از دست داده است، درک ساختار کلی مفید است.

ساختار پوشه و فایل

در اینجا یک نمای کلی از پوشه و ساختار فایل برنامه آورده شده است:

داده اتصال/

شامل پیکربندی‌های 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 در کنسول.
  • lib/dataconnect-sdk/ : این پوشه حاوی SDK تولید شده است. می‌توانید مکان تولید SDK را در فایل connector/connector.yaml ویرایش کنید و هر زمان که درخواست یا جهش را تعریف کنید، SDK‌ها به‌طور خودکار تولید می‌شوند.

3. تعریف یک طرحواره برای بررسی فیلم

در این بخش، ساختار و روابط بین موجودیت های کلیدی در برنامه فیلم را در یک طرحواره تعریف می کنید. موجودیت هایی مانند Movie , User , Actor و Review به جداول پایگاه داده نگاشت می شوند و روابطی با استفاده از Firebase Data Connect و دستورالعمل های طرحواره GraphQL ایجاد می شوند. پس از نصب، برنامه شما برای انجام همه چیز از جستجوی فیلم‌های دارای رتبه برتر و فیلتر کردن بر اساس ژانر گرفته تا اجازه دادن به کاربران برای گذاشتن نظرات، علامت‌گذاری موارد دلخواه، کاوش فیلم‌های مشابه یا یافتن فیلم‌های توصیه‌شده بر اساس ورودی متن از طریق جستجوی برداری، آماده خواهد بود.

نهادهای اصلی و روابط

نوع Movie حاوی جزئیات کلیدی مانند عنوان، ژانر و برچسب‌ها است که برنامه از آنها برای جستجوها و نمایه‌های فیلم استفاده می‌کند. نوع User تعاملات کاربر مانند نظرات و موارد دلخواه را ردیابی می کند. Reviews کاربران را به فیلم‌ها متصل می‌کند و به برنامه اجازه می‌دهد رتبه‌بندی‌ها و بازخوردهای تولیدشده توسط کاربر را نشان دهد.

روابط بین فیلم ها، بازیگران و کاربران، برنامه را پویاتر می کند. جدول پیوستن MovieActor به نمایش جزئیات بازیگران و فیلم‌شناسی بازیگران کمک می‌کند. نوع FavoriteMovie به کاربران امکان می دهد فیلم های مورد علاقه خود را داشته باشند، بنابراین برنامه می تواند لیست علاقه مندی های شخصی شده را نشان دهد و انتخاب های محبوب را برجسته کند.

جدول فیلم

نوع فیلم ساختار اصلی یک موجودیت فیلم را شامل فیلدهایی مانند عنوان، ژانر، سال انتشار و رتبه بندی تعریف می کند.

قطعه کد را کپی کرده و در فایل 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 یک رابطه یک به یک با نوع 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 اشاره می‌کند و یک رابطه کلید خارجی ایجاد می‌کند.

میز بازیگر

قطعه کد را کپی کرده و در فایل dataconnect/schema/schema.gql خود جایگذاری کنید:

type Actor @table {
  id: UUID!
  imageUrl: String! 
  name: String! @col(name: "name", dataType: "varchar(30)")
}

نوع Actor نشان دهنده یک بازیگر در پایگاه داده فیلم است، جایی که هر بازیگر می تواند بخشی از چندین فیلم باشد و یک رابطه چند به چند را تشکیل دهد.

میز فیلم بازیگر

قطعه کد را کپی کرده و در فایل 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 یک موجودیت کاربری را تعریف می کند که با گذاشتن نظرات یا فیلم های مورد علاقه با فیلم ها تعامل دارد.

قطعه کد را کپی کرده و در فایل 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 یک جدول پیوستن است که روابط چند به چند بین کاربران و فیلم های مورد علاقه آنها را مدیریت می کند. هر جدول یک 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 نشان‌دهنده نهاد بازبینی است و انواع کاربر و فیلم را در یک رابطه چند به چند به هم پیوند می‌دهد (یک کاربر می‌تواند نظرات زیادی بگذارد و هر فیلم می‌تواند نقدهای زیادی داشته باشد).

قطعه کد را کپی کرده و در فایل 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 پر می شود که یک رکورد جدید ایجاد شود.

اکنون که طرحواره تعریف شده است، برنامه فیلم شما یک پایه محکم برای ساختار داده و روابط خود دارد!

4. بازیابی فیلم های برتر و جدید

برنامه FriendlyMovies

در این بخش، داده های فیلم ساختگی را در شبیه سازهای محلی وارد می کنید، سپس کانکتورها (پرس و جوها) و کد TypeScript را برای فراخوانی این کانکتورها در برنامه وب پیاده سازی می کنید. در پایان، برنامه شما می‌تواند به صورت پویا فیلم‌های دارای رتبه برتر و جدید را مستقیماً از پایگاه داده دریافت و نمایش دهد.

درج داده های فیلم ساختگی، بازیگر و بررسی

  1. در VSCode، dataconnect/moviedata_insert.gql باز کنید . اطمینان حاصل کنید که شبیه سازها در افزونه Firebase Data Connect در حال اجرا هستند.
  2. شما باید یک دکمه Run (محلی) را در بالای فایل ببینید. روی این کلیک کنید تا داده های فیلم ساختگی را در پایگاه داده خود وارد کنید.

e424f75e63bf2e10.png

  1. پایانه اجرای Data Connect Execution را بررسی کنید تا تأیید کنید که داده ها با موفقیت اضافه شده اند.

e0943d7704fb84ea.png

پیاده سازی کانکتور

  1. dataconnect/movie-connector/queries.gql را باز کنید. یک پرس و جو اصلی ListMovies در نظرات پیدا خواهید کرد:
query ListMovies @auth(level: PUBLIC) {
  movies {
    id
    title
    imageUrl
    releaseYear
    genre
    rating
    tags
    description
  }
}

این درخواست همه فیلم‌ها و جزئیات آن‌ها (به عنوان مثال، شناسه، عنوان، سال انتشار) را واکشی می‌کند. با این حال، فیلم ها را مرتب نمی کند .

  1. برای افزودن گزینه‌های مرتب‌سازی و محدود کردن کوئری 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 (محلی) کلیک کنید تا پرس و جو در برابر پایگاه داده محلی شما اجرا شود. همچنین می توانید قبل از اجرا، متغیرهای پرس و جو را در قسمت تنظیمات وارد کنید.

c4d947115bb11b16.png

نکات کلیدی:

  • movies(): فیلد پرس و جو GraphQL برای واکشی داده های فیلم از پایگاه داده.
  • orderByRating: پارامتری برای مرتب‌سازی فیلم‌ها بر اساس رتبه (صعودی/نزولی).
  • orderByReleaseYear: پارامتری برای مرتب‌سازی فیلم‌ها بر اساس سال انتشار (صعودی/نزولی).
  • محدودیت: تعداد فیلم های برگشتی را محدود می کند.

یکپارچه سازی کوئری ها در برنامه وب

در این قسمت از کوئری های تعریف شده در قسمت قبل در برنامه وب خود استفاده می کنید. شبیه سازهای Firebase Data Connect بر اساس اطلاعات موجود در فایل های .gql (schema.gql، queries.gql، mutations.gql) و connector.yaml، SDK تولید می کنند. این SDK ها را می توان مستقیماً در برنامه شما فراخوانی کرد.

  1. در MovieService ( app/src/lib/MovieService.tsx )، عبارت import را در بالا لغو نظر کنید :
import { listMovies, ListMoviesData, OrderDirection } from "@movie/dataconnect";

تابع listMovies ، نوع پاسخ ListMoviesData و enum OrderDirection همگی SDKهایی هستند که توسط شبیه سازهای Firebase Data Connect بر اساس طرح و پرس و جوهایی که قبلاً تعریف کرده اید تولید می شوند.

  1. توابع 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: تابعی است که به صورت خودکار ایجاد می شود که query listMovies را برای بازیابی لیستی از فیلم ها فراخوانی می کند. این شامل گزینه هایی برای مرتب سازی بر اساس رتبه بندی یا سال انتشار و محدود کردن تعداد نتایج است.
  • ListMoviesData: نوع نتیجه مورد استفاده برای نمایش 10 فیلم برتر و آخرین فیلم در صفحه اصلی.

آن را در عمل ببینید

برنامه وب خود را دوباره بارگیری کنید تا پرس و جو را در عمل ببینید. صفحه اصلی اکنون به صورت پویا لیست فیلم ها را نمایش می دهد و داده ها را مستقیماً از پایگاه داده محلی شما واکشی می کند. می‌بینید که بهترین و جدیدترین فیلم‌ها به‌صورت یکپارچه ظاهر می‌شوند و داده‌هایی را که به‌تازگی تنظیم کرده‌اید منعکس می‌کنند.

5. نمایش جزئیات فیلم و بازیگر

در این بخش، شما قابلیت بازیابی اطلاعات دقیق یک فیلم یا یک بازیگر را با استفاده از شناسه‌های منحصر به فرد آن‌ها پیاده‌سازی می‌کنید. این نه تنها شامل واکشی داده‌ها از جداول مربوطه می‌شود، بلکه شامل پیوستن به جداول مرتبط برای نمایش جزئیات جامع، مانند نقد فیلم و فیلم‌برداری بازیگران می‌شود.

ac7fefa7ff779231.png

پیاده سازی اتصال دهنده ها

  1. dataconnect/movie-connector/queries.gql را در پروژه خود باز کنید .
  2. برای بازیابی جزئیات فیلم و بازیگر، جستارهای زیر را اضافه کنید :
# 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
    }
  }
}
  1. تغییرات خود را ذخیره کنید و پرس و جوها را بررسی کنید.

نکات کلیدی:

  • 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 کلیک کنید تا جزئیات مربوط به "پارادوکس کوانتومی" (فیلم ساختگی که شناسه فوق به آن مربوط می شود) بازیابی شود.

1b08961891e44da2.png

یکپارچه سازی کوئری ها در برنامه وب

  1. در MovieService ( app/src/lib/MovieService.tsx )، واردات زیر را لغو نظر کنید :
import { getMovieById, GetMovieByIdData } from "@movie/dataconnect";
import { GetActorByIdData, getActorById } from "@movie/dataconnect";
  1. توابع 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 : اینها انواع نتایج هستند که برای نمایش جزئیات فیلم و بازیگر در برنامه استفاده می شوند.

آن را در عمل ببینید

اکنون به صفحه اصلی برنامه وب خود بروید. روی یک فیلم کلیک کنید و می‌توانید تمام جزئیات آن، از جمله بازیگران و نظرات را مشاهده کنید - اطلاعاتی که از جداول مرتبط استخراج شده‌اند. به همین ترتیب، با کلیک بر روی یک بازیگر، فیلم‌هایی که او بخشی از آن بودند نمایش داده می‌شود.

6. مدیریت احراز هویت کاربر

در این بخش، قابلیت ورود و خروج کاربر را با استفاده از احراز هویت Firebase پیاده سازی خواهید کرد. همچنین از داده‌های Firebase Authentication برای بازیابی یا اضافه کردن مستقیم داده‌های کاربر در Firebase DataConnect استفاده می‌کنید و از مدیریت امن کاربر در برنامه خود اطمینان می‌یابید.

9890838045d5a00e.png

پیاده سازی اتصال دهنده ها

  1. mutations.gql در dataconnect/movie-connector/ باز کنید .
  2. جهش زیر را برای ایجاد یا به روز رسانی کاربر تأیید شده فعلی اضافه کنید:
# 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 : همه نظرات مربوط به کاربر، از جمله شناسه و عنوان فیلم را واکشی می کند.
  • favorite_movies_on_user : همه فیلم‌هایی که توسط کاربر به‌عنوان موارد دلخواه علامت‌گذاری شده‌اند، از جمله اطلاعات دقیق مانند ژانر، سال انتشار، رتبه‌بندی و ابرداده را بازیابی می‌کند.

یکپارچه سازی کوئری ها در برنامه وب

  1. در MovieService ( app/src/lib/MovieService.tsx )، واردات زیر را لغو نظر کنید:
import { upsertUser } from "@movie/dataconnect";
import { getCurrentUser, GetCurrentUserData } from "@movie/dataconnect";
  1. توابع 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 Auth وارد شوید. پس از ورود به سیستم، روی "نمایه من" کلیک کنید. در حال حاضر خالی خواهد بود، اما شما پایه و اساس مدیریت داده های خاص کاربر را در برنامه خود تنظیم کرده اید.

7. پیاده سازی تعاملات کاربر

در این بخش، تعاملات کاربران را در برنامه نقد و بررسی فیلم پیاده‌سازی می‌کنید و به کاربران این امکان را می‌دهید که فیلم‌های مورد علاقه خود را مدیریت کنند و نظرات را ترک یا حذف کنند.

b3d0ac1e181c9de9.png

پیاده سازی اتصال دهنده ها

  1. mutations.gql در dataconnect/movie-connector/ باز کنید .
  2. جهش های زیر را برای مدیریت فیلم های مورد علاقه اضافه کنید :
# 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 ارائه می شود و اطمینان حاصل می کند که فقط به داده های کاربر تأیید شده دسترسی یا اصلاح می شود.
  1. سپس queries.gql در dataconnect/movie-connector/ باز کنید .
  2. برای بررسی اینکه آیا یک فیلم مورد علاقه است، عبارت زیر را اضافه کنید :
query GetIfFavoritedMovie($movieId: UUID!) @auth(level: USER) {
  favorite_movie(key: { userId_expr: "auth.uid", movieId: $movieId }) {
    movieId
  }
}

نکات کلیدی:

  • auth.uid : با استفاده از احراز هویت Firebase دسترسی ایمن به داده های خاص کاربر را تضمین می کند.
  • favorite_movie : جدول پیوستن favorite_movies را بررسی می کند تا ببیند آیا یک فیلم خاص به عنوان مورد علاقه توسط کاربر فعلی علامت گذاری شده است یا خیر.

یکپارچه سازی کوئری ها در برنامه وب

  1. در MovieService ( app/src/lib/MovieService.tsx )، واردات زیر را لغو نظر کنید :
import { addFavoritedMovie, deleteFavoritedMovie, getIfFavoritedMovie } from "@movie/dataconnect";
  1. توابع 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 and handleDeleteFavoritedMovie : از جهش ها برای افزودن یا حذف یک فیلم از موارد دلخواه کاربر به صورت ایمن استفاده کنید.
  • handleGetIfFavoritedMovie : از عبارت getIfFavoritedMovie برای بررسی اینکه آیا یک فیلم به عنوان فیلم مورد علاقه توسط کاربر علامت گذاری شده است، استفاده می کند.

آن را در عمل ببینید

اکنون، می‌توانید با کلیک کردن روی نماد قلب روی کارت‌های فیلم و صفحه جزئیات فیلم، فیلم‌های مورد علاقه یا غیرمورد علاقه را انتخاب کنید. علاوه بر این، می توانید فیلم های مورد علاقه خود را در صفحه نمایه خود مشاهده کنید.

پیاده سازی نظرات کاربران

در مرحله بعد، بخش مدیریت نظرات کاربران را در برنامه پیاده سازی خواهید کرد.

پیاده سازی اتصال دهنده ها

  1. در 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 ایجاد می کند و نیازی به ورودی دستی را از بین می برد.

یکپارچه سازی کوئری ها در برنامه وب

  1. در MovieService ( app/src/lib/MovieService.tsx )، واردات زیر را لغو نظر کنید :
import { addReview, deleteReview } from "@movie/dataconnect";
  1. توابع 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 برای حذف نظر یک فیلم توسط کاربر تأیید شده استفاده می کند.

آن را در عمل ببینید

اکنون کاربران می توانند در صفحه جزئیات فیلم، نظرات خود را برای فیلم ها ارسال کنند. آنها همچنین می توانند نظرات خود را در صفحه نمایه خود مشاهده و حذف کنند و به آنها کنترل کامل بر تعاملات خود با برنامه می دهد.

8. فیلترهای پیشرفته و تطبیق متن جزئی

در این بخش، قابلیت‌های جستجوی پیشرفته را پیاده‌سازی می‌کنید که به کاربران امکان می‌دهد فیلم‌ها را بر اساس طیف وسیعی از رتبه‌بندی‌ها و سال‌های انتشار جستجو کنند، بر اساس ژانرها و برچسب‌ها فیلتر کنند، تطبیق متنی جزئی در عنوان یا توضیحات انجام دهند، و حتی چندین فیلتر را برای دقیق‌تر ترکیب کنند. نتایج

ece70ee0ab964e28.png

پیاده سازی اتصال دهنده ها

  1. queries.gql در dataconnect/movie-connector/ باز کنید.
  2. برای پشتیبانی از قابلیت‌های جستجوی مختلف، عبارت زیر را اضافه کنید :
# 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 برای تعریف معیارهای خاص برای جستجو استفاده می کند.

یکپارچه سازی کوئری ها در برنامه وب

  1. در MovieService ( app/src/lib/MovieService.tsx )، واردات زیر را لغو نظر کنید :
import { searchAll, SearchAllData } from "@movie/dataconnect";
  1. تابع 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 برای انجام جستجوی بر اساس ورودی کاربر، فیلتر کردن نتایج بر اساس پارامترهایی مانند سال، رتبه، ژانر و تطابق متن جزئی استفاده می کند.

آن را در عمل ببینید

از نوار ناوبری در برنامه وب به صفحه «جستجوی پیشرفته» بروید. اکنون می توانید فیلم ها، بازیگران و نظرات را با استفاده از فیلترها و ورودی های مختلف جستجو کنید و نتایج جستجوی دقیق و متناسب را دریافت کنید.

9. اختیاری: استقرار در Cloud (صورت‌حساب مورد نیاز است)

اکنون که از طریق تکرار توسعه محلی کار کرده اید، زمان آن رسیده است که طرح، داده ها و پرس و جوهای خود را در سرور مستقر کنید. این را می توان با استفاده از پسوند Firebase Data Connect VS Code یا Firebase CLI انجام داد.

افزودن یک برنامه وب در کنسول Firebase

  1. یک برنامه وب در کنسول Firebase ایجاد کنید و شناسه برنامه خود را یادداشت کنید

7030822793e4d75b.png

  1. با کلیک بر روی "افزودن برنامه" یک برنامه وب را در کنسول Firebase تنظیم کنید. در حال حاضر می‌توانید با خیال راحت تنظیمات و پیکربندی SDK را نادیده بگیرید، اما به شی firebaseConfig ایجاد شده توجه داشته باشید.
  2. firebaseConfig را در app/src/lib/firebase.tsx جایگزین کنید :
const firebaseConfig = {
  apiKey: "API_KEY",
  authDomain: "PROJECT_ID.firebaseapp.com",
  projectId: "PROJECT_ID",
  storageBucket: "PROJECT_ID.appspot.com",
  messagingSenderId: "SENDER_ID",
  appId: "APP_ID"
};
  1. ساخت برنامه وب: در پوشه app ، از Vite برای ساخت برنامه وب برای استقرار میزبانی استفاده کنید:
cd app
npm run build

احراز هویت Firebase را در کنسول تنظیم کنید

  1. Firebase Auth را با ورود به سیستم Google تنظیم کنید

62af2f225e790ef6.png

  1. (اختیاری) اجازه دادن به دامنه ها برای (Firebase Auth) [https://firebase.google.com/docs/auth/web/hosting] در کنسول پروژه شما (به عنوان مثال، http://127.0.0.1 ):
  • در تنظیمات Auth، پروژه خود را انتخاب کنید و به (Authorized Domains) [https://firebase.google.com/docs/auth/web/hosting] بروید. روی «افزودن دامنه» کلیک کنید و دامنه محلی خود را در لیست قرار دهید.

c255098f12549886.png

استقرار با Firebase CLI

  1. در 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"]
  1. مطمئن شوید که Firebase CLI را با پروژه خود تنظیم کرده اید
npm i -g firebase-tools
firebase login --reauth
firebase use --add
  1. در ترمینال خود، دستور زیر را برای استقرار اجرا کنید:
firebase deploy --only dataconnect,hosting
  1. این دستور را برای مقایسه تغییرات طرحواره خود اجرا کنید:
firebase dataconnect:sql:diff
  1. اگر تغییرات قابل قبول هستند، آنها را با موارد زیر اعمال کنید:
firebase dataconnect:sql:migrate

Cloud SQL شما برای نمونه PostgreSQL با طرح و داده های مستقر نهایی به روز می شود. می توانید وضعیت را در کنسول Firebase نظارت کنید.

اکنون باید بتوانید برنامه خود را به صورت زنده در your-project.web.app/ ببینید. علاوه بر این، می‌توانید روی Run (Production) در پنل Firebase Data Connect کلیک کنید، همانطور که با شبیه‌سازهای محلی انجام دادید، تا داده‌ها را به محیط تولید اضافه کنید.

10. اختیاری: جستجوی برداری با Firebase Data Connect

در این بخش، جستجوی برداری را در برنامه بررسی فیلم خود با استفاده از Firebase Data Connect فعال می‌کنید. این ویژگی امکان جستجوهای مبتنی بر محتوا را فراهم می کند، مانند یافتن فیلم هایی با توضیحات مشابه با استفاده از جاسازی های برداری.

4b5aca5a447d2feb.png

طرحواره را برای گنجاندن جاسازی‌های یک فیلد به‌روزرسانی کنید

  1. در 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

  1. راهنمای پیش نیازها را برای راه اندازی Vertex AI API با Google Cloud دنبال کنید. این مرحله برای پشتیبانی از تولید جاسازی و قابلیت جستجوی برداری ضروری است.
  2. با کلیک بر روی Deploy to Production با استفاده از افزونه Firebase Data Connect VSCode، طرح خود را مجدداً مستقر کنید تا جستجوی pgvector و vector را فعال کنید.

پر کردن پایگاه داده با جاسازی ها

  1. پوشه dataconnect را در VSCode باز کنید و روی Run(local) در optional_vector_embed.gql کلیک کنید تا پایگاه داده شما با جاسازی های فیلم ها پر شود.

b858da780f6ec103.png

یک عبارت جستجوی برداری اضافه کنید

  1. در 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 محدود می کند.

تابع جستجوی برداری را در برنامه اجرا کنید

  1. در app/src/lib/MovieService.ts ، واردات زیر را لغو نظر کنید:

تابع جستجوی برداری را در برنامه اجرا کنید

اکنون که طرح و پرس و جو تنظیم شده اند، جستجوی برداری را در لایه سرویس برنامه خود ادغام کنید. این مرحله به شما امکان می‌دهد تا درخواست جستجو را از برنامه وب خود فراخوانی کنید.

در 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 را فراخوانی می‌کند و متن ورودی را برای انجام جستجوی محتوای مبتنی بر برداری ارسال می‌کند.

آن را در عمل ببینید

به بخش «جستجوی برداری» در نوار ناوبری بروید و عباراتی مانند «عاشقانه و مدرن» را تایپ کنید. فهرستی از فیلم‌ها را می‌بینید که با محتوایی که جستجو می‌کنید مطابقت دارند، یا به صفحه جزئیات فیلم هر فیلمی بروید و بخش فیلم‌های مشابه را در پایین صفحه بررسی کنید.

7b71f1c75633c1be.png

11. نتیجه گیری

تبریک می گویم، شما باید بتوانید از برنامه وب استفاده کنید! اگر می‌خواهید با داده‌های فیلم خود بازی کنید، نگران نباشید، داده‌های خود را با استفاده از پسوند FDC با تقلید از فایل‌های _insert.gql وارد کنید، یا آنها را از طریق صفحه اجرای Data Connect اضافه کنید.

بیشتر بدانید

،

1. قبل از شروع

برنامه FriendlyMovies

در این کد لبه، شما 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 را در برنامه تولید و استفاده می کند.
  • طرحواره خود را مستقر کنید و پایگاه داده را به طور موثر مدیریت کنید.

آنچه شما نیاز دارید

تنظیم محیط توسعه شما

این بخش شما را در راه‌اندازی محیطی راهنمایی می‌کند تا با استفاده از Firebase Data Connect، برنامه بررسی فیلم خود را بسازید.

مرحله 1: مخزن پروژه را شبیه سازی کنید

با شبیه سازی مخزن پروژه و نصب وابستگی های مورد نیاز شروع کنید:

git clone https://github.com/firebaseextended/codelab-dataconnect-web
cd codelab-dataconnect-web
cd ./app && npm i
npm run dev
  1. پس از اجرای این دستورات، http://localhost:5173 را در مرورگر خود باز کنید تا برنامه وب را در حال اجرا به صورت محلی ببینید. این به عنوان قسمت جلویی شما برای ساختن برنامه بررسی فیلم و تعامل با ویژگی های آن عمل می کند.

93f6648a2532c606.png

مرحله 2: پروژه را در Visual Studio Code باز کنید

پوشه codelab-dataconnect-web کلون شده را با استفاده از Visual Studio Code باز کنید . اینجا جایی است که شما طرح خود را تعریف می‌کنید، پرس و جو می‌نویسید و عملکرد برنامه را آزمایش می‌کنید.

مرحله 3: افزونه Firebase Data Connect Visual Studio را نصب کنید

برای استفاده از ویژگی‌های Data Connect، افزونه Firebase Data Connect Visual Studio را نصب کنید. یا: آن را از Visual Studio Code Marketplace نصب کنید یا آن را در VS Code جستجو کنید.

  1. یا: آن را از Visual Studio Code Marketplace نصب کنید یا آن را در VS Code جستجو کنید.

b03ee38c9a81b648.png

مرحله 4: یک پروژه Firebase ایجاد کنید

اگر قبلاً ندارید، به کنسول Firebase بروید تا یک پروژه Firebase جدید ایجاد کنید. سپس در افزونه Firebase Data Connect VSCode:

  • روی دکمه ورود کلیک کنید.
  • روی Connect a Firebase Project کلیک کنید و پروژه ای را که در Firebase Console ایجاد کرده اید انتخاب کنید.

4bb2fbf8f9fac29b.png

مرحله 5: شبیه سازهای Firebase را راه اندازی کنید

در افزونه Firebase Data Connect VSCode، روی Start Emulators کلیک کنید و تأیید کنید که شبیه سازها در ترمینال در حال اجرا هستند.

6d3d95f4cb708db1.png

2. پایگاه کد استارتر را مرور کنید

در این بخش، بخش‌های کلیدی پایگاه کد شروع برنامه را بررسی خواهید کرد. در حالی که برنامه برخی از عملکردها را از دست داده است، درک ساختار کلی مفید است.

ساختار پوشه و فایل

در اینجا یک نمای کلی از پوشه و ساختار فایل برنامه آورده شده است:

داده اتصال/

شامل پیکربندی‌های 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 در کنسول.
  • lib/dataconnect-sdk/ : این پوشه حاوی SDK تولید شده است. می‌توانید مکان تولید SDK را در فایل connector/connector.yaml ویرایش کنید و هر زمان که درخواست یا جهش را تعریف کنید، SDK‌ها به‌طور خودکار تولید می‌شوند.

3. تعریف یک طرحواره برای بررسی فیلم

در این بخش، ساختار و روابط بین موجودیت های کلیدی در برنامه فیلم را در یک طرحواره تعریف می کنید. موجودیت هایی مانند Movie , User , Actor و Review به جداول پایگاه داده نگاشت می شوند و روابطی با استفاده از Firebase Data Connect و دستورالعمل های طرحواره GraphQL ایجاد می شوند. پس از نصب، برنامه شما برای انجام همه چیز از جستجوی فیلم‌های دارای رتبه برتر و فیلتر کردن بر اساس ژانر گرفته تا اجازه دادن به کاربران برای گذاشتن نظرات، علامت‌گذاری موارد دلخواه، کاوش فیلم‌های مشابه یا یافتن فیلم‌های توصیه‌شده بر اساس ورودی متن از طریق جستجوی برداری، آماده خواهد بود.

نهادهای اصلی و روابط

نوع Movie حاوی جزئیات کلیدی مانند عنوان، ژانر و برچسب‌ها است که برنامه از آنها برای جستجوها و نمایه‌های فیلم استفاده می‌کند. نوع User تعاملات کاربر مانند نظرات و موارد دلخواه را ردیابی می کند. Reviews کاربران را به فیلم‌ها متصل می‌کند و به برنامه اجازه می‌دهد رتبه‌بندی‌ها و بازخوردهای تولیدشده توسط کاربر را نشان دهد.

روابط بین فیلم ها، بازیگران و کاربران، برنامه را پویاتر می کند. جدول پیوستن MovieActor به نمایش جزئیات بازیگران و فیلم‌شناسی بازیگران کمک می‌کند. نوع FavoriteMovie به کاربران امکان می دهد فیلم های مورد علاقه خود را داشته باشند، بنابراین برنامه می تواند لیست علاقه مندی های شخصی شده را نشان دهد و انتخاب های محبوب را برجسته کند.

جدول فیلم

نوع فیلم ساختار اصلی یک موجودیت فیلم را شامل فیلدهایی مانند عنوان، ژانر، سال انتشار و رتبه بندی تعریف می کند.

قطعه کد را در پرونده 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]
}

نکات کلیدی:

  • شناسه: یک UUID منحصر به فرد برای هر فیلم ، با استفاده از @default(expr: "uuidV4()") تولید می شود.

میز Moviemetadata

نوع Moviemetadata رابطه یک به یک با نوع فیلم برقرار می کند. این شامل داده های اضافی مانند کارگردان فیلم است.

قطعه کد را در پرونده 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 مراجعه می کند و یک رابطه کلیدی خارجی ایجاد می کند.

میز بازیگر

قطعه کد را در پرونده dataconnect/schema/schema.gql خود کپی و چسبانده و چسبانده کنید :

type Actor @table {
  id: UUID!
  imageUrl: String! 
  name: String! @col(name: "name", dataType: "varchar(30)")
}

نوع Actor نماینده یک بازیگر در پایگاه داده فیلم است ، جایی که هر بازیگر می تواند بخشی از فیلم های مختلف باشد و رابطه ای با بسیاری از افراد را تشکیل می دهد.

میز حرکت

قطعه کد را در پرونده 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"
}

نکات کلیدی:

  • فیلم: به نوع فیلم مراجعه می کند ، به طور ضمنی یک فیلم اصلی اصلی را ایجاد می کند: UUID!.
  • بازیگر: به نوع بازیگر مراجعه می کند ، به طور ضمنی یک بازیگر کلیدی خارجی ایجاد می کند: UUID!.
  • نقش: نقش بازیگر را در فیلم تعریف می کند (به عنوان مثال ، "اصلی" یا "پشتیبانی").

جدول کاربر

نوع 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 یک جدول پیوست است که روابط بسیاری از افراد بین کاربران و فیلم های مورد علاقه آنها را به همراه دارد. هر جدول 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!
}

نکات کلیدی:

  • فیلم: به نوع فیلم مراجعه می کند ، به طور ضمنی یک فیلم اصلی اصلی را ایجاد می کند: UUID!.
  • کاربر: به نوع کاربر مراجعه می کند ، به طور ضمنی یک کاربر کلید خارجی را ایجاد می کند: UUID!.

جدول بررسی

نوع بررسی نمایانگر موجودیت بررسی است و انواع کاربر و فیلم را در یک رابطه بسیار به بسیاری از افراد پیوند می دهد (یک کاربر می تواند بررسی های زیادی را انجام دهد ، و هر فیلم می تواند بررسی های زیادی داشته باشد).

قطعه کد را در پرونده 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()") استفاده می کند تا به طور خودکار شناسه ها و زمان های منحصر به فرد را تولید کند. به عنوان مثال ، هنگام ایجاد یک رکورد جدید ، زمینه شناسه در فیلم و انواع بررسی به طور خودکار با UUID جمع می شود.

اکنون که این طرح مشخص شده است ، برنامه فیلم شما پایه و اساس محکمی برای ساختار داده و روابط خود دارد!

4. بازیابی فیلم های برتر و جدید

برنامه دوستانه

در این بخش ، داده های فیلم Mock را در شبیه سازهای محلی قرار می دهید ، سپس اتصالات (نمایش داده ها) و کد Typescript را پیاده سازی می کنید تا این اتصالات را در برنامه وب فراخوانی کنید. در پایان ، برنامه شما قادر خواهد بود به صورت پویا به طور پویا و جدیدترین فیلم ها را مستقیماً از پایگاه داده به نمایش بگذارد.

درج فیلم مسخره ، بازیگر و بررسی داده ها

  1. در VScode ، dataconnect/moviedata_insert.gql باز کنید . اطمینان حاصل کنید که شبیه سازهای موجود در پسوند اتصال داده های Firebase در حال اجرا هستند.
  2. شما باید یک دکمه اجرا (محلی) را در بالای پرونده مشاهده کنید. برای وارد کردن داده های فیلم Mock در پایگاه داده خود ، روی این کلیک کنید.

e424f75e63bf2e10.png

  1. ترمینال اجرای Connect Connect را بررسی کنید تا تأیید شود که داده ها با موفقیت اضافه شده اند.

E0943D7704FB84EA.PNG

اجرای کانکتور

  1. dataconnect/movie-connector/queries.gql را باز کنید. در نظرات یک پرس و جو اصلی ListMovies پیدا خواهید کرد:
query ListMovies @auth(level: PUBLIC) {
  movies {
    id
    title
    imageUrl
    releaseYear
    genre
    rating
    tags
    description
  }
}

این پرس و جو تمام فیلم ها و جزئیات آنها را واگذار می کند (به عنوان مثال ، شناسه ، عنوان ، نسخه آزاد). با این حال ، فیلم ها را مرتب نمی کند .

  1. برای افزودن گزینه های مرتب سازی و محدود کردن گزینه های زیر ، پرس و جو 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 (محلی) کلیک کنید. همچنین می توانید قبل از اجرا متغیرهای پرس و جو را در صفحه پیکربندی وارد کنید.

C4D947115BB16B16.PNG

نکات کلیدی:

  • فیلم ها (): فیلد پرس و جو GraphQL برای واکشی داده های فیلم از پایگاه داده.
  • OrderByrating: پارامتر برای مرتب کردن فیلم ها با رتبه بندی (صعودی/نزولی).
  • OrderByReleaseYear: پارامتر برای مرتب کردن فیلم ها بر اساس سال انتشار (صعودی/نزولی).
  • حد: تعداد فیلم های برگشتی را محدود می کند.

ادغام نمایش داده ها در برنامه وب

در این قسمت ، از نمایش داده شدگان تعریف شده در بخش قبلی در برنامه وب خود استفاده خواهید کرد. شبیه سازهای اتصال داده های Firebase SDK را بر اساس اطلاعات موجود در پرونده های .GQL (Schema.GQL ، queries.gql ، mutations.gql) و connector.yaml تولید می کنند. این SDK ها را می توان مستقیماً در برنامه شما خواند.

  1. در MovieService ( app/src/lib/MovieService.tsx ) ، بیانیه واردات را در بالا از بین ببرید :
import { listMovies, ListMoviesData, OrderDirection } from "@movie/dataconnect";

Function listMovies ، نوع پاسخ ListMoviesData و Enum OrderDirection همه SDK هایی هستند که توسط شبیه سازهای اتصال داده های Firebase بر اساس طرحواره و نمایش داده شده ای که قبلاً تعریف کرده اید تولید می شود.

  1. توابع 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 فیلم برتر و آخرین فیلم در صفحه اصلی استفاده می شود.

آن را در عمل ببینید

بارگذاری مجدد برنامه وب خود برای دیدن پرس و جو در عمل. صفحه اصلی اکنون به صورت پویا لیست فیلم ها را نشان می دهد و داده ها را مستقیماً از پایگاه داده محلی خود واکشی می کند. خواهید دید که رتبه های برتر و جدیدترین فیلم ها یکپارچه به نظر می رسند ، و اطلاعاتی را که به تازگی تنظیم کرده اید منعکس می کند.

5. نمایش جزئیات فیلم و بازیگر

در این بخش ، عملکردی را برای بازیابی اطلاعات دقیق برای یک فیلم یا یک بازیگر با استفاده از شناسه های منحصر به فرد خود اجرا خواهید کرد. این شامل نه تنها داده ها از جداول مربوطه بلکه به جداول مرتبط برای نمایش جزئیات جامع ، مانند بررسی فیلم و فیلم های بازیگر نیز می پیوندد.

ac7fefa7ff779231.png

اجرای اتصالات

  1. dataconnect/movie-connector/queries.gql را در پروژه خود باز کنید .
  2. نمایش داده های زیر را برای بازیابی جزئیات فیلم و بازیگر اضافه کنید :
# 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
    }
  }
}
  1. تغییرات خود را ذخیره کرده و نمایش داده ها را مرور کنید.

نکات کلیدی:

  • movie() / actor() : زمینه های پرس و جو GraphQL برای واکشی یک فیلم یا بازیگر واحد از جدول فیلم ها یا بازیگران.
  • _on_ : این امکان دسترسی مستقیم به زمینه ها از نوع مرتبط را دارد که دارای یک رابطه کلیدی خارجی است. به عنوان مثال ، reviews_on_movie تمام بررسی های مربوط به یک فیلم خاص را واگذار می کند.
  • _via_ : برای حرکت در روابط بسیاری از طریق از طریق جدول پیوستن استفاده می شود. به عنوان مثال ، actors_via_MovieActor از طریق جدول پیوستن به Movieactor ، به نوع بازیگر دسترسی پیدا می کنند ، و where را بر اساس نقش خود فیلتر می کند (به عنوان مثال ، "اصلی" یا "پشتیبانی").

در صفحه اجرای Data Connect ، می توانید پرس و جو را با وارد کردن شناسه های مسخره ، مانند:

{"id": "550e8400-e29b-41d4-a716-446655440000"}

برای بازیابی جزئیات مربوط به "کوانتومی پارادوکس" (فیلم مسخره که شناسه فوق به آن مربوط می شود) برای GetMovieById کلیک کنید.

1B08961891E44DA2.PNG

ادغام نمایش داده ها در برنامه وب

  1. در MovieService ( app/src/lib/MovieService.tsx ) ، واردات زیر را از بین ببرید :
import { getMovieById, GetMovieByIdData } from "@movie/dataconnect";
import { GetActorByIdData, getActorById } from "@movie/dataconnect";
  1. توابع 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 : این انواع نتیجه است که برای نمایش جزئیات فیلم و بازیگر در برنامه استفاده می شود.

آن را در عمل ببینید

اکنون به صفحه اصلی برنامه وب خود بروید. روی یک فیلم کلیک کنید ، و شما قادر خواهید بود تمام جزئیات آن ، از جمله بازیگران و بررسی ها را مشاهده کنید - اطلاعاتی که از جداول مرتبط گرفته شده است. به همین ترتیب ، با کلیک بر روی یک بازیگر ، فیلم هایی که بخشی از آنها بودند به نمایش می گذارند.

6. دست زدن به احراز هویت کاربر

در این بخش ، با استفاده از احراز هویت Firebase ، عملکرد ورود به سیستم و ورود به سیستم را پیاده سازی خواهید کرد. همچنین از داده های تأیید هویت Firebase برای بازیابی مستقیم یا افزایش داده های کاربر در Firebase DataConnect استفاده می کنید ، و از مدیریت ایمن کاربر در برنامه خود اطمینان می دهید.

9890838045D5A00e.png

اجرای اتصالات

  1. Open mutations.gql در dataconnect/movie-connector/ .
  2. برای ایجاد یا به روزرسانی کاربر معتبر فعلی ، جهش زیر را اضافه کنید:
# 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 ارائه می شود ، نه توسط کاربر یا برنامه ، با اطمینان از برخورد ایمن و خودکار ، یک لایه امنیتی اضافی اضافه می کند.

در مرحله بعد ، queries.gql در DataConnect 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 : کلیه بررسی های مربوط به کاربر ، از جمله شناسه و عنوان فیلم را واگذار می کند.
  • favorite_movies_on_user : همه فیلم های مشخص شده توسط کاربر را به عنوان موارد دلخواه ، از جمله اطلاعات دقیق مانند ژانر ، نسخه آزاد ، رتبه بندی و ابرداده بازیابی می کند.

ادغام نمایش داده ها در برنامه وب

  1. در فیلم های ( app/src/lib/MovieService.tsx ) ، واردات زیر را از بین ببرید:
import { upsertUser } from "@movie/dataconnect";
import { getCurrentUser, GetCurrentUserData } from "@movie/dataconnect";
  1. توابع 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 ، که بررسی های کاربر و فیلم های مورد علاقه را بازیابی می کند ، می گیرد.

آن را در عمل ببینید

اکنون روی دکمه "ورود به سیستم با Google" در Navbar کلیک کنید. می توانید با استفاده از Emulator Firebase Auth وارد سیستم شوید. پس از ورود به سیستم ، روی "نمایه من" کلیک کنید. در حال حاضر خالی خواهد بود ، اما شما پایه و اساس مدیریت داده های خاص کاربر را در برنامه خود تنظیم کرده اید.

7. اجرای تعامل کاربر

در این بخش ، تعامل کاربر را در برنامه بررسی فیلم پیاده سازی می کنید ، به کاربران این امکان را می دهید که فیلم های مورد علاقه خود را مدیریت کنند و بررسی ها را ترک یا حذف کنند.

B3D0AC1E181C9DE9.png

اجرای اتصالات

  1. Open mutations.gql در dataconnect/movie-connector/ .
  2. جهش های زیر را برای رسیدگی به فیلم های مورد علاقه اضافه کنید :
# 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 ارائه می شود ، و اطمینان می دهد که فقط به داده های کاربر معتبر کاربر دسترسی یا اصلاح می شود.
  1. در مرحله بعد ، queries.gql در DataConnect dataconnect/movie-connector/ .
  2. پرس و جو زیر را اضافه کنید تا بررسی کنید که آیا یک فیلم مورد علاقه است:
query GetIfFavoritedMovie($movieId: UUID!) @auth(level: USER) {
  favorite_movie(key: { userId_expr: "auth.uid", movieId: $movieId }) {
    movieId
  }
}

نکات کلیدی:

  • auth.uid : دسترسی ایمن به داده های خاص کاربر را با استفاده از احراز هویت Firebase تضمین می کند.
  • favorite_movie : جدول پیوستن favorite_movies را بررسی می کند تا ببیند آیا یک فیلم خاص توسط کاربر فعلی به عنوان مورد علاقه مشخص شده است یا خیر.

ادغام نمایش داده ها در برنامه وب

  1. در MovieService ( app/src/lib/MovieService.tsx ) ، واردات زیر را از بین ببرید :
import { addFavoritedMovie, deleteFavoritedMovie, getIfFavoritedMovie } from "@movie/dataconnect";
  1. توابع 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 استفاده می کند تا بررسی کند که آیا یک فیلم به عنوان مورد علاقه کاربر مشخص شده است یا خیر.

آن را در عمل ببینید

اکنون می توانید با کلیک بر روی نماد قلب در کارتهای فیلم و صفحه جزئیات فیلم ، فیلم های مورد علاقه یا نامشخص را مورد علاقه خود قرار دهید. علاوه بر این ، می توانید فیلم های مورد علاقه خود را در صفحه نمایه خود مشاهده کنید.

اجرای بررسی های کاربر

در مرحله بعد ، بخش مدیریت بررسی کاربر را در برنامه پیاده سازی خواهید کرد.

اجرای اتصالات

  1. در 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 ایجاد می کند و نیاز به ورودی دستی را از بین می برد.

ادغام نمایش داده ها در برنامه وب

  1. در MovieService ( app/src/lib/MovieService.tsx ) ، واردات زیر را از بین ببرید :
import { addReview, deleteReview } from "@movie/dataconnect";
  1. توابع 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 برای حذف یک بررسی برای یک فیلم توسط کاربر معتبر استفاده می کند.

آن را در عمل ببینید

اکنون کاربران می توانند بررسی فیلم ها را در صفحه جزئیات فیلم بگذارند. آنها همچنین می توانند بررسی های خود را در صفحه نمایه خود مشاهده و حذف کنند و به آنها کنترل کامل بر تعامل خود با برنامه می دهند.

8. فیلترهای پیشرفته و تطبیق متن جزئی

در این بخش ، شما قابلیت های جستجوی پیشرفته را پیاده سازی خواهید کرد ، به کاربران این امکان را می دهید تا فیلم ها را بر اساس طیف وسیعی از رتبه بندی ها و سالهای انتشار ، فیلتر بر روی ژانرها و برچسب ها جستجو کنند ، تطبیق متن جزئی را در عناوین یا توضیحات انجام دهند و حتی چندین فیلتر را برای دقیق تر ترکیب کنند. نتایج

ECE70EE0AB964E28.PNG

اجرای اتصالات

  1. Open queries.gql در dataconnect/movie-connector/ .
  2. پرس و جو زیر را برای پشتیبانی از قابلیت های مختلف جستجوی اضافه کنید :
# 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 برای تعریف معیارهای خاص برای جستجو استفاده می کند.

ادغام نمایش داده ها در برنامه وب

  1. در MovieService ( app/src/lib/MovieService.tsx ) ، واردات زیر را از بین ببرید :
import { searchAll, SearchAllData } from "@movie/dataconnect";
  1. عملکرد 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 برای انجام یک جستجو بر اساس ورودی کاربر ، نتایج فیلتر شده بر اساس پارامترهایی مانند سال ، رتبه بندی ، ژانر و متن های جزئی استفاده می کند.

آن را در عمل ببینید

به صفحه "جستجوی پیشرفته" از NAVBAR در برنامه وب بروید. هم اکنون می توانید با استفاده از فیلترها و ورودی های مختلف ، فیلم ها ، بازیگران و بررسی ها را جستجو کنید ، و نتایج جستجوی دقیق و متناسب را دریافت کنید.

9. اختیاری: استقرار به ابر (صورتحساب مورد نیاز)

اکنون که شما از طریق تکرار توسعه محلی کار کرده اید ، وقت آن است که طرح ، داده و نمایش داده های خود را به سرور مستقر کنید. این کار را می توان با استفاده از پسوند داده Firebase Connect vs Code یا Firebase CLI انجام داد.

اضافه کردن یک برنامه وب در کنسول Firebase

  1. در کنسول Firebase یک برنامه وب ایجاد کنید و به شناسه برنامه خود توجه کنید

7030822793e4d75b.png

  1. با کلیک بر روی "افزودن برنامه" ، یک برنامه وب را در کنسول Firebase تنظیم کنید. اکنون می توانید با خیال راحت تنظیمات و تنظیمات SDK را نادیده بگیرید ، اما به شیء firebaseConfig تولید شده توجه کنید.
  2. firebaseConfig را در app/src/lib/firebase.tsx جایگزین کنید :
const firebaseConfig = {
  apiKey: "API_KEY",
  authDomain: "PROJECT_ID.firebaseapp.com",
  projectId: "PROJECT_ID",
  storageBucket: "PROJECT_ID.appspot.com",
  messagingSenderId: "SENDER_ID",
  appId: "APP_ID"
};
  1. برنامه وب را بسازید: در پوشه app ، از Vite برای ساخت برنامه وب برای استقرار میزبانی استفاده کنید:
cd app
npm run build

احراز هویت Firebase را در کنسول تنظیم کنید

  1. تنظیمات Firebase را با ورود به سیستم Google تنظیم کنید

62AF2F225E790EF6.PNG

  1. (اختیاری) اجازه دهید دامنه ها برای (Firebase Auth) [https://firebase.google.com/docs/auth/web/hosting] در کنسول پروژه خود (به عنوان مثال ، http: http://127.0.0.1 ):
  • در تنظیمات AUTH ، پروژه خود را انتخاب کرده و به (دامنه های مجاز) بروید [https://firebase.google.com/docs/auth/web/hosting] . روی "افزودن دامنه" کلیک کنید و دامنه محلی خود را در لیست قرار دهید.

C255098F12549886.PNG

استقرار با Firebase CLI

  1. در 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"]
  1. اطمینان حاصل کنید که Firebase CLI را با پروژه خود تنظیم کرده اید
npm i -g firebase-tools
firebase login --reauth
firebase use --add
  1. در ترمینال خود دستور زیر را برای استقرار اجرا کنید:
firebase deploy --only dataconnect,hosting
  1. این دستور را برای مقایسه تغییرات طرحواره خود اجرا کنید:
firebase dataconnect:sql:diff
  1. اگر تغییرات قابل قبول است ، آنها را با:
firebase dataconnect:sql:migrate

Cloud SQL شما برای نمونه PostgreSQL با طرح و داده های مستقر نهایی به روز می شود. می توانید وضعیت موجود در کنسول Firebase را کنترل کنید.

اکنون باید بتوانید برنامه خود را به صورت زنده در your-project.web.app/ ببینید. علاوه بر این ، می توانید بر روی Run (تولید) در صفحه Firebase Data Connect ، دقیقاً همانطور که با شبیه سازهای محلی انجام دادید ، کلیک کنید تا داده ها را به محیط تولید اضافه کنید.

10. اختیاری: جستجوی بردار با داده های Firebase Connect

در این بخش ، با استفاده از Firebase Data Connect ، جستجوی بردار را در برنامه بررسی فیلم خود فعال می کنید. این ویژگی امکان جستجوهای مبتنی بر محتوا را فراهم می کند ، مانند یافتن فیلم هایی با توضیحات مشابه با استفاده از تعبیه بردار.

4B5ACA5A447D2FEB.PNG

طرح را به روز کنید تا شامل تعبیه برای یک زمینه باشد

  1. در 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

  1. راهنمای پیش نیازها را برای تنظیم API های Vertex AI با Google Cloud دنبال کنید. این مرحله برای پشتیبانی از عملکرد تعبیه و عملکرد جستجوی بردار ضروری است.
  2. طرح خود را برای فعال کردن جستجوی pgvector و بردار با کلیک بر روی Deploy to تولید با استفاده از Firebase Data Connect VSCODE پسوند مجدداً مستقر کنید .

جمع آوری پایگاه داده با تعبیه

  1. پوشه dataconnect را در VScode باز کنید و روی Run (محلی) در optional_vector_embed.gql کلیک کنید تا پایگاه داده خود را با تعبیه برای فیلم ها جمع کنید.

B858DA780F6EC103.png

یک پرس و جو جستجوی بردار اضافه کنید

  1. در 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 را محدود می کند.

عملکرد جستجوی بردار را در برنامه پیاده سازی کنید

  1. در app/src/lib/MovieService.ts ، واردات زیر را کاهش دهید:

عملکرد جستجوی بردار را در برنامه پیاده سازی کنید

اکنون که طرح و پرس و جو تنظیم شده است ، جستجوی بردار را در لایه سرویس برنامه خود ادغام کنید. این مرحله به شما امکان می دهد از برنامه وب خود با جستجوی جستجو تماس بگیرید.

در 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 می پردازد و از متن ورودی برای انجام یک جستجوی محتوای مبتنی بر بردار استفاده می کند.

آن را در عمل ببینید

به بخش "جستجوی بردار" در NAVBAR بروید و عباراتی مانند "عاشقانه و مدرن" را تایپ کنید. لیستی از فیلم هایی را مشاهده می کنید که با محتوایی که در جستجوی آن هستند مطابقت دارند یا به صفحه جزئیات فیلم هر فیلم می روید و بخش فیلم های مشابه را در پایین صفحه مشاهده می کنید.

7b71f1c75633c1be.png

11. نتیجه گیری

تبریک می گویم ، شما باید بتوانید از برنامه وب استفاده کنید! اگر می خواهید با داده های فیلم خود بازی کنید ، نگران نباشید ، داده های خود را با استفاده از پسوند FDC با تقلید از پرونده های _insert.gql وارد کنید ، یا آنها را از طریق صفحه اجرای Connect Connect اضافه کنید.

بیشتر بدانید