الإنشاء باستخدام Firebase Data Connect (على الويب)

1. قبل البدء

تطبيق FriendlyMovies

في هذا الدرس العملي، ستدمج Firebase Data Connect مع قاعدة بيانات Cloud SQL لإنشاء تطبيق ويب لمراجعة الأفلام. يوضّح التطبيق المكتمل كيف يسهّل Firebase Data Connect عملية إنشاء تطبيقات تستند إلى SQL. يتضمّن هذا التطبيق الميزات التالية:

  • المصادقة: يمكنك تنفيذ مصادقة مخصّصة لطلبات البحث والتعديلات في تطبيقك، ما يضمن تفاعل المستخدمين المصرَّح لهم فقط مع بياناتك.
  • مخطط GraphQL: يمكنك إنشاء بنى البيانات وإدارتها باستخدام مخطط GraphQL مرن ومصمّم خصيصًا لتلبية احتياجات تطبيق الويب الخاص بمراجعات الأفلام.
  • استعلامات SQL وعمليات التعديل: يمكنك استرداد البيانات وتعديلها وإدارتها في Cloud SQL باستخدام الاستعلامات وعمليات التعديل المستندة إلى GraphQL.
  • البحث المتقدّم مع مطابقة السلسلة الجزئية: استخدِم الفلاتر وخيارات البحث للعثور على أفلام استنادًا إلى حقول مثل العنوان أو الوصف أو العلامات.
  • (اختياري) دمج البحث المتّجه: أضِف وظيفة البحث عن المحتوى باستخدام البحث المتّجه في Firebase Data Connect لتقديم تجربة مستخدم غنية استنادًا إلى المدخلات والإعدادات المفضّلة.

المتطلبات الأساسية

ستحتاج إلى فهم أساسي للغة JavaScript.

ما ستتعلمه

  • إعداد Firebase Data Connect باستخدام المحاكيات المحلية
  • تصميم مخطط بيانات باستخدام Data Connect وGraphQL
  • كتابة واختبار طلبات بحث وعمليات تغيير مختلفة لتطبيق مراجعة أفلام
  • تعرَّف على كيفية إنشاء حزمة تطوير البرامج (SDK) واستخدامها في التطبيق من خلال ميزة "ربط البيانات في Firebase".
  • نشر المخطط وإدارة قاعدة البيانات بكفاءة

المتطلبات

  • Git
  • Visual Studio Code
  • ثبِّت Node.js باستخدام nvm-windows (في نظام التشغيل Windows) أو nvm (في نظام التشغيل macOS أو Linux).
  • إذا لم يسبق لك إنشاء مشروع على Firebase، أنشئ مشروعًا في وحدة تحكّم Firebase.
  • (اختياري) للبحث المتّجه، يمكنك ترقية مشروعك إلى خطة أسعار Blaze للدفع حسب الاستخدام

2. إعداد بيئة التطوير

ستساعدك هذه المرحلة من الدرس العملي في إعداد البيئة لبدء إنشاء تطبيق مراجعة الأفلام باستخدام Firebase Data Connect.

  1. أنشئ نسخة طبق الأصل من مستودع المشروع وثبِّت التبعيات المطلوبة:
    git clone https://github.com/firebaseextended/codelab-dataconnect-web
    cd codelab-dataconnect-web
    cd ./app && npm i
    npm run dev
    
  2. بعد تنفيذ هذه الأوامر، افتح http://localhost:5173 في المتصفّح للاطّلاع على تطبيق الويب الذي يتم تشغيله محليًا. سيكون هذا بمثابة الواجهة الأمامية لإنشاء تطبيق مراجعة الأفلام والتفاعل مع ميزاته.93f6648a2532c606.png
  3. افتح مجلد codelab-dataconnect-web المستنسخ باستخدام Visual Studio Code. هذا هو المكان الذي ستحدّد فيه المخطط وتكتب طلبات البحث وتختبر وظائف التطبيق.
  4. لاستخدام ميزات Data Connect، ثبِّت إضافة Firebase Data Connect في Visual Studio.
    بدلاً من ذلك، يمكنك تثبيت الإضافة من Visual Studio Code Marketplace أو البحث عنها في VS Code.b03ee38c9a81b648.png
  5. افتح مشروعًا جديدًا في Firebase أو أنشئ مشروعًا جديدًا في وحدة تحكّم Firebase.
  6. ربط مشروعك على Firebase بإضافة Firebase Data Connect VSCode. في الإضافة، اتّبِع الخطوات التالية:
    1. انقر على الزر تسجيل الدخول.
    2. انقر على ربط مشروع Firebase واختَر مشروعك على Firebase.
    4bb2fbf8f9fac29b.png
  7. ابدأ محاكيات Firebase باستخدام إضافة Firebase Data Connect في VS Code:
    انقر على بدء المحاكيات، ثم تأكَّد من أنّ المحاكيات تعمل في الوحدة الطرفية.6d3d95f4cb708db1.png

3- مراجعة قاعدة الرموز البرمجية الأولية

في هذا القسم، سنتعرّف على المجالات الرئيسية لقاعدة الرموز الأولية للتطبيق. على الرغم من أنّ التطبيق لا يتضمّن بعض الوظائف، إلا أنّه مفيد لفهم البنية العامة.

بنية المجلدات والملفات

تقدّم الأقسام الفرعية التالية نظرة عامة على بنية المجلدات والملفات في التطبيق.

دليل dataconnect/

يحتوي على إعدادات Firebase Data Connect والموصلات (التي تحدّد طلبات البحث والتعديلات) وملفات المخطط.

  • schema/schema.gql: تحدّد مخطط GraphQL
  • connector/queries.gql: طلبات البحث المطلوبة في تطبيقك
  • connector/mutations.gql: التغييرات المطلوبة في تطبيقك
  • connector/connector.yaml: ملف الإعداد لإنشاء حزمة SDK

دليل app/src/

يحتوي على منطق التطبيق والتفاعل مع Firebase Data Connect.

  • firebase.ts: إعدادات الربط بتطبيق Firebase في مشروعك على Firebase
  • lib/dataconnect-sdk/: يحتوي على حزمة SDK التي تم إنشاؤها. يمكنك تعديل موقع إنشاء حزمة SDK في ملف connector/connector.yaml وسيتم إنشاء حِزم SDK تلقائيًا في أي وقت تحدّد فيه طلب بحث أو تغييرًا.

4. تحديد مخطط لمراجعات الأفلام

في هذا القسم، ستحدّد بنية الكيانات الرئيسية في تطبيق الأفلام والعلاقات بينها في مخطط. يتم ربط الكيانات، مثل Movie وUser وActor وReview، بجداول قواعد البيانات، مع إنشاء علاقات باستخدام Firebase Data Connect وتوجيهات مخطط GraphQL. بعد إعداد هذه الميزة، سيصبح تطبيقك جاهزًا للتعامل مع كل شيء، بدءًا من البحث عن الأفلام الأعلى تقييمًا والفلترة حسب النوع، وصولاً إلى السماح للمستخدمين بترك مراجعات أو وضع علامة على الأفلام المفضّلة أو استكشاف أفلام مشابهة أو العثور على أفلام مقترَحة استنادًا إلى إدخال نصي من خلال البحث المتّجه.

العناصر والعلاقات الأساسية

يحتوي النوع Movie على تفاصيل أساسية، مثل العنوان والنوع والعلامات، التي يستخدمها التطبيق في عمليات البحث وملفات الأفلام. يتتبّع النوع User تفاعلات المستخدمين، مثل المراجعات وقوائم المفضّلة. Reviews ربط المستخدمين بالأفلام، ما يتيح للتطبيق عرض التقييمات والملاحظات التي ينشئها المستخدمون

تساهم العلاقات بين الأفلام والممثلين والمستخدمين في جعل التطبيق أكثر ديناميكية. يساعد جدول الربط MovieActor في عرض تفاصيل فريق التمثيل وأعمال الممثلين السينمائية. يتيح النوع FavoriteMovie للمستخدمين إضافة الأفلام إلى قائمة المفضّلة، ما يسمح للتطبيق بعرض قائمة مفضّلة مخصّصة وإبراز الأفلام الرائجة.

إعداد جدول Movie

يحدّد النوع Movie البنية الرئيسية لعنصر الفيلم، بما في ذلك الحقول مثل title وgenre وreleaseYear وrating.

انسخ مقتطف الرمز وألصِقه في ملف dataconnect/schema/schema.gql:

type Movie
  @table {
  id: UUID! @default(expr: "uuidV4()")
  title: String!
  imageUrl: String!
  releaseYear: Int
  genre: String
  rating: Float
  description: String
  tags: [String]
}

الأفكار الرئيسية:

  • id: معرّف فريد لكل فيلم، يتم إنشاؤه باستخدام @default(expr: "uuidV4()").

إعداد جدول MovieMetadata

يُنشئ النوع MovieMetadata علاقة فردية مع النوع Movie. ويتضمّن بيانات إضافية، مثل مخرج الفيلم.

انسخ مقتطف الرمز وألصِقه في ملف dataconnect/schema/schema.gql:

type MovieMetadata
  @table {
  # @ref creates a field in the current table (MovieMetadata)
  # It is a reference that holds the primary key of the referenced type
  # In this case, @ref(fields: "movieId", references: "id") is implied
  movie: Movie! @ref
  # movieId: UUID <- this is created by the above @ref
  director: String
}

الأفكار الرئيسية:

  • فيلم! ‫@ref: يشير إلى النوع Movie، ما يؤدي إلى إنشاء علاقة مفتاح خارجي.

إعداد جدول Actor

انسخ مقتطف الرمز وألصِقه في ملف dataconnect/schema/schema.gql:

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

يمثّل النوع Actor ممثلاً في قاعدة بيانات الأفلام، حيث يمكن أن يكون كل ممثل جزءًا من أفلام متعددة، ما يشكّل علاقة متعددة إلى متعددة.

إعداد جدول MovieActor

انسخ مقتطف الرمز وألصِقه في ملف dataconnect/schema/schema.gql:

type MovieActor @table(key: ["movie", "actor"]) {
  # @ref creates a field in the current table (MovieActor) that holds the primary key of the referenced type
  # In this case, @ref(fields: "id") is implied
  movie: Movie!
  # movieId: UUID! <- this is created by the implied @ref, see: implicit.gql

  actor: Actor!
  # actorId: UUID! <- this is created by the implied  @ref, see: implicit.gql

  role: String! # "main" or "supporting"
}

الأفكار الرئيسية:

  • الفيلم: يشير إلى نوع الفيلم، ويُنشئ ضمنيًا مفتاحًا خارجيًا movieId: UUID!.
  • actor: يشير إلى نوع "المُنفِّذ"، ويُنشئ ضمنيًا مفتاحًا خارجيًا actorId: UUID!.
  • role: تحدّد دور الممثل في الفيلم (مثلاً "main" أو "supporting").

إعداد جدول User

يحدّد النوع User كيان مستخدم يتفاعل مع الأفلام من خلال ترك مراجعات أو إضافة الأفلام إلى المفضّلة.

انسخ مقتطف الرمز وألصِقه في ملف 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
}

إعداد جدول FavoriteMovie

النوع FavoriteMovie هو جدول ربط يتعامل مع علاقات متعددة إلى متعددة بين المستخدمين وأفلامهم المفضّلة. يربط كل جدول User بـ Movie.

انسخ مقتطف الرمز وألصِقه في ملف dataconnect/schema/schema.gql:

type FavoriteMovie
  @table(name: "FavoriteMovies", singular: "favorite_movie", plural: "favorite_movies", key: ["user", "movie"]) {
  # @ref is implicit
  user: User!
  movie: Movie!
}

الأفكار الرئيسية:

  • الفيلم: يشير إلى نوع الفيلم، وينشئ ضمنيًا مفتاحًا خارجيًا movieId: UUID!.
  • user: يشير إلى نوع المستخدم، وينشئ ضمنيًا مفتاحًا خارجيًا userId: UUID!.

إعداد جدول Review

يمثّل النوع Review كيان المراجعة ويربط النوعَين User وMovie في علاقة متعددة إلى متعددة (يمكن لمستخدم واحد ترك العديد من المراجعات، ويمكن أن يتضمّن كل فيلم العديد من المراجعات).

انسخ مقتطف الرمز وألصِقه في ملف dataconnect/schema/schema.gql:

type Review @table(name: "Reviews", key: ["movie", "user"]) {
  id: UUID! @default(expr: "uuidV4()")
  user: User!
  movie: Movie!
  rating: Int
  reviewText: String
  reviewDate: Date! @default(expr: "request.time")
}

الأفكار الرئيسية:

  • المستخدم: يشير إلى المستخدم الذي أضاف المراجعة.
  • movie: تشير إلى الفيلم الذي تتم مراجعته.
  • reviewDate: يتم ضبطها تلقائيًا على الوقت الذي تم فيه إنشاء المراجعة باستخدام @default(expr: "request.time").

الحقول والقيم التلقائية التي يتم إنشاؤها تلقائيًا

يستخدم المخطط تعابير مثل @default(expr: "uuidV4()") لإنشاء معرّفات فريدة وطوابع زمنية تلقائيًا. على سبيل المثال، يتم تلقائيًا ملء الحقل id في النوعَين Movie وReview بمعرّف فريد عالمي (UUID) عند إنشاء سجلّ جديد.

بعد تحديد المخطط، سيصبح تطبيق الأفلام الخاص بك مزوّدًا بأساس متين لبنية البيانات والعلاقات.

5- استرداد أهم وأحدث الأفلام

تطبيق FriendlyMovies

في هذا القسم، ستُدرج بيانات أفلام تجريبية في المحاكيات المحلية، ثم ستنفّذ أدوات الربط (طلبات البحث) ورمز TypeScript لاستدعاء أدوات الربط هذه في تطبيق الويب. في النهاية، سيتمكّن تطبيقك من استرداد وعرض الأفلام الأعلى تقييمًا والأحدث مباشرةً من قاعدة البيانات.

إدراج بيانات وهمية للأفلام والممثلين والمراجعات

  1. في VSCode، افتح dataconnect/moviedata_insert.gql. تأكَّد من أنّ المحاكيات في إضافة Firebase Data Connect تعمل.
  2. من المفترض أن يظهر لك الزر تشغيل (محلي) في أعلى الملف. انقر على هذا الزر لإدراج بيانات الأفلام التجريبية في قاعدة البيانات.
    e424f75e63bf2e10.png
  3. راجِع نافذة تنفيذ Data Connect للتأكّد من أنّه تمت إضافة البيانات بنجاح.
    e0943d7704fb84ea.png

تنفيذ الموصّل

  1. فتح dataconnect/movie-connector/queries.gql ستجد استعلامًا أساسيًا في ListMovies في التعليقات:
    query ListMovies @auth(level: PUBLIC) {
      movies {
        id
        title
        imageUrl
        releaseYear
        genre
        rating
        tags
        description
      }
    }
    
    يجلب هذا الطلب جميع الأفلام وتفاصيلها (مثل id وtitle وreleaseYear)، ولكنّه لا يرتب الأفلام.
  2. استبدِل طلب البحث 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
      }
    }
    
  3. انقر على الزر تشغيل (محلي) لتنفيذ طلب البحث في قاعدة البيانات المحلية. يمكنك أيضًا إدخال متغيّرات طلب البحث في لوحة الإعداد قبل التشغيل.
    c4d947115bb11b16.png

الأفكار الرئيسية:

  • movies(): حقل طلب بحث GraphQL لاسترداد بيانات الأفلام من قاعدة البيانات
  • orderByRating: مَعلمة لترتيب الأفلام حسب التقييم (تصاعديًا أو تنازليًا).
  • استبدِل orderByReleaseYear بما يلي:مَعلمة لترتيب الأفلام حسب سنة الإصدار (تصاعديًا أو تنازليًا).
  • استبدِل limit بـ: تقيّد هذه السمة عدد الأفلام التي يتم عرضها.

دمج طلبات البحث في تطبيق الويب

في هذا الجزء من الدرس العملي، ستستخدم طلبات البحث المحدّدة في القسم السابق في تطبيق الويب. وتنشئ محاكيات Firebase Data Connect حِزم 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";
    
    الدالة listMovies ونوع الاستجابة ListMoviesData والقيمة الثابتة OrderDirection هي جميعها حِزم تطوير برامج (SDK) أنشأتها محاكيات Firebase Data Connect استنادًا إلى المخطط والاستعلامات التي حدّدتها سابقًا .
  2. استبدِل الدالتَين handleGetTopMovies وhandleGetLatestMovies بالرمز التالي:
    // Fetch top-rated movies
    export const handleGetTopMovies = async (
      limit: number
    ): Promise<ListMoviesData["movies"] | null> => {
      try {
        const response = await listMovies({
          orderByRating: OrderDirection.DESC,
          limit,
        });
        return response.data.movies;
      } catch (error) {
        console.error("Error fetching top movies:", error);
        return null;
      }
    };
    
    // Fetch latest movies
    export const handleGetLatestMovies = async (
      limit: number
    ): Promise<ListMoviesData["movies"] | null> => {
      try {
        const response = await listMovies({
          orderByReleaseYear: OrderDirection.DESC,
          limit,
        });
        return response.data.movies;
      } catch (error) {
        console.error("Error fetching latest movies:", error);
        return null;
      }
    };
    

الأفكار الرئيسية:

  • listMovies: هي دالة يتم إنشاؤها تلقائيًا وتستدعي طلب البحث listMovies لاسترداد قائمة بالأفلام. ويتضمّن خيارات للترتيب حسب التقييم أو سنة الإصدار والحدّ من عدد النتائج.
  • ListMoviesData: هو نوع النتيجة المستخدَم لعرض أفضل 10 أفلام وأحدثها على الصفحة الرئيسية للتطبيق.

مثال عملي

أعِد تحميل تطبيق الويب للاطّلاع على طلب البحث أثناء التنفيذ. تعرض الصفحة الرئيسية الآن قائمة الأفلام بشكل ديناميكي، حيث يتم استرداد البيانات مباشرةً من قاعدة البيانات المحلية. ستظهر لك الأفلام الأعلى تقييمًا والأحدث بسلاسة، ما يعكس البيانات التي أعددتها للتو.

6. عرض تفاصيل الأفلام والممثلين

في هذا القسم، ستنفّذ وظيفة استرداد معلومات تفصيلية عن فيلم أو ممثل باستخدام المعرّفات الفريدة الخاصة بهما. ولا يقتصر ذلك على استرداد البيانات من الجداول الخاصة بها، بل يشمل أيضًا ربط الجداول ذات الصلة لعرض تفاصيل شاملة، مثل مراجعات الأفلام وأعمال الممثلين السينمائية.

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
        }
      }
    }
    
  3. احفظ التغييرات وراجِع طلبات البحث.

الأفكار الرئيسية:

  • movie()/actor(): حقول طلب بحث GraphQL لاسترداد فيلم أو ممثل واحد من الجدول Movies أو Actors
  • _on_: يتيح ذلك الوصول المباشر إلى الحقول من نوع مرتبط يتضمّن علاقة مفتاح خارجي. على سبيل المثال، يؤدي طلب البحث reviews_on_movie إلى جلب جميع المراجعات المرتبطة بفيلم معيّن.
  • _via_: تُستخدَم للتنقّل بين علاقات متعددة إلى متعددة من خلال جدول ربط. على سبيل المثال، يصل actors_via_MovieActor إلى النوع Actor من خلال جدول الربط MovieActor، ويتم فلترة الممثلين استنادًا إلى دورهم (على سبيل المثال، "رئيسي" أو "ثانوي") باستخدام الشرط where.

اختبار طلب البحث عن طريق إدخال بيانات وهمية

  1. في لوحة تنفيذ Data Connect، يمكنك اختبار طلب البحث عن طريق إدخال معرّفات وهمية، مثل:
    {"id": "550e8400-e29b-41d4-a716-446655440000"}
    
  2. انقر على تشغيل (محلي) لـ GetMovieById لاسترداد التفاصيل حول "Quantum Paradox" (الفيلم التجريبي الذي يرتبط به رقم التعريف أعلاه).

1b08961891e44da2.png

دمج طلبات البحث في تطبيق الويب

  1. في MovieService (app/src/lib/MovieService.tsxأزِل التعليق عن عمليات الاستيراد التالية:
    import { getMovieById, GetMovieByIdData } from "@movie/dataconnect";
    import { GetActorByIdData, getActorById } from "@movie/dataconnect";
    
  2. استبدِل الدالتَين handleGetMovieById وhandleGetActorById بالرمز البرمجي التالي:
    // Fetch movie details by ID
    export const handleGetMovieById = async (
      movieId: string
    ) => {
      try {
        const response = await getMovieById({ id: movieId });
        if (response.data.movie) {
          return response.data.movie;
        }
        return null;
      } catch (error) {
        console.error("Error fetching movie:", error);
        return null;
      }
    };
    
    // Calling generated SDK for GetActorById
    export const handleGetActorById = async (
      actorId: string
    ): Promise<GetActorByIdData["actor"] | null> => {
      try {
        const response = await getActorById({ id: actorId });
        if (response.data.actor) {
          return response.data.actor;
        }
        return null;
      } catch (error) {
        console.error("Error fetching actor:", error);
        return null;
      }
    };
    

الأفكار الرئيسية:

  • getMovieById / getActorById: هذه دوال يتم إنشاؤها تلقائيًا وتستدعي طلبات البحث التي حدّدتها، ما يؤدي إلى استرداد معلومات تفصيلية عن فيلم أو ممثل معيّن.
  • GetMovieByIdData / GetActorByIdData: هذان النوعان من النتائج يُستخدمان لعرض تفاصيل الأفلام والممثلين في التطبيق.

مثال عملي

الآن، انتقِل إلى الصفحة الرئيسية لتطبيق الويب. انقر على فيلم، وستتمكّن من الاطّلاع على جميع تفاصيله، بما في ذلك الممثلون والمراجعات، وهي معلومات يتم استخلاصها من جداول ذات صلة. وبالمثل، سيؤدي النقر على ممثل إلى عرض الأفلام التي شارك فيها.

7. التعامل مع مصادقة المستخدم

في هذا القسم، ستنفّذ وظائف تسجيل الدخول والخروج للمستخدمين باستخدام خدمة "المصادقة" من Firebase. ستستخدم أيضًا بيانات Firebase Authentication لاسترداد بيانات المستخدم أو إدراجها أو تعديلها مباشرةً في Firebase DataConnect، ما يضمن إدارة المستخدمين بشكل آمن داخل تطبيقك.

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 مباشرةً، وليس المستخدم أو التطبيق، ما يضيف طبقة أمان إضافية من خلال ضمان التعامل مع معرّف المستخدم بشكل آمن وتلقائي.

استرداد المستخدم الحالي

  1. افتح queries.gql في dataconnect/movie-connector/.
  2. أضِف طلب البحث التالي لجلب المستخدم الحالي:
    # Get user by ID
    query GetCurrentUser @auth(level: USER) {
      user(key: { id_expr: "auth.uid" }) {
        id
        username
        reviews: reviews_on_user {
          id
          rating
          reviewDate
          reviewText
          movie {
            id
            title
          }
        }
        favoriteMovies: favorite_movies_on_user {
          movie {
            id
            title
            genre
            imageUrl
            releaseYear
            rating
            description
            tags
            metadata: movieMetadatas_on_movie {
              director
            }
          }
        }
      }
    }
    

الأفكار الرئيسية:

  • auth.uid: يتم استرداد هذا المعرّف مباشرةً من خدمة "مصادقة Firebase"، ما يضمن الوصول الآمن إلى البيانات الخاصة بالمستخدم.
  • حقول _on_: تمثّل هذه الحقول جداول الربط:
    • reviews_on_user: يجلب جميع المراجعات المرتبطة بالمستخدم، بما في ذلك id وtitle الخاصان بالفيلم.
    • favorite_movies_on_user: تسترد هذه السمة جميع الأفلام التي وضع المستخدم علامة عليها كمفضّلة، بما في ذلك معلومات تفصيلية مثل genre وreleaseYear وrating وmetadata.

دمج طلبات البحث في تطبيق الويب

  1. في MovieService (app/src/lib/MovieService.tsx)، أزِل التعليق من أمام عمليات الاستيراد التالية:
    import { upsertUser } from "@movie/dataconnect";
    import { getCurrentUser, GetCurrentUserData } from "@movie/dataconnect";
    
  2. استبدِل الدالتَين 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" في شريط التنقّل. يمكنك تسجيل الدخول باستخدام محاكي "مصادقة Firebase". بعد تسجيل الدخول، انقر على "ملفي الشخصي". سيكون هذا الحقل فارغًا في الوقت الحالي، ولكنّك أعددت الأساس لمعالجة البيانات الخاصة بالمستخدمين في تطبيقك.

8. تنفيذ تفاعلات المستخدمين

في هذا القسم من الدرس العملي، ستنفّذ تفاعلات المستخدمين في تطبيق مراجعات الأفلام، وتحديدًا ستتيح للمستخدمين إدارة أفلامهم المفضّلة وكتابة المراجعات أو حذفها.

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" مباشرةً، ما يضمن عدم الوصول إلى بيانات المستخدم الذي تمّت مصادقته أو تعديلها إلا من خلاله.

التحقّق ممّا إذا كان الفيلم قد تمّت إضافته إلى قائمة الأفلام المفضّلة

  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";
    
  2. استبدِل الدوال handleAddFavoritedMovie وhandleDeleteFavoritedMovie وhandleGetIfFavoritedMovie بالرمز التالي:
    // Add a movie to user's favorites
    export const handleAddFavoritedMovie = async (
      movieId: string
    ): Promise<void> => {
      try {
        await addFavoritedMovie({ movieId });
      } catch (error) {
        console.error("Error adding movie to favorites:", error);
        throw error;
      }
    };
    
    // Remove a movie from user's favorites
    export const handleDeleteFavoritedMovie = async (
      movieId: string
    ): Promise<void> => {
      try {
        await deleteFavoritedMovie({ movieId });
      } catch (error) {
        console.error("Error removing movie from favorites:", error);
        throw error;
      }
    };
    
    // Check if the movie is favorited by the user
    export const handleGetIfFavoritedMovie = async (
      movieId: string
    ): Promise<boolean> => {
      try {
        const response = await getIfFavoritedMovie({ movieId });
        return !!response.data.favorite_movie;
      } catch (error) {
        console.error("Error checking if movie is favorited:", error);
        return false;
      }
    };
    

الأفكار الرئيسية:

  • handleAddFavoritedMovie وhandleDeleteFavoritedMovie: استخدِم عمليات التغيير لإضافة فيلم إلى قائمة الأفلام المفضّلة للمستخدم أو إزالته منها بشكل آمن.
  • handleGetIfFavoritedMovie: تستخدم طلب البحث getIfFavoritedMovie للتحقّق مما إذا كان المستخدم قد وضع علامة "مفضّلة" على فيلم.

مثال عملي

يمكنك الآن إضافة أفلام إلى قائمة الأفلام المفضّلة أو إزالتها منها من خلال النقر على رمز القلب في بطاقات الأفلام وصفحة تفاصيل الفيلم. بالإضافة إلى ذلك، يمكنك الاطّلاع على أفلامك المفضّلة في صفحة ملفك الشخصي.

السماح للمستخدمين بإضافة مراجعات أو حذفها

بعد ذلك، عليك تنفيذ القسم الخاص بإدارة مراجعات المستخدمين في التطبيق.

تنفيذ الموصلات

في mutations.gql (dataconnect/movie-connector/mutations.gql): أضِف التغييرات التالية:

# Add a review for a movie
mutation AddReview($movieId: UUID!, $rating: Int!, $reviewText: String!)
@auth(level: USER) {
  review_insert(
    data: {
      userId_expr: "auth.uid"
      movieId: $movieId
      rating: $rating
      reviewText: $reviewText
      reviewDate_date: { today: true }
    }
  )
}

# Delete a user's review for a movie
mutation DeleteReview($movieId: UUID!) @auth(level: USER) {
  review_delete(key: { userId_expr: "auth.uid", movieId: $movieId })
}

الأفكار الرئيسية:

  • userId_expr: "auth.uid": يضمن ربط المراجعات بالمستخدم الذي تمّت مصادقته.
  • reviewDate_date: { today: true }: يتم إنشاء التاريخ الحالي للمراجعة تلقائيًا باستخدام DataConnect، ما يلغي الحاجة إلى إدخاله يدويًا.

دمج طلبات البحث في تطبيق الويب

  1. في MovieService (app/src/lib/MovieService.tsxأزِل التعليق عن عمليات الاستيراد التالية:
    import { addReview, deleteReview } from "@movie/dataconnect";
    
  2. استبدِل الدالتَين handleAddReview وhandleDeleteReview بالرمز البرمجي التالي:
    // Add a review to a movie
    export const handleAddReview = async (
      movieId: string,
      rating: number,
      reviewText: string
    ): Promise<void> => {
      try {
        await addReview({ movieId, rating, reviewText });
      } catch (error) {
        console.error("Error adding review:", error);
        throw error;
      }
    };
    
    // Delete a review from a movie
    export const handleDeleteReview = async (movieId: string): Promise<void> => {
      try {
        await deleteReview({ movieId });
      } catch (error) {
        console.error("Error deleting review:", error);
        throw error;
      }
    };
    

الأفكار الرئيسية:

  • handleAddReview: يتم استدعاء عملية التغيير addReview لإضافة مراجعة للفيلم المحدّد، مع ربطها بشكل آمن بالمستخدم الذي تمّت مصادقته.
  • handleDeleteReview: تستخدم هذه السمة عملية التغيير deleteReview لإزالة مراجعة فيلم كتبها المستخدم الذي تمّت مصادقته.

مثال عملي

يمكن للمستخدمين الآن كتابة مراجعات للأفلام على صفحة تفاصيل الفيلم. ويمكنهم أيضًا الاطّلاع على مراجعاتهم وحذفها من صفحة ملفهم الشخصي، ما يمنحهم تحكّمًا كاملاً في تفاعلاتهم مع التطبيق.

9. الفلاتر المتقدّمة ومطابقة النص الجزئي

في هذا القسم، ستنفّذ إمكانات بحث متقدّمة، ما يتيح للمستخدمين البحث عن الأفلام استنادًا إلى مجموعة من التقييمات وسنوات الإصدار، والفلترة حسب الأنواع والعلامات، وإجراء مطابقة جزئية للنص في العناوين أو الأوصاف، وحتى الجمع بين فلاتر متعددة للحصول على نتائج أكثر دقة.

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: يجمع بين شروط متعددة في طلب بحث واحد، ما يسمح بفلترة البحث حسب عدة حقول، مثل releaseYear وrating وgenre.
  • عامل التشغيل contains: يبحث عن تطابقات جزئية للنص داخل الحقول. في طلب البحث هذا، يتم البحث عن تطابقات ضمن title أو description أو name أو reviewText.
  • where: تحدّد شروط فلترة البيانات. يستخدم كل قسم (الأفلام والممثلون والمراجعات) عبارة where لتحديد المعايير المحدّدة للبحث.

دمج طلبات البحث في تطبيق الويب

  1. في MovieService (app/src/lib/MovieService.tsxأزِل التعليق عن عمليات الاستيراد التالية:
    import { searchAll, SearchAllData } from "@movie/dataconnect";
    
  2. استبدِل الدالة handleSearchAll بالرمز التالي:
    // Function to perform the search using the query and filters
    export const handleSearchAll = async (
      searchQuery: string,
      minYear: number,
      maxYear: number,
      minRating: number,
      maxRating: number,
      genre: string
    ): Promise<SearchAllData | null> => {
      try {
        const response = await searchAll({
          input: searchQuery,
          minYear,
          maxYear,
          minRating,
          maxRating,
          genre,
        });
    
        return response.data;
      } catch (error) {
        console.error("Error performing search:", error);
        return null;
      }
    };
    

الأفكار الرئيسية:

  • handleSearchAll: تستخدم هذه الدالة طلب البحث searchAll لإجراء بحث استنادًا إلى إدخال المستخدم، مع فلترة النتائج حسب مَعلمات مثل السنة والتقييم والنوع والمطابقات الجزئية للنص.

مثال عملي

انتقِل إلى صفحة "البحث المتقدّم" من شريط التنقّل في تطبيق الويب. يمكنك الآن البحث عن الأفلام والممثلين والمراجعات باستخدام فلاتر ومدخلات مختلفة، والحصول على نتائج بحث مفصّلة ومخصّصة.

10. اختياري: النشر على السحابة الإلكترونية (يجب توفّر الفوترة)

بعد الانتهاء من عملية التطوير المحلية، حان الوقت لنشر المخطط والبيانات والاستعلامات على الخادم. يمكن إجراء ذلك باستخدام إضافة Firebase Data Connect VS Code أو واجهة سطر الأوامر (CLI) في Firebase.

ترقية خطة أسعار Firebase

لدمج Firebase Data Connect مع Cloud SQL for PostgreSQL، يجب أن يكون مشروعك على Firebase ضمن خطة الأسعار "الدفع حسب الاستخدام" (Blaze)، ما يعني أنّه مرتبط بحساب فوترة على السحابة الإلكترونية.

لترقية مشروعك إلى خطة Blaze، اتّبِع الخطوات التالية:

  1. في "وحدة تحكّم Firebase"، اختَر ترقية خطتك.
  2. اختَر خطة Blaze. اتّبِع التعليمات الظاهرة على الشاشة لربط حساب فوترة على Cloud بمشروعك.
    إذا احتجت إلى إنشاء حساب فوترة على Cloud كجزء من عملية الترقية هذه، قد تحتاج إلى الرجوع إلى مسار الترقية في وحدة تحكّم Firebase لإكمال عملية الترقية.

ربط تطبيق الويب بمشروعك على Firebase

  1. سجِّل تطبيق الويب في مشروعك على Firebase باستخدام وحدة تحكّم Firebase:
    1. افتح مشروعك، ثم انقر على إضافة تطبيق.
    2. تجاهَل إعداد حزمة تطوير البرامج (SDK) وإعدادات الضبط في الوقت الحالي، ولكن احرص على نسخ العنصر firebaseConfig الذي تم إنشاؤه.
    7030822793e4d75b.png
  2. استبدِل firebaseConfig الحالي في app/src/lib/firebase.tsx بالإعداد الذي نسخته للتو من وحدة تحكّم Firebase.
    const firebaseConfig = {
      apiKey: "API_KEY",
      authDomain: "PROJECT_ID.firebaseapp.com",
      projectId: "PROJECT_ID",
      storageBucket: "PROJECT_ID.firebasestorage.app",
      messagingSenderId: "SENDER_ID",
      appId: "APP_ID"
    };
    
  3. إنشاء تطبيق الويب: في VS Code، في المجلد app، استخدِم Vite لإنشاء تطبيق الويب من أجل نشر الاستضافة:
    cd app
    npm run build
    

إعداد خدمة "المصادقة عبر Firebase" في مشروعك على Firebase

  1. إعداد مصادقة Firebase باستخدام ميزة "تسجيل الدخول باستخدام حساب Google"62af2f225e790ef6.png
  2. (اختياري) السماح بالنطاقات في مصادقة Firebase باستخدام وحدة تحكّم Firebase (على سبيل المثال، http://127.0.0.1).
    1. في إعدادات المصادقة، انتقِل إلى النطاقات المعتمَدة.
    2. انقر على "إضافة نطاق" وأدرِج نطاقك المحلي في القائمة.

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"]
    
  2. تأكَّد من إعداد واجهة سطر الأوامر (CLI) في Firebase مع مشروعك:
    npm i -g firebase-tools
    firebase login --reauth
    firebase use --add
    
  3. في الوحدة الطرفية، شغِّل الأمر التالي لنشر التطبيق:
    firebase deploy --only dataconnect,hosting
    
  4. نفِّذ الأمر التالي لمقارنة تغييرات المخطط:
    firebase dataconnect:sql:diff
    
  5. إذا كانت التغييرات مقبولة، طبِّقها باستخدام:
    firebase dataconnect:sql:migrate
    

سيتم تعديل آلة Cloud SQL الافتراضية التي تستخدم PostgreSQL باستخدام المخطط والبيانات النهائية التي تم نشرها. يمكنك تتبُّع الحالة في وحدة تحكُّم Firebase.

من المفترض أن تتمكّن الآن من مشاهدة تطبيقك مباشرةً على your-project.web.app/. بالإضافة إلى ذلك، يمكنك النقر على تشغيل (الإنتاج) في لوحة Firebase Data Connect، تمامًا كما فعلت مع المحاكيات المحلية، لإضافة بيانات إلى بيئة الإنتاج.

11. اختياري: البحث المتّجه باستخدام Firebase Data Connect (يجب توفّر معلومات الفوترة)

في هذا القسم، ستفعِّل البحث المتّجه في تطبيق مراجعات الأفلام باستخدام Firebase Data Connect. تتيح هذه الميزة إجراء عمليات بحث مستندة إلى المحتوى، مثل العثور على أفلام تتضمّن أوصافًا مشابهة باستخدام التضمينات المتجهة.

تتطلّب هذه الخطوة أن تكون قد أكملت الخطوة الأخيرة من هذا الدرس العملي لتنفيذ عملية النشر على Google Cloud.

4b5aca5a447d2feb.png

تعديل المخطّط ليشمل عمليات تضمين لحقل معيّن

في 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. أعِد نشر المخطط لتفعيل pgvector والبحث المتّجه من خلال النقر على "النشر في مرحلة الإنتاج" باستخدام إضافة Firebase Data Connect VS Code.

تعبئة قاعدة البيانات بالتضمينات

  1. افتح مجلد dataconnect في VS Code.
  2. انقر على تشغيل(محلي) في optional_vector_embed.gql لملء قاعدة البيانات بعمليات التضمين الخاصة بالأفلام.

b858da780f6ec103.png

إضافة طلب بحث عن تطابق دلالي

في 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، أزِل التعليق عن عمليات الاستيراد التالية من حِزم SDK، وسيعمل ذلك مثل أي طلب بحث آخر.
    import {
      searchMovieDescriptionUsingL2similarity,
      SearchMovieDescriptionUsingL2similarityData,
    } from "@movie/dataconnect";
    
  2. أضِف الدالة التالية لدمج البحث المستند إلى المتجهات في التطبيق:
    // 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

12. الخاتمة

تهانينا، من المفترض أن تتمكّن من استخدام تطبيق الويب. إذا كنت تريد تجربة بيانات الأفلام الخاصة بك، لا تقلق، يمكنك إدراج بياناتك باستخدام إضافة Firebase Data Connect عن طريق محاكاة ملفات _insert.gql، أو إضافتها من خلال لوحة تنفيذ Data Connect في VS Code.

مزيد من المعلومات