Xây dựng bằng Firebase Data Connect (web)

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 này minh hoạ cách Firebase Data Connect đơn giản hoá quy trình tạo các ứ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 giản đồ GraphQL linh hoạt, phù hợp với nhu cầu của một ứ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 tính năng so khớp chuỗi một phần: 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 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 thông tin đầ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ả.

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 tạo ứ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 để bạn xây dựng ứ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 đã sao chép bằng Visual Studio Code. Đây là nơi bạn sẽ xác định giản đồ, viết 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 Firebase Data Connect cho Visual Studio.
    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 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 một 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 xét cơ sở mã khởi đầu

Trong phần này, bạn sẽ khám phá các khía cạnh chính của cơ sở mã khởi đầ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 nên tìm hiểu cấu trúc tổng thể.

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

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

Thư mục dataconnect/

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

  • 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 của bạn
  • connector/mutations.gql: Các thay đổi cần thiết trong ứng dụng của bạn
  • connector/connector.yaml: Tệp cấu hình để tạo SDK

Thư mục app/src/

Chứa logic ứng dụng và 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 của bạn.
  • 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ẽ tự động được tạo 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 Firebase Data Connect và các chỉ thị lược đồ GraphQL. Sau khi được thiết lập, ứng dụng của bạn sẽ sẵn sàng xử lý mọi thứ, từ tìm kiếm những bộ phim được đánh giá cao 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 là mục yêu thích, khám phá những bộ phim tương tự hoặc tìm những bộ 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 quan trọng như tiêu đề, thể loại và thẻ. Ứng dụng dùng các thông tin này cho các lượt tìm kiếm và hồ sơ phim. Loại User theo dõi các hoạt động 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 hoạt hơn. Bảng kết hợp 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 thêm phim vào danh sách yêu thích, nhờ đó ứ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 những 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 riêng biệ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-một với loại Movie. Trong đó có thêm dữ liệu như đạo diễn của bộ 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 đến kiểu 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 biểu thị 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-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 Phim, ngầm tạo khoá ngoại movieId: UUID!.
  • actor: Tham chiếu đến kiểu Actor, ngầm tạo khoá ngoài actorId: UUID!.
  • role: Xác định vai trò của diễn viên trong phim (ví dụ: "main" hoặc "supporting").

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
  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 kết hợp xử lý mối quan hệ nhiều với nhiều giữa người dùng và những bộ phim 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, ngầm tạo khoá ngoại movieId: UUID!.
  • user: Tham chiếu đến loại người dùng, ngầm tạo 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 trong mối quan hệ nhiều-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: Đề cập đến người dùng đã viết bài đánh giá.
  • movie: Tham chiếu đến bộ phim đang được đánh giá.
  • reviewDate: Tự động đặt thành thời điểm bài đánh giá được tạo bằng @default(expr: "request.time").

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

Lược đồ 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 riêng biệt. Ví dụ: trường id trong các loại MovieReview sẽ tự động được điền bằng một UUID khi một bản ghi mới được tạo.

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

5. Lấy 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 các 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. Đến cuối khoá học, ứng dụng của bạn sẽ có thể tìm nạp và hiển thị linh hoạt các bộ phim mới nhất và được đánh giá cao nhất ngay từ cơ sở dữ liệu.

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

  1. Trong VSCode, hãy mở dataconnect/moviedata_insert.gql. Đảm bảo rằng các 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 (cục bộ)) ở đầu tệp. Nhấp vào đây để chèn dữ liệu phim mô phỏng vào cơ sở dữ liệu của bạn.
    e424f75e63bf2e10.png
  3. Kiểm tra thiết bị đầu cuối Data Connect Execution (Thực thi Data Connect) để 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 câu hỏi cơ bản về ListMovies trong phần bình luận:
    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ả các bộ phim và thông tin chi tiết của chúng (ví dụ: id, title, releaseYear). Tuy nhiên, truy vấn này không sắp xếp các bộ phim.
  2. Thay thế truy vấn ListMovies hiện có bằng truy vấn sau để thêm các lựa 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 vào 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 các 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. Các trình mô phỏng Firebase Data Connect tạo ra các SDK dựa trên thông tin trong các 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 của mình.

  1. Trong MovieService (app/src/lib/MovieService.tsx), hãy xoá dấu nhận xét câu lệnh nhập ở trên cùng:
    import { listMovies, ListMoviesData, OrderDirection } from "@movie/dataconnect";
    
    Hàm listMovies, kiểu phản hồi ListMoviesData và enum OrderDirection đều là các SDK do trình mô phỏng Firebase Data Connect tạo 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 đoạn 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: Một hàm được tạo tự động, gọi truy vấn listMovies để truy xuất danh sách phim. Bạn có thể sắp xếp theo mức phân loại 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 bộ phim hàng đầu và mới nhất trên trang chủ của ứng dụng.

Ví dụ thực tế

Tải lại ứng dụng web để xem truy vấn đang hoạt động. Giờ đây, trang chủ sẽ hiển thị danh sách phim một cách linh hoạt, tìm nạp dữ liệu trực tiếp từ cơ sở dữ liệu cục bộ của bạn. Bạn sẽ thấy những bộ phim mới nhất và được xếp hạng cao nhất xuất hiện liền mạch, phản ánh dữ liệu mà 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 diễn viên bằng cách sử dụng mã nhận dạng duy nhất của họ. Điều 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 kết hợp các bảng 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 của bạ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 cụm từ tìm kiếm.

Đ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 duy nhất từ bảng Movies hoặc Actors.
  • _on_: Thao tác này 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 sẽ tìm nạp tất cả các bài đánh giá liên quan đến một bộ phim cụ thể.
  • _via_: Dùng để điều hướng mối quan hệ nhiều với nhiều thông qua bảng kết hợp. Ví dụ: actors_via_MovieActor truy cập vào loại Actor thông qua bảng kết hợp MovieActor và điều kiện where sẽ lọc diễn viên dựa trên vai trò của họ (ví dụ: "chính" hoặc "phụ").

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 (cục bộ)) cho GetMovieById để truy xuất thông tin chi tiết về "Quantum Paradox" (Nghịch lý lượng tử) (phim giả mà mã nhận dạng ở trên liên quan đến).

1b08961891e44da2.png

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

  1. Trong MovieService (app/src/lib/MovieService.tsx), hãy xoá dấu nhận xét 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.

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á – 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ý quy trình 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 để trực tiếp truy xuất hoặc chèn dữ liệu người dùng vào Firebase DataConnect, đảm bảo việc quản lý người dùng an toàn trong ứng dụng của bạn.

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 hiện tại đã xác thực:
    # 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 cung cấp trực tiếp, chứ không phải do người dùng hoặc ứng dụng cung cấp, giúp tă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.
  • _on_ trường: Các trường này đại diện cho các bảng kết hợp:
    • 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à yêu thích, bao gồm cả thông tin chi tiết như genre, releaseYear, ratingmetadata.

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

  1. Trong MovieService (app/src/lib/MovieService.tsx), hãy bỏ chú thí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 đoạn 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, thao tác này 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 truy vấn getCurrentUser. Truy vấn này sẽ truy xuất các bài đánh giá và phim yêu thích của người dùng.

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, bảng này sẽ trống, nhưng bạn đã thiết lập cơ sở để xử lý dữ liệu dành riêng cho người dùng trong ứng dụng của mình.

8. Triển khai các 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 yêu thích và để 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 một bộ 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 cung cấp trực tiếp, đảm bảo rằng chỉ dữ liệu của người dùng đã xác thực mới được truy cập hoặc sửa đổi.

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 kết hợp 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 các truy vấn trong ứng dụng web

  1. Trong MovieService (app/src/lib/MovieService.tsx), hãy xoá dấu nhận xét 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 đoạn 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 này để 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.

Ví dụ thực tế

Giờ đây, bạn có thể thêm 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 các 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 nhập dữ liệu theo cách thủ công.

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

  1. Trong MovieService (app/src/lib/MovieService.tsx), hãy xoá dấu nhận xét 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 một bài đánh giá cho bộ phim đã chỉ định, liên kết một cách an toàn bài đánh giá đó 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 của người dùng đã xác thực.

Ví dụ thực tế

Giờ đây, người dùng có thể viết bài đánh giá cho phim trên trang chi tiết về phim. Họ cũng có thể xem và xoá bài đánh giá trên trang hồ sơ của mình, giúp họ 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 khớp văn bản một phần

Trong phần này, bạn sẽ triển khai các chức 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 dải xếp hạng và năm phát hành, lọc theo thể loại và thẻ, thực hiện so khớp văn bản một phầ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 chức 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 duy nhất, cho phép lọc nội dung tìm kiếm theo một số trường như releaseYear, ratinggenre.
  • Toán tử contains: Tìm kiếm các phần văn bản khớp trong các trường. Trong truy vấn này, hệ thống sẽ tìm các kết quả 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á) đều 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 các truy vấn trong ứng dụng web

  1. Trong MovieService (app/src/lib/MovieService.tsx), hãy xoá dấu nhận xét các lệnh nhập sau:
    import { searchAll, SearchAllData } from "@movie/dataconnect";
    
  2. Thay thế hàm handleSearchAll bằng đoạn 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 để thực hiện tìm kiếm dựa trên thông tin đầ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.

Ví dụ thực tế

Chuyển đến trang "Tìm kiếm nâng cao" trong thanh điều hướng của ứ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, từ đó nhận được 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 Cloud (bắt buộc phải có thông tin thanh toán)

Giờ đây, bạn đã hoàn tất quá trình phát triển cục bộ, đã đến lúc triển khai giản đồ, dữ liệu và truy vấn của bạn lên 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á của 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 giá trả theo mức sử dụng (Blaze). Tức là dự án đó phải được liên kết với một tài khoản thanh toán trên Cloud.

Để 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 một tài khoản thanh toán trên Cloud với dự án của bạn.
    Nếu cần tạo một tài khoản thanh toán trên Cloud 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 của bạn 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. Tạm thời bỏ qua chế độ thiết lập SDK và chế độ thiết lập cấu hình, nhưng 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 mà bạn vừa sao chép từ bảng điều khiển của 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: Trong VS Code, trong thư mục app, hãy dùng Vite để tạo ứng dụng web cho việc triển khai lưu trữ:
    cd app
    npm run build
    

Thiết lập 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 của Firebase (ví dụ: http://127.0.0.1).
    1. Trong phần cài đặt Xác thực, hãy chuyển đến phần Miền được uỷ quyền.
    2. Nhấp vào "Thêm miền" rồi thêm miền cục bộ 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 phiên bản, 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 cho dự án của mình:
    npm i -g firebase-tools
    firebase login --reauth
    firebase use --add
    
  3. Trong thiết bị đầu cuối, hãy chạy lệnh sau để triển khai:
    firebase deploy --only dataconnect,hosting
    
  4. Chạy lệnh này để 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 này, hãy áp dụng bằng cách:
    firebase dataconnect:sql:migrate
    

Phiên bản Cloud SQL cho PostgreSQL của bạn sẽ được cập nhật bằng giản đồ và dữ liệu được 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.

Giờ đây, bạn có thể xem ứng dụng của mình hoạt động 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 (Sản xuất)) trong bảng điều khiển Firebase Data Connect, giống như khi bạn sử dụng trình mô phỏng cục bộ, để thêm dữ liệu vào môi trường sản xuất.

11. Không bắt buộc: Tìm kiếm vectơ bằng Firebase Data Connect (cần có thông tin 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 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 mục 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 thông tin 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 của bạn.

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 Vertex AI API từ Google Cloud. Bước này là cần thiết để hỗ trợ chức năng tạo mục 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 cho sản xuất" bằng tiện ích Firebase Data Connect VS Code.

Điền các mục 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 (cục bộ)) trong optional_vector_embed.gql để điền vào cơ sở dữ liệu của bạn bằng các mục nhúng cho phim.

b858da780f6ec103.png

Thêm cụm từ 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 tự (L2), biểu thị khoảng cách Euclide.
  • within: Giới hạn phạm vi tìm kiếm ở những phim có khoảng cách L2 từ 2 trở xuống, tập trung vào những nội dung khớp gần nhất.
  • limit: Giới hạn số lượng kết quả trả về là 5.

Triển khai chức năng tìm kiếm vectơ trong ứng dụng của bạn

Giờ đây, khi lược đồ và truy vấn đã được thiết lập, 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 của mình.

  1. Trong app/src/lib/ MovieService.ts, hãy xoá dấu nhận xét khỏi các nội dung nhập sau đây từ SDK. Thao tác 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ơ.

Ví dụ thực tế

Chuyển đến phần "Vector Search" (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 các bộ phim phù hợp với nội dung bạn đang tìm kiếm, hoặc truy cập vào trang thông tin chi tiết của bất kỳ bộ phim nào và 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ày! Nếu bạn muốn sử dụng dữ liệu phim của riêng mình, đừng lo lắng, hãy chèn dữ liệu của riêng bạn bằng cách sử dụng tiện ích Firebase Data Connect bằng cách mô phỏng các tệp _insert.gql hoặc thêm chúng thông qua ngăn thực thi Data Connect trong VS Code.

Tìm hiểu thêm