Tạo bằng Firebase Data Connect

1. Trước khi bắt đầu

Ứng dụng FriendlyMovies

Trong lớp học lập trình này, bạn sẽ tích hợp Firebase Data Connect với cơ sở dữ liệu Cloud SQL để tạo một ứng dụng web đánh giá phim. Ứng dụng hoàn chỉnh sẽ cho thấy cách Firebase Data Connect đơn giản hoá quy trình tạo ứng dụng dựa trên SQL. Gói này bao gồm các tính năng sau:

  • Xác thực: Triển khai quy trình xác thực tuỳ chỉnh cho các truy vấn và đột biến của ứng dụng, đảm bảo chỉ những người dùng được uỷ quyền mới có thể tương tác với dữ liệu của bạn.
  • Giản đồ GraphQL: Tạo và quản lý cấu trúc dữ liệu bằng cách sử dụng giản đồ GraphQL linh hoạt, phù hợp với nhu cầu của ứng dụng web đánh giá phim.
  • Truy vấn và đột biến SQL: Truy xuất, cập nhật và quản lý dữ liệu trong Cloud SQL bằng các truy vấn và đột biến do GraphQL cung cấp.
  • Tìm kiếm nâng cao bằng kiểu khớp một phần chuỗi: Sử dụng bộ lọc và lựa chọn tìm kiếm để tìm phim dựa trên các trường như tiêu đề, nội dung mô tả hoặc thẻ.
  • (Không bắt buộc) Tích hợp tính năng tìm kiếm vectơ: Thêm chức năng tìm kiếm nội dung bằng cách sử dụng tính năng tìm kiếm vectơ của Firebase Data Connect để mang lại trải nghiệm phong phú cho người dùng dựa trên dữ liệu đầu vào và lựa chọn ưu tiên.

Điều kiện tiên quyết

Bạn cần có kiến thức cơ bản về JavaScript.

Kiến thức bạn sẽ học được

  • Thiết lập Firebase Data Connect bằng trình mô phỏng cục bộ.
  • Thiết kế giản đồ dữ liệu bằng Data Connect và GraphQL.
  • Viết và kiểm thử nhiều truy vấn và đột biến cho một ứng dụng đánh giá phim.
  • Tìm hiểu cách Firebase Data Connect tạo và sử dụng SDK trong ứng dụng.
  • Triển khai giản đồ và quản lý cơ sở dữ liệu một cách hiệu quả.

Những gì bạn cần

2. Thiết lập môi trường phát triển

Giai đoạn này của lớp học lập trình sẽ hướng dẫn bạn thiết lập môi trường để bắt đầu xây dựng ứng dụng đánh giá phim bằng Firebase Data Connect.

  1. Nhân bản kho lưu trữ dự án và cài đặt các phần phụ thuộc bắt buộc:
    git clone https://github.com/firebaseextended/codelab-dataconnect-web
    cd codelab-dataconnect-web
    cd ./app && npm i
    npm run dev
    
  2. Sau khi chạy các lệnh này, hãy mở http://localhost:5173 trong trình duyệt để xem ứng dụng web đang chạy cục bộ. Đây là giao diện người dùng để tạo ứng dụng đánh giá phim và tương tác với các tính năng của ứng dụng.93f6648a2532c606.png
  3. Mở thư mục codelab-dataconnect-web được sao chép bằng Visual Studio Code. Đây là nơi bạn sẽ xác định giản đồ, ghi truy vấn và kiểm thử chức năng của ứng dụng.
  4. Để sử dụng các tính năng của Data Connect, hãy cài đặt Tiện ích Visual Studio cho Firebase Data Connect.
    Ngoài ra, bạn có thể cài đặt tiện ích này từ Visual Studio Code Marketplace hoặc tìm kiếm tiện ích đó trong VS Code.b03ee38c9a81b648.png
  5. Mở hoặc tạo một dự án Firebase mới trong bảng điều khiển của Firebase.
  6. Kết nối dự án Firebase với tiện ích Firebase Data Connect VSCode. Trong tiện ích, hãy làm như sau:
    1. Nhấp vào nút Đăng nhập.
    2. Nhấp vào Kết nối dự án Firebase rồi chọn dự án Firebase của bạn.
    4bb2fbf8f9fac29b.png
  7. Khởi động trình mô phỏng Firebase bằng tiện ích Firebase Data Connect VS Code:
    Nhấp vào Start Emulators (Khởi động trình mô phỏng), sau đó xác nhận rằng trình mô phỏng đang chạy trong thiết bị đầu cuối.6d3d95f4cb708db1.png

3. Xem lại cơ sở mã khởi động

Trong phần này, bạn sẽ khám phá các phần chính của cơ sở mã ban đầu của ứng dụng. Mặc dù ứng dụng này thiếu một số chức năng, nhưng bạn vẫn nên tìm hiểu cấu trúc tổng thể của ứng dụng.

Cấu trúc thư mục và tệp

Các tiểu mục sau đây cung cấp thông tin tổng quan về thư mục và cấu trúc tệp của ứng dụng.

Thư mục dataconnect/

Chứa các cấu hình Firebase Data Connect, trình kết nối (xác định truy vấn và đột biến) và tệp giản đồ.

  • schema/schema.gql: Xác định giản đồ GraphQL
  • connector/queries.gql: Các truy vấn cần thiết trong ứng dụng
  • connector/mutations.gql: Các đột biến cần thiết trong ứng dụng
  • connector/connector.yaml: Tệp cấu hình để tạo SDK

Thư mục app/src/

Chứa logic ứng dụng và hoạt động tương tác với Firebase Data Connect.

  • firebase.ts: Cấu hình để kết nối với một Ứng dụng Firebase trong dự án Firebase.
  • lib/dataconnect-sdk/: Chứa SDK đã tạo. Bạn có thể chỉnh sửa vị trí tạo SDK trong tệp connector/connector.yaml và SDK sẽ được tạo tự động bất cứ khi nào bạn xác định một truy vấn hoặc đột biến.

4. Xác định giản đồ cho bài đánh giá phim

Trong phần này, bạn sẽ xác định cấu trúc và mối quan hệ giữa các thực thể chính trong ứng dụng phim trong một giản đồ. Các thực thể như Movie, User, ActorReview được liên kết với các bảng cơ sở dữ liệu, với các mối quan hệ được thiết lập bằng cách sử dụng lệnh của giản đồ Firebase Data Connect và GraphQL. Sau khi triển khai, ứng dụng của bạn sẽ sẵn sàng xử lý mọi thứ, từ việc tìm kiếm phim có điểm xếp hạng cao nhất và lọc theo thể loại cho đến việc cho phép người dùng để lại bài đánh giá, đánh dấu phim yêu thích, khám phá các phim tương tự hoặc tìm phim được đề xuất dựa trên nội dung nhập bằng văn bản thông qua tính năng tìm kiếm vectơ.

Các thực thể và mối quan hệ cốt lõi

Loại Movie chứa các thông tin chi tiết chính như tiêu đề, thể loại và thẻ mà ứng dụng sử dụng cho nội dung tìm kiếm và hồ sơ phim. Loại User theo dõi các lượt tương tác của người dùng, chẳng hạn như bài đánh giá và mục yêu thích. Reviews kết nối người dùng với phim, cho phép ứng dụng hiển thị điểm xếp hạng và ý kiến phản hồi do người dùng tạo.

Mối quan hệ giữa phim, diễn viên và người dùng giúp ứng dụng trở nên linh động hơn. Bảng nối MovieActor giúp hiển thị thông tin chi tiết về dàn diễn viên và danh sách phim của diễn viên. Loại FavoriteMovie cho phép người dùng đánh dấu phim yêu thích để ứng dụng có thể hiển thị danh sách yêu thích được cá nhân hoá và làm nổi bật các lựa chọn phổ biến.

Thiết lập bảng Movie

Loại Movie xác định cấu trúc chính cho một thực thể phim, bao gồm các trường như title, genre, releaseYearrating.

Sao chép và dán đoạn mã vào tệp 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]
}

Điểm chính cần ghi nhớ:

  • id: Một UUID duy nhất cho mỗi bộ phim, được tạo bằng @default(expr: "uuidV4()").

Thiết lập bảng MovieMetadata

Loại MovieMetadata thiết lập mối quan hệ một với một với loại Movie. Dữ liệu này bao gồm các dữ liệu bổ sung như đạo diễn của phim.

Sao chép và dán đoạn mã vào tệp 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
}

Điểm chính cần ghi nhớ:

  • Phim! @ref: Tham chiếu loại Movie, thiết lập mối quan hệ khoá ngoại.

Thiết lập bảng Actor

Sao chép và dán đoạn mã vào tệp dataconnect/schema/schema.gql:

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

Loại Actor đại diện cho một diễn viên trong cơ sở dữ liệu phim, trong đó mỗi diễn viên có thể tham gia nhiều bộ phim, tạo thành mối quan hệ nhiều với nhiều.

Thiết lập bảng MovieActor

Sao chép và dán đoạn mã vào tệp 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"
}

Điểm chính cần ghi nhớ:

  • movie: Tham chiếu đến loại Movie (Phim), ngầm tạo một khoá ngoại movieId: UUID!.
  • actor: Tham chiếu đến loại Actor, ngầm tạo một khoá ngoại actorId: UUID!.
  • role: Xác định vai trò của diễn viên trong phim (ví dụ: "chính" hoặc "hỗ trợ").

Thiết lập bảng User

Loại User xác định một thực thể người dùng tương tác với phim bằng cách để lại bài đánh giá hoặc thêm phim vào danh sách yêu thích.

Sao chép và dán đoạn mã vào tệp 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
}

Thiết lập bảng FavoriteMovie

Loại FavoriteMovie là một bảng nối xử lý mối quan hệ nhiều với nhiều giữa người dùng và những bộ phim mà họ yêu thích. Mỗi bảng liên kết một User với một Movie.

Sao chép và dán đoạn mã vào tệp 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!
}

Điểm chính cần ghi nhớ:

  • movie: Tham chiếu đến loại Movie (Phim), ngầm tạo một khoá ngoại movieId: UUID!.
  • user: Tham chiếu đến loại người dùng, ngầm tạo một khoá ngoại userId: UUID!.

Thiết lập bảng Review

Loại Review đại diện cho thực thể bài đánh giá và liên kết các loại UserMovie theo mối quan hệ nhiều với nhiều (một người dùng có thể để lại nhiều bài đánh giá và mỗi bộ phim có thể có nhiều bài đánh giá).

Sao chép và dán đoạn mã vào tệp 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")
}

Điểm chính cần ghi nhớ:

  • user: Tham chiếu đến người dùng đã để lại bài đánh giá.
  • movie: Tham chiếu đến bộ phim đang được đánh giá.
  • reviewDate: Tự động đặt thành thời gian tạo bài đánh giá bằng @default(expr: "request.time").

Các trường được tạo tự động và mặc định

Giản đồ này sử dụng các biểu thức như @default(expr: "uuidV4()") để tự động tạo mã nhận dạng và dấu thời gian duy nhất. Ví dụ: trường id trong các loại MovieReview sẽ tự động được điền bằng UUID khi tạo một bản ghi mới.

Giờ đây, khi đã xác định được giản đồ, ứng dụng phim của bạn đã có nền tảng vững chắc cho cấu trúc và mối quan hệ dữ liệu!

5. Truy xuất các bộ phim hàng đầu và mới nhất

Ứng dụng FriendlyMovies

Trong phần này, bạn sẽ chèn dữ liệu phim mô phỏng vào trình mô phỏng cục bộ, sau đó triển khai các trình kết nối (truy vấn) và mã TypeScript để gọi các trình kết nối này trong ứng dụng web. Cuối cùng, ứng dụng của bạn sẽ có thể tự động tìm nạp và hiển thị các bộ phim mới nhất và được đánh giá cao nhất ngay trong cơ sở dữ liệu.

Chèn dữ liệu giả lập về phim, diễn viên và bài đánh giá

  1. Trong VSCode, hãy mở dataconnect/moviedata_insert.gql. Đảm bảo trình mô phỏng trong tiện ích Firebase Data Connect đang chạy.
  2. Bạn sẽ thấy nút Run (local) (Chạy (trên máy)) ở đầu tệp. Nhấp vào đây để chèn dữ liệu phim mô phỏng vào cơ sở dữ liệu.
    e424f75e63bf2e10.png
  3. Kiểm tra thiết bị đầu cuối Data Connect Execution (Thực thi kết nối dữ liệu) để xác nhận rằng dữ liệu đã được thêm thành công.
    e0943d7704fb84ea.png

Triển khai trình kết nối

  1. Mở dataconnect/movie-connector/queries.gql. Bạn sẽ thấy một truy vấn ListMovies cơ bản trong phần nhận xét:
    query ListMovies @auth(level: PUBLIC) {
      movies {
        id
        title
        imageUrl
        releaseYear
        genre
        rating
        tags
        description
      }
    }
    
    Truy vấn này tìm nạp tất cả phim và thông tin chi tiết về phim (ví dụ: id, title, releaseYear). Tuy nhiên, truy vấn này không sắp xếp các phim.
  2. Thay thế truy vấn ListMovies hiện có bằng truy vấn sau để thêm các tuỳ chọn sắp xếp và giới hạn:
    # 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
      }
    }
    
  3. Nhấp vào nút Run (local) (Chạy (cục bộ)) để thực thi truy vấn trên cơ sở dữ liệu cục bộ. Bạn cũng có thể nhập các biến truy vấn trong ngăn cấu hình trước khi chạy.
    c4d947115bb11b16.png

Điểm chính cần ghi nhớ:

  • movies(): Trường truy vấn GraphQL để tìm nạp dữ liệu phim từ cơ sở dữ liệu.
  • orderByRating: Tham số để sắp xếp phim theo điểm xếp hạng (tăng dần/giảm dần).
  • orderByReleaseYear: Tham số để sắp xếp phim theo năm phát hành (tăng dần/giảm dần).
  • limit: Hạn chế số lượng phim được trả về.

Tích hợp truy vấn trong ứng dụng web

Trong phần này của lớp học lập trình, bạn sẽ sử dụng các truy vấn được xác định trong phần trước trong ứng dụng web của mình. Trình mô phỏng Firebase Data Connect tạo SDK dựa trên thông tin trong tệp .gql (cụ thể là schema.gql, queries.gql, mutations.gql) và tệp connector.yaml. Bạn có thể gọi trực tiếp các SDK này trong ứng dụng.

  1. Trong MovieService (app/src/lib/MovieService.tsx), hãy bỏ ghi chú câu lệnh nhập ở trên cùng:
    import { listMovies, ListMoviesData, OrderDirection } from "@movie/dataconnect";
    
    Hàm listMovies, loại phản hồi ListMoviesData và enum OrderDirection đều là các SDK do trình mô phỏng Firebase Data Connect tạo ra dựa trên giản đồ và các truy vấn mà bạn đã xác định trước đó .
  2. Thay thế các hàm handleGetTopMovieshandleGetLatestMovies bằng mã sau:
    // 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;
      }
    };
    

Điểm chính cần ghi nhớ:

  • listMovies: Hàm được tạo tự động gọi truy vấn listMovies để truy xuất danh sách phim. Trang này có các tuỳ chọn sắp xếp theo điểm xếp hạng hoặc năm phát hành và giới hạn số lượng kết quả.
  • ListMoviesData: Loại kết quả dùng để hiển thị 10 phim hàng đầu và mới nhất trên trang chủ của ứng dụng.

Xem ví dụ thực tế

Tải lại ứng dụng web để xem truy vấn hoạt động. Trang chủ hiện hiển thị linh động danh sách phim, tìm nạp dữ liệu trực tiếp từ cơ sở dữ liệu cục bộ. Bạn sẽ thấy các bộ phim mới nhất và được đánh giá cao nhất xuất hiện liền mạch, phản ánh dữ liệu bạn vừa thiết lập.

6. Hiển thị thông tin chi tiết về phim và diễn viên

Trong phần này, bạn sẽ triển khai chức năng truy xuất thông tin chi tiết về một bộ phim hoặc một diễn viên bằng mã nhận dạng duy nhất của họ. Việc này không chỉ liên quan đến việc tìm nạp dữ liệu từ các bảng tương ứng mà còn liên kết các bảng có liên quan để hiển thị thông tin chi tiết toàn diện, chẳng hạn như bài đánh giá phim và danh sách phim của diễn viên.

ac7fefa7ff779231.png

Triển khai trình kết nối

  1. Mở dataconnect/movie-connector/queries.gql trong dự án.
  2. Thêm các truy vấn sau để truy xuất thông tin chi tiết về phim và diễn viên:
    # 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
        }
      }
    }
    
  3. Lưu các thay đổi và xem lại các truy vấn.

Điểm chính cần ghi nhớ:

  • movie()/actor(): Các trường truy vấn GraphQL để tìm nạp một bộ phim hoặc diễn viên từ bảng Movies hoặc Actors.
  • _on_: Cho phép truy cập trực tiếp vào các trường từ một loại được liên kết có mối quan hệ khoá ngoại. Ví dụ: reviews_on_movie tìm nạp tất cả bài đánh giá liên quan đến một bộ phim cụ thể.
  • _via_: Dùng để điều hướng các mối quan hệ nhiều với nhiều thông qua bảng nối. Ví dụ: actors_via_MovieActor truy cập vào loại Actor thông qua bảng nối MovieActor và điều kiện where lọc diễn viên dựa trên vai trò của họ (ví dụ: "chính" hoặc "hỗ trợ").

Kiểm thử truy vấn bằng cách nhập dữ liệu mô phỏng

  1. Trong ngăn thực thi Data Connect, bạn có thể kiểm thử truy vấn bằng cách nhập mã nhận dạng mô phỏng, chẳng hạn như:
    {"id": "550e8400-e29b-41d4-a716-446655440000"}
    
  2. Nhấp vào Run (local) (Chạy (trên máy)) cho GetMovieById để truy xuất thông tin chi tiết về "Quantum Paradox" (phim mô phỏng liên quan đến mã nhận dạng ở trên).

1b08961891e44da2.png

Tích hợp truy vấn trong ứng dụng web

  1. Trong MovieService (app/src/lib/MovieService.tsx), hãy bỏ ghi chú các lệnh nhập sau:
    import { getMovieById, GetMovieByIdData } from "@movie/dataconnect";
    import { GetActorByIdData, getActorById } from "@movie/dataconnect";
    
  2. Thay thế các hàm handleGetMovieByIdhandleGetActorById bằng mã sau:
    // 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;
      }
    };
    

Điểm chính cần ghi nhớ:

  • getMovieById / getActorById: Đây là các hàm được tạo tự động gọi các truy vấn mà bạn đã xác định, truy xuất thông tin chi tiết về một bộ phim hoặc diễn viên cụ thể.
  • GetMovieByIdData / GetActorByIdData: Đây là các loại kết quả, dùng để hiển thị thông tin chi tiết về phim và diễn viên trong ứng dụng.

Xem ví dụ thực tế

Bây giờ, hãy chuyển đến trang chủ của ứng dụng web. Nhấp vào một bộ phim để xem tất cả thông tin chi tiết về bộ phim đó, bao gồm cả diễn viên và bài đánh giá. Đây là thông tin được lấy từ các bảng liên quan. Tương tự, khi bạn nhấp vào một diễn viên, những bộ phim mà họ tham gia sẽ xuất hiện.

7. Xử lý việc xác thực người dùng

Trong phần này, bạn sẽ triển khai chức năng đăng nhập và đăng xuất của người dùng bằng tính năng Xác thực Firebase. Bạn cũng sẽ sử dụng dữ liệu Xác thực Firebase để truy xuất hoặc chèn/cập nhật dữ liệu người dùng trong Firebase DataConnect, đảm bảo việc quản lý người dùng an toàn trong ứng dụng.

9890838045d5a00e.png

Triển khai trình kết nối

  1. Mở mutations.gql trong dataconnect/movie-connector/.
  2. Thêm đột biến sau để tạo hoặc cập nhật người dùng đã xác thực hiện tại:
    # Create or update the current authenticated user
    mutation UpsertUser($username: String!) @auth(level: USER) {
      user_upsert(
        data: {
          id_expr: "auth.uid"
          username: $username
        }
      )
    }
    

Điểm chính cần ghi nhớ:

  • id_expr: "auth.uid": Phương thức này sử dụng auth.uid do Xác thực Firebase trực tiếp cung cấp, chứ không phải do người dùng hoặc ứng dụng cung cấp, giúp tăng cường thêm một lớp bảo mật bằng cách đảm bảo mã nhận dạng người dùng được xử lý một cách an toàn và tự động.

Tìm nạp người dùng hiện tại

  1. Mở queries.gql trong dataconnect/movie-connector/.
  2. Thêm truy vấn sau để tìm nạp người dùng hiện tại:
    # 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
            }
          }
        }
      }
    }
    

Điểm chính cần ghi nhớ:

  • auth.uid: Mã này được truy xuất trực tiếp từ tính năng Xác thực Firebase, đảm bảo quyền truy cập an toàn vào dữ liệu dành riêng cho người dùng.
  • Các trường _on_: Các trường này đại diện cho các bảng nối:
    • reviews_on_user: Tìm nạp tất cả bài đánh giá liên quan đến người dùng, bao gồm cả idtitle của phim.
    • favorite_movies_on_user: Truy xuất tất cả phim mà người dùng đánh dấu là phim yêu thích, bao gồm cả thông tin chi tiết như genre, releaseYear, ratingmetadata.

Tích hợp truy vấn trong ứng dụng web

  1. Trong MovieService (app/src/lib/MovieService.tsx), hãy bỏ ghi chú các lệnh nhập sau:
    import { upsertUser } from "@movie/dataconnect";
    import { getCurrentUser, GetCurrentUserData } from "@movie/dataconnect";
    
  2. Thay thế các hàm handleAuthStateChangehandleGetCurrentUser bằng mã sau:
    // 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;
      }
    };
    

Điểm chính cần ghi nhớ:

  • handleAuthStateChange: Hàm này theo dõi các thay đổi về trạng thái xác thực. Khi người dùng đăng nhập, ứng dụng sẽ đặt dữ liệu của người dùng và gọi đột biến upsertUser để tạo hoặc cập nhật thông tin của người dùng trong cơ sở dữ liệu.
  • handleGetCurrentUser: Tìm nạp hồ sơ của người dùng hiện tại bằng cách sử dụng truy vấn getCurrentUser. Truy vấn này sẽ truy xuất bài đánh giá và phim yêu thích của người dùng.

Xem ví dụ thực tế

Bây giờ, hãy nhấp vào nút "Đăng nhập bằng Google" trong thanh điều hướng. Bạn có thể đăng nhập bằng trình mô phỏng Xác thực Firebase. Sau khi đăng nhập, hãy nhấp vào "Hồ sơ của tôi". Hiện tại, phần này sẽ trống, nhưng bạn đã thiết lập nền tảng để xử lý dữ liệu dành riêng cho người dùng trong ứng dụng.

8. Triển khai hoạt động tương tác của người dùng

Trong phần này của lớp học lập trình, bạn sẽ triển khai các hoạt động tương tác của người dùng trong ứng dụng đánh giá phim, cụ thể là cho phép người dùng quản lý các bộ phim mà họ yêu thích, đồng thời để lại hoặc xoá bài đánh giá.

b3d0ac1e181c9de9.png

Cho phép người dùng thêm phim vào danh sách yêu thích

Trong phần này, bạn sẽ thiết lập cơ sở dữ liệu để cho phép người dùng thêm phim vào danh sách yêu thích.

Triển khai trình kết nối

  1. Mở mutations.gql trong dataconnect/movie-connector/.
  2. Thêm các đột biến sau để xử lý việc thêm phim vào danh sách yêu thích:
    # 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 })
    }
    
    

Điểm chính cần ghi nhớ:

  • userId_expr: "auth.uid": Sử dụng auth.uid do Xác thực Firebase trực tiếp cung cấp, đảm bảo rằng chỉ truy cập hoặc sửa đổi dữ liệu của người dùng đã xác thực.

Kiểm tra xem một bộ phim có được thêm vào danh sách yêu thích hay không

  1. Mở queries.gql trong dataconnect/movie-connector/.
  2. Thêm truy vấn sau để kiểm tra xem một bộ phim có được thêm vào danh sách yêu thích hay không:
    query GetIfFavoritedMovie($movieId: UUID!) @auth(level: USER) {
      favorite_movie(key: { userId_expr: "auth.uid", movieId: $movieId }) {
        movieId
      }
    }
    

Điểm chính cần ghi nhớ:

  • auth.uid: Đảm bảo quyền truy cập an toàn vào dữ liệu dành riêng cho người dùng bằng tính năng Xác thực Firebase.
  • favorite_movie: Kiểm tra bảng nối favorite_movies để xem người dùng hiện tại có đánh dấu một bộ phim cụ thể là phim yêu thích hay không.

Tích hợp truy vấn trong ứng dụng web

  1. Trong MovieService (app/src/lib/MovieService.tsx), hãy bỏ ghi chú các lệnh nhập sau:
    import { addFavoritedMovie, deleteFavoritedMovie, getIfFavoritedMovie } from "@movie/dataconnect";
    
  2. Thay thế các hàm handleAddFavoritedMovie, handleDeleteFavoritedMoviehandleGetIfFavoritedMovie bằng mã sau:
    // 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;
      }
    };
    

Điểm chính cần ghi nhớ:

  • handleAddFavoritedMoviehandleDeleteFavoritedMovie: Sử dụng các đột biến để thêm hoặc xoá một bộ phim khỏi danh sách yêu thích của người dùng một cách an toàn.
  • handleGetIfFavoritedMovie: Sử dụng truy vấn getIfFavoritedMovie để kiểm tra xem người dùng có đánh dấu một bộ phim là yêu thích hay không.

Xem ví dụ thực tế

Giờ đây, bạn có thể thêm phim vào danh sách yêu thích hoặc xoá phim khỏi danh sách yêu thích bằng cách nhấp vào biểu tượng trái tim trên thẻ phim và trang chi tiết về phim. Ngoài ra, bạn có thể xem các bộ phim yêu thích trên trang hồ sơ của mình.

Cho phép người dùng để lại hoặc xoá bài đánh giá

Tiếp theo, bạn sẽ triển khai phần quản lý bài đánh giá của người dùng trong ứng dụng.

Triển khai trình kết nối

Trong mutations.gql (dataconnect/movie-connector/mutations.gql): Thêm các đột biến sau:

# 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 })
}

Điểm chính cần ghi nhớ:

  • userId_expr: "auth.uid": Đảm bảo rằng bài đánh giá được liên kết với người dùng đã xác thực.
  • reviewDate_date: { today: true }: Tự động tạo ngày hiện tại cho bài đánh giá bằng DataConnect, giúp bạn không cần phải nhập theo cách thủ công.

Tích hợp truy vấn trong ứng dụng web

  1. Trong MovieService (app/src/lib/MovieService.tsx), hãy bỏ ghi chú các lệnh nhập sau:
    import { addReview, deleteReview } from "@movie/dataconnect";
    
  2. Thay thế các hàm handleAddReviewhandleDeleteReview bằng mã sau:
    // 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;
      }
    };
    

Điểm chính cần ghi nhớ:

  • handleAddReview: Gọi đột biến addReview để thêm bài đánh giá cho bộ phim đã chỉ định, liên kết bài đánh giá đó một cách an toàn với người dùng đã xác thực.
  • handleDeleteReview: Sử dụng đột biến deleteReview để xoá bài đánh giá về một bộ phim do người dùng đã xác thực thực hiện.

Xem ví dụ thực tế

Giờ đây, người dùng có thể để lại bài đánh giá về phim trên trang chi tiết về phim. Người dùng cũng có thể xem và xoá bài đánh giá của mình trên trang hồ sơ, nhờ đó có toàn quyền kiểm soát các hoạt động tương tác với ứng dụng.

9. Bộ lọc nâng cao và tính năng so khớp văn bản một phần

Trong phần này, bạn sẽ triển khai các tính năng tìm kiếm nâng cao, cho phép người dùng tìm kiếm phim dựa trên một loạt điểm xếp hạng và năm phát hành, lọc theo thể loại và thẻ, so khớp một phần văn bản trong tiêu đề hoặc nội dung mô tả, thậm chí kết hợp nhiều bộ lọc để có kết quả chính xác hơn.

ece70ee0ab964e28.png

Triển khai trình kết nối

  1. Mở queries.gql trong dataconnect/movie-connector/.
  2. Thêm truy vấn sau để hỗ trợ nhiều tính năng tìm kiếm:
    # 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
        }
      }
    }
    

Điểm chính cần ghi nhớ:

  • Toán tử _and: Kết hợp nhiều điều kiện trong một truy vấn, cho phép lọc kết quả tìm kiếm theo một số trường như releaseYear, ratinggenre.
  • Toán tử contains: Tìm kiếm các kết quả khớp một phần văn bản trong các trường. Trong truy vấn này, hàm này tìm kiếm các kết quả trùng khớp trong title, description, name hoặc reviewText.
  • Mệnh đề where: Chỉ định các điều kiện để lọc dữ liệu. Mỗi phần (phim, diễn viên, bài đánh giá) sử dụng một mệnh đề where để xác định tiêu chí cụ thể cho nội dung tìm kiếm.

Tích hợp truy vấn trong ứng dụng web

  1. Trong MovieService (app/src/lib/MovieService.tsx), hãy bỏ ghi chú các lệnh nhập sau:
    import { searchAll, SearchAllData } from "@movie/dataconnect";
    
  2. Thay thế hàm handleSearchAll bằng mã sau:
    // 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;
      }
    };
    

Điểm chính cần ghi nhớ:

  • handleSearchAll: Hàm này sử dụng truy vấn searchAll để tìm kiếm dựa trên dữ liệu đầu vào của người dùng, lọc kết quả theo các tham số như năm, điểm xếp hạng, thể loại và kết quả trùng khớp một phần văn bản.

Xem ví dụ thực tế

Chuyển đến trang "Tìm kiếm nâng cao" trên thanh điều hướng trong ứng dụng web. Giờ đây, bạn có thể tìm kiếm phim, diễn viên và bài đánh giá bằng nhiều bộ lọc và thông tin đầu vào, nhận kết quả tìm kiếm chi tiết và phù hợp.

10. Không bắt buộc: Triển khai lên Google Cloud (bắt buộc phải có thông tin thanh toán)

Giờ đây, khi bạn đã hoàn tất quá trình lặp lại phát triển cục bộ, đã đến lúc triển khai giản đồ, dữ liệu và truy vấn cho máy chủ. Bạn có thể thực hiện việc này bằng cách sử dụng tiện ích Firebase Data Connect VS Code hoặc Firebase CLI.

Nâng cấp gói giá Firebase

Để tích hợp Firebase Data Connect với Cloud SQL cho PostgreSQL, dự án Firebase của bạn cần sử dụng gói thanh toán theo mức sử dụng (Blaze), tức là dự án được liên kết với một tài khoản Google Cloud Billing.

  • Tài khoản Cloud Billing cần có một phương thức thanh toán, chẳng hạn như thẻ tín dụng.
  • Nếu bạn mới sử dụng Firebase và Google Cloud, hãy kiểm tra xem bạn có đủ điều kiện nhận khoản tín dụng trị giá 300 USD và tài khoản Cloud Billing dùng thử miễn phí hay không.
  • Nếu bạn tham gia lớp học lập trình này trong một sự kiện, hãy hỏi người tổ chức xem có khoản tín dụng Google Cloud nào không.

Để nâng cấp dự án lên gói Blaze, hãy làm theo các bước sau:

  1. Trong bảng điều khiển của Firebase, hãy chọn nâng cấp gói.
  2. Chọn gói Blaze. Làm theo hướng dẫn trên màn hình để liên kết tài khoản Cloud Billing với dự án của bạn.
    Nếu cần tạo tài khoản Cloud Billing trong quá trình nâng cấp này, bạn có thể cần quay lại quy trình nâng cấp trong bảng điều khiển Firebase để hoàn tất quá trình nâng cấp.

Kết nối ứng dụng web với dự án Firebase

  1. Đăng ký ứng dụng web trong dự án Firebase bằng bảng điều khiển của Firebase:
    1. Mở dự án của bạn, rồi nhấp vào Thêm ứng dụng.
    2. Bỏ qua phần thiết lập SDK và cấu hình hiện tại, nhưng hãy nhớ sao chép đối tượng firebaseConfig đã tạo.
    7030822793e4d75b.png
  2. Thay thế firebaseConfig hiện có trong app/src/lib/firebase.tsx bằng cấu hình bạn vừa sao chép từ bảng điều khiển 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"
    };
    
  3. Tạo ứng dụng web: Quay lại VS Code, trong thư mục app, hãy sử dụng Vite để tạo ứng dụng web nhằm lưu trữ quá trình triển khai:
    cd app
    npm run build
    

Thiết lập tính năng Xác thực Firebase trong dự án Firebase

  1. Thiết lập Xác thực Firebase bằng tính năng Đăng nhập bằng Google.62af2f225e790ef6.png
  2. (Không bắt buộc) Cho phép các miền cho Xác thực Firebase bằng bảng điều khiển Firebase (ví dụ: http://127.0.0.1).
    1. Trong phần cài đặt Xác thực, hãy chuyển đến Miền được uỷ quyền.
    2. Nhấp vào "Thêm miền" rồi thêm miền địa phương của bạn vào danh sách.

c255098f12549886.png

Triển khai bằng Giao diện dòng lệnh (CLI) của Firebase

  1. Trong dataconnect/dataconnect.yaml, hãy đảm bảo rằng mã nhận dạng thực thể, cơ sở dữ liệu và mã nhận dạng dịch vụ khớp với dự án của bạn:
    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"]
    
  2. Đảm bảo bạn đã thiết lập Firebase CLI với dự án:
    npm i -g firebase-tools
    firebase login --reauth
    firebase use --add
    
  3. Trong dòng lệnh, hãy chạy lệnh sau để triển khai:
    firebase deploy --only dataconnect,hosting
    
  4. Chạy lệnh sau để so sánh các thay đổi về giản đồ:
    firebase dataconnect:sql:diff
    
  5. Nếu bạn chấp nhận các thay đổi, hãy áp dụng bằng:
    firebase dataconnect:sql:migrate
    

Phiên bản Cloud SQL cho PostgreSQL sẽ được cập nhật bằng giản đồ và dữ liệu đã triển khai cuối cùng. Bạn có thể theo dõi trạng thái trong bảng điều khiển của Firebase.

Bây giờ, bạn có thể xem ứng dụng của mình trực tiếp tại your-project.web.app/. Ngoài ra, bạn có thể nhấp vào Run (Production) (Chạy (Bản chính thức)) trong bảng điều khiển Firebase Data Connect (Kết nối dữ liệu Firebase), giống như cách bạn đã làm với trình mô phỏng cục bộ, để thêm dữ liệu vào môi trường chính thức.

11. Không bắt buộc: Tìm kiếm vectơ bằng Firebase Data Connect (yêu cầu thanh toán)

Trong phần này, bạn sẽ bật tính năng tìm kiếm vectơ trong ứng dụng đánh giá phim bằng Firebase Data Connect. Tính năng này cho phép tìm kiếm dựa trên nội dung, chẳng hạn như tìm phim có nội dung mô tả tương tự bằng cách sử dụng các vectơ nhúng.

Bước này yêu cầu bạn phải hoàn tất bước cuối cùng của lớp học lập trình này để triển khai lên Google Cloud.

4b5aca5a447d2feb.png

Cập nhật giản đồ để thêm các phần nhúng cho một trường

Trong dataconnect/schema/schema.gql, hãy thêm trường descriptionEmbedding vào bảng 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
}

Điểm chính cần ghi nhớ:

  • descriptionEmbedding: Vector @col(size:768): Trường này lưu trữ các nội dung nhúng ngữ nghĩa của nội dung mô tả phim, cho phép tìm kiếm nội dung dựa trên vectơ trong ứng dụng.

Kích hoạt Vertex AI

  1. Làm theo hướng dẫn về điều kiện tiên quyết để thiết lập API Vertex AI từ Google Cloud. Bước này rất quan trọng để hỗ trợ chức năng tạo tính năng nhúng và tìm kiếm vectơ.
  2. Triển khai lại giản đồ để kích hoạt pgvector và tìm kiếm vectơ bằng cách nhấp vào "Triển khai công khai" bằng tiện ích Firebase Data Connect VS Code.

Điền nội dung nhúng vào cơ sở dữ liệu

  1. Mở thư mục dataconnect trong VS Code.
  2. Nhấp vào Run(local) (Chạy (tại máy)) trong optional_vector_embed.gql để điền các nội dung nhúng cho phim vào cơ sở dữ liệu.

b858da780f6ec103.png

Thêm truy vấn tìm kiếm vectơ

Trong dataconnect/movie-connector/queries.gql, hãy thêm truy vấn sau để thực hiện tìm kiếm vectơ:

# 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
  }
}

Điểm chính cần ghi nhớ:

  • compare_embed: Chỉ định mô hình nhúng (textembedding-gecko@003) và văn bản đầu vào ($query) để so sánh.
  • method: Chỉ định phương thức tương đồng (L2) đại diện cho khoảng cách Euclide.
  • within: Giới hạn nội dung tìm kiếm ở những bộ phim có khoảng cách L2 từ 2 trở xuống, tập trung vào những nội dung trùng khớp gần.
  • limit: Giới hạn số lượng kết quả trả về ở mức 5.

Triển khai hàm tìm kiếm vectơ trong ứng dụng

Giờ đây, khi đã thiết lập giản đồ và truy vấn, hãy tích hợp tính năng tìm kiếm vectơ vào lớp dịch vụ của ứng dụng. Bước này cho phép bạn gọi cụm từ tìm kiếm từ ứng dụng web.

  1. Trong app/src/lib/ MovieService.ts, hãy bỏ ghi chú các lệnh nhập sau đây từ SDK, lệnh này sẽ hoạt động như mọi truy vấn khác.
    import {
      searchMovieDescriptionUsingL2similarity,
      SearchMovieDescriptionUsingL2similarityData,
    } from "@movie/dataconnect";
    
  2. Thêm hàm sau để tích hợp tính năng tìm kiếm dựa trên vectơ vào ứng dụng:
    // 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;
      }
    };
    

Điểm chính cần ghi nhớ:

  • searchMoviesByDescription: Hàm này gọi truy vấn searchMovieDescriptionUsingL2similarity, truyền văn bản đầu vào để thực hiện tìm kiếm nội dung dựa trên vectơ.

Xem ví dụ thực tế

Chuyển đến phần "Tìm kiếm vectơ" trong thanh điều hướng rồi nhập các cụm từ như "lãng mạn và hiện đại". Bạn sẽ thấy danh sách phim phù hợp với nội dung bạn đang tìm kiếm. Ngoài ra, bạn có thể truy cập vào trang chi tiết của bất kỳ phim nào rồi xem phần phim tương tự ở cuối trang.

7b71f1c75633c1be.png

12. Kết luận

Xin chúc mừng! Bạn có thể sử dụng ứng dụng web! Nếu bạn muốn chơi với dữ liệu phim của riêng mình, đừng lo, hãy chèn dữ liệu của riêng bạn bằng tiện ích Firebase Data Connect bằng cách mô phỏng các tệp _insert.gql hoặc thêm các tệp đó thông qua ngăn thực thi Data Connect trong VS Code.

Tìm hiểu thêm