1. نظرة عامة
في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية إضافة ميزات بحث فعّالة إلى تطبيقك باستخدام البحث عن التشابه المتّجه في Firestore. ستنفّذ ميزة البحث الدلالي في تطبيق لتدوين الملاحظات مكتوب بلغة Swift وواجهة SwiftUI.

ما ستتعلمه
- كيفية تثبيت إضافة "البحث المتّجهي باستخدام Firestore" لاحتساب تضمينات المتّجهات
- كيفية استدعاء "وظائف Firebase السحابية" من تطبيق Swift
- كيفية فلترة البيانات مسبقًا استنادًا إلى المستخدم الذي سجّل الدخول
المتطلبات
- Xcode 15.3
- رمز نموذجي لدرس تطبيقي حول الترميز سيتم تنزيل هذا الملف في خطوة لاحقة من الدرس العملي.
2. إنشاء مشروع Firebase وإعداده
لاستخدام إضافة "البحث المتّجه" في Firebase، يجب أن يكون لديك مشروع على Firebase. في هذا الجزء من الدرس العملي، ستنشئ مشروعًا جديدًا على Firebase، وستفعّل الخدمات المطلوبة، مثل Cloud Firestore ومصادقة Firebase.
إنشاء مشروع Firebase
- سجِّل الدخول إلى وحدة تحكّم Firebase باستخدام حساب Google.
- انقر على الزر لإنشاء مشروع جديد، ثم أدخِل اسم المشروع (على سبيل المثال،
Firestore Vector Search Codelab).
- انقر على متابعة.
- إذا طُلب منك ذلك، راجِع بنود Firebase واقبلها، ثم انقر على متابعة.
- (اختياري) فعِّل ميزة "المساعدة المستندة إلى الذكاء الاصطناعي" في وحدة تحكّم Firebase (المعروفة باسم "Gemini في Firebase").
- في هذا الدرس العملي، لا تحتاج إلى "إحصاءات Google"، لذا أوقِف خيار "إحصاءات Google".
- انقر على إنشاء مشروع، وانتظِر إلى أن يتم توفير مشروعك، ثم انقر على متابعة.
لمزيد من المعلومات عن مشاريع Firebase، اطّلِع على مقالة التعرّف على مشاريع Firebase.
ترقية خطة أسعار Firebase
لاستخدام "إضافات Firebase" وخدمات السحابة الإلكترونية الأساسية، يجب أن يكون مشروعك على Firebase ضمن خطة التسعير "الدفع حسب الاستخدام" (Blaze)، ما يعني أنّه مرتبط بحساب فوترة على Cloud.
- يتطلّب حساب الفوترة في Cloud طريقة دفع، مثل بطاقة الائتمان.
- إذا كنت حديث العهد باستخدام Firebase وGoogle Cloud، تحقّق ممّا إذا كنت مؤهَّلاً للحصول على رصيد بقيمة 300 دولار أمريكي وحساب فوترة في Cloud ضمن "الفترة التجريبية المجانية".
- إذا كنت تجري هذا الدرس التطبيقي حول الترميز كجزء من حدث، اسأل المنظّم عمّا إذا كانت هناك أي أرصدة Cloud متاحة.
لترقية مشروعك إلى خطة Blaze، اتّبِع الخطوات التالية:
- في "وحدة تحكّم Firebase"، اختَر ترقية خطتك.
- اختَر خطة Blaze. اتّبِع التعليمات الظاهرة على الشاشة لربط حساب فوترة على Cloud بمشروعك.
إذا كان عليك إنشاء حساب فوترة على Cloud كجزء من عملية الترقية هذه، قد تحتاج إلى الرجوع إلى مسار الترقية في وحدة تحكّم Firebase لإكمال عملية الترقية.
تفعيل منتجات Firebase وإعدادها في وحدة التحكّم
يستخدم التطبيق الذي تنشئه العديد من منتجات Firebase المتاحة لتطبيقات Apple:
- مصادقة Firebase للسماح للمستخدمين بتسجيل الدخول إلى تطبيقك بسهولة
- Cloud Firestore لحفظ البيانات المنظَّمة على السحابة الإلكترونية وتلقّي إشعارات فورية عند تغيُّر البيانات
- قواعد الأمان في Firebase لتأمين قاعدة البيانات
تتطلّب بعض هذه المنتجات إعدادًا خاصًا أو يجب تفعيلها باستخدام وحدة تحكّم Firebase.
تفعيل المصادقة بدون الكشف عن الهوية في مصادقة Firebase
يستخدم هذا التطبيق المصادقة المجهولة للسماح للمستخدمين ببدء استخدام التطبيق بدون الحاجة إلى إنشاء حساب أولاً. ويؤدي ذلك إلى توفير عملية إعداد سلسة. لمزيد من المعلومات حول المصادقة بدون اسم (وكيفية الترقية إلى حساب باسم)، يُرجى الاطّلاع على أفضل الممارسات للمصادقة بدون اسم.
- في اللوحة الجانبية اليمنى من "وحدة تحكّم Firebase"، انقر على إنشاء > المصادقة. بعد ذلك، انقر على البدء.

- أنت الآن في لوحة بيانات المصادقة، حيث يمكنك الاطّلاع على المستخدمين الذين اشتركوا، وإعداد موفّري خدمة تسجيل الدخول، وإدارة الإعدادات.
- انقر على علامة التبويب طريقة تسجيل الدخول (أو انقر هنا للانتقال مباشرةً إلى علامة التبويب).
- انقر على مجهول من خيارات مقدّم الخدمة، ثم فعِّل الخيار تفعيل، وانقر على حفظ.
إعداد Cloud Firestore
يستخدم تطبيق Swift هذا Cloud Firestore لحفظ الملاحظات.
في ما يلي كيفية إعداد Cloud Firestore في مشروع Firebase:
- في اللوحة اليمنى من "وحدة تحكّم Firebase"، وسِّع إنشاء، ثم اختَر قاعدة بيانات Firestore.
- انقر على إنشاء قاعدة بيانات.
- اترك معرّف قاعدة البيانات مضبوطًا على
(default). - اختَر موقعًا لقاعدة البيانات، ثم انقر على التالي.
بالنسبة إلى تطبيق حقيقي، عليك اختيار موقع جغرافي قريب من المستخدمين. - انقر على بدء التشغيل في وضع الاختبار. اقرأ بيان إخلاء المسؤولية عن قواعد الأمان.
في وقت لاحق من هذا الدرس العملي، ستضيف قواعد الأمان لتأمين بياناتك. لا توزِّع تطبيقًا أو تعرضه بشكل علني بدون إضافة "قواعد الأمان" لقاعدة البيانات. - انقر على إنشاء.
إعداد مساحة تخزين سحابية لـ Firebase
يستخدم تطبيق الويب "مساحة تخزين سحابية لـ Firebase" لتخزين الصور وتحميلها ومشاركتها.
في ما يلي كيفية إعداد مساحة تخزين سحابية لـ Firebase في مشروع Firebase:
- في اللوحة اليمنى من وحدة تحكّم Firebase، وسِّع إنشاء، ثم اختَر مساحة التخزين.
- انقر على البدء.
- اختَر موقعًا جغرافيًا لحزمة التخزين التلقائية.
يمكن للحِزم فيUS-WEST1وUS-CENTRAL1وUS-EAST1الاستفادة من الفئة"دائمًا مجانية" في Google Cloud Storage. تخضع الحِزم في جميع المواقع الجغرافية الأخرى لأسعار واستخدام Google Cloud Storage. - انقر على بدء التشغيل في وضع الاختبار. اقرأ بيان إخلاء المسؤولية حول قواعد الأمان.
في وقت لاحق من هذا الدرس العملي، ستضيف قواعد أمان لحماية بياناتك. لا توزّع تطبيقًا أو تعرضه للجميع بدون إضافة "قواعد الأمان" لحزمة Cloud Storage. - انقر على إنشاء.
3- ربط تطبيق الأجهزة الجوّالة
في هذا القسم من الدرس التطبيقي حول الترميز، ستنزّل الرمز المصدر لتطبيق بسيط لتدوين الملاحظات، وتربطه بمشروع Firebase الذي أنشأته للتو.
تنزيل نموذج التطبيق
- انتقِل إلى https://github.com/FirebaseExtended/codelab-firestore-vectorsearch-ios، واستنسِخ المستودع إلى جهازك المحلي
- افتح مشروع Notes.xcodeproj في Xcode
ربط التطبيق بمشروع Firebase
لكي يتمكّن تطبيقك من الوصول إلى خدمات Firebase، عليك إعداده في وحدة تحكّم Firebase. يمكنك ربط تطبيقات عميل متعددة بمشروع Firebase نفسه، على سبيل المثال، إذا أنشأت تطبيق Android أو تطبيق ويب، عليك ربطهما بمشروع Firebase نفسه.
لمزيد من المعلومات عن مشاريع Firebase، اطّلِع على مقالة التعرّف على مشاريع Firebase.
- في "وحدة تحكّم Firebase"، انتقِل إلى صفحة النظرة العامة لمشروعك على Firebase.

- انقر على رمز iOS+ لإضافة تطبيق iOS.
- في شاشة إضافة Firebase إلى تطبيق Apple، أدخِل رقم تعريف الحزمة من مشروع Xcode (com.google.firebase.codelab.Notes).
- يمكنك إدخال اسم مستعار للتطبيق (ملاحظات على iOS) إذا أردت ذلك.
- انقر على "تسجيل التطبيق" للانتقال إلى الخطوة التالية.
- نزِّل الملف GoogleServices-Info.plist.
- اسحب ملف GoogleServices-Info.plist إلى مجلد Notes في مشروع Xcode. يمكنك إجراء ذلك من خلال إسقاطه أسفل الملف Assets.xcassets.

- اختَر نسخ العناصر إذا لزم الأمر، وتأكَّد من اختيار هدف الملاحظات في الإضافة إلى الأهداف، ثم انقر على إنهاء.

- في "وحدة تحكّم Firebase"، يمكنك الآن النقر خلال بقية عملية الإعداد: تتضمّن العيّنة التي نزّلتها في بداية هذا القسم حزمة تطوير البرامج (SDK) من Firebase لنظام التشغيل iOS مثبَّتة، كما تم إعداد عملية التهيئة. يمكنك إنهاء العملية من خلال النقر على متابعة إلى وحدة التحكّم.
تشغيل التطبيق
حان الوقت الآن لتجربة التطبيق.
- عُد إلى Xcode، وشغِّل التطبيق على محاكي iOS. في القائمة المنسدلة تشغيل الوجهات، اختَر أولاً أحد محاكيات iOS.

- بعد ذلك، انقر على الزر تشغيل أو اضغط على ⌘ + R.
- بعد تشغيل التطبيق بنجاح على المحاكي، أضِف بعض الملاحظات.
- في وحدة تحكّم Firebase، انتقِل إلى "متصفّح بيانات Firestore"، حتى تتمكّن من الاطّلاع على المستندات الجديدة التي يتم إنشاؤها أثناء إضافة ملاحظات جديدة في التطبيق.

4. تثبيت إضافة "البحث المتّجهي مع Firestore"
في هذا الجزء من الدرس التطبيقي حول الترميز، ستثبّت إضافة "البحث المتّجه مع Firestore"، وستضبطها وفقًا لمتطلبات تطبيق تدوين الملاحظات الذي تعمل عليه.
بدء تثبيت الإضافة
- في قسم Firestore، انقر على علامة التبويب الإضافات.

- انقر على استكشاف "مركز الإضافات"
. - اكتب "متّجه".
- انقر على "Vector Search with Firestore extension".
سيتم نقلك إلى صفحة تفاصيل الإضافة، حيث يمكنك الاطّلاع على مزيد من المعلومات عن الإضافة وطريقة عملها وخدمات Firebase التي تتطلّبها وكيفية إعدادها. - انقر على التثبيت في وحدة تحكّم Firebase.

- ستظهر لك قائمة بجميع مشاريعك.
- اختَر المشروع الذي أنشأته في الخطوة الأولى من هذا الدرس العملي.

ضبط الإضافة
- راجِع واجهات برمجة التطبيقات المفعَّلة والموارد التي تم إنشاؤها.

- فعِّل الخدمات المطلوبة.

- بعد تفعيل جميع الخدمات، انقر على التالي.

- راجِع أذونات الوصول الممنوحة لهذه الإضافة.
- ضبط الإضافة:
- اختَر Vertex AI كـ نموذج لغوي كبير.
- مسار المجموعة: notes
- الحدّ التلقائي لعدد طلبات البحث: 3
- اسم حقل الإدخال: text
- اسم حقل الإخراج: embedding
- اسم حقل الحالة:* *الحالة*
- تضمين المستندات الحالية: نعم
- تعديل المستندات الحالية: نعم
- موقع Cloud Function: us-central1
- انقر على تثبيت الإضافة لإنهاء عملية التثبيت.
قد تستغرق هذه العملية بضع دقائق. أثناء انتظار اكتمال عملية التثبيت، يمكنك الانتقال إلى القسم التالي من البرنامج التعليمي وقراءة بعض المعلومات الأساسية حول التضمينات المتجهة.
5- الخلفية
أثناء انتظار انتهاء عملية التثبيت، إليك بعض المعلومات الأساسية حول طريقة عمل إضافة "البحث المتّجه مع Firestore".
ما هي المتّجهات والتضمينات وقواعد بيانات المتّجهات؟
- المتجهات هي كائنات رياضية تمثّل مقدار واتجاه كمية ما. ويمكن استخدامها لتمثيل البيانات بطريقة تسهّل مقارنتها والبحث فيها.
- التضمينات هي متجهات تمثّل معنى كلمة أو عبارة. يتم إنشاؤها من خلال تدريب شبكة عصبية على مجموعة كبيرة من النصوص وتعلُّم العلاقات بين الكلمات.
- قواعد بيانات المتّجهات هي قواعد بيانات تم تحسينها لتخزين بيانات المتّجهات والبحث فيها. تتيح هذه الفهارس إجراء بحث فعّال عن أقرب جيران، وهي عملية العثور على المتّجهات الأكثر تشابهًا مع متّجه طلب بحث معيّن.
كيف يعمل Vector Search؟
تعمل ميزة "البحث المتّجهي" من خلال مقارنة متّجه طلب البحث بجميع المتّجهات في قاعدة البيانات. يتم عرض المتّجهات الأكثر تشابهًا مع متّجه طلب البحث كنتائج بحث.
يمكن قياس التشابه بين متجهَين باستخدام مجموعة متنوعة من مقاييس المسافة. مقياس المسافة الأكثر شيوعًا هو تشابه جيب التمام، الذي يقيس الزاوية بين متجهين.
6. جرِّب إضافة "البحث المتّجه باستخدام Firestore"
قبل استخدام إضافة "البحث المتّجه مع Firestore" في تطبيق iOS الذي نزّلته سابقًا في هذا الدرس العملي، يمكنك تجربة الإضافة في وحدة تحكّم Firebase.
قراءة المستندات
تتضمّن إضافات Firebase مستندات حول طريقة عملها.
- بعد انتهاء تثبيت الإضافة، انقر على الزر البدء.

- اطّلِع على علامة التبويب "طريقة عمل هذه الإضافة" التي توضّح ما يلي:
- كيفية احتساب التضمينات للمستندات من خلال إضافتها إلى المجموعة
notes - كيفية طلب البحث في الفهرس من خلال استدعاء الدالة القابلة للاستدعاء
ext-firestore-vector-search-queryCallable - أو كيفية طلب البحث في الفهرس عن طريق إضافة مستند طلب بحث إلى المجموعة
_firestore-vector-search/index/queries. - توضّح هذه المقالة أيضًا كيفية إعداد دالة تضمين مخصّصة، وهو أمر مفيد إذا لم يستوفِ أي من النماذج اللغوية الكبيرة المتوافقة مع الإضافة متطلباتك، وكنت تريد استخدام نموذج لغوي كبير مختلف لحساب عمليات التضمين.

- كيفية احتساب التضمينات للمستندات من خلال إضافتها إلى المجموعة
- انقر على رابط لوحة بيانات Cloud Firestore للانتقال إلى نسخة Firestore.
- انتقِل إلى المستند
_firestore-vector-search/index. يجب أن يظهر أنّ الإضافة قد انتهت من احتساب التضمينات لجميع مستندات الملاحظات التي أنشأتها في خطوة سابقة من هذا الدرس العملي.
- للتأكّد من ذلك، افتح أحد مستندات الملاحظات، وسيظهر لك حقل إضافي باسم
embeddingمن النوعvector<768>، بالإضافة إلى حقلstatus.
إنشاء مستند نموذجي
يمكنك إنشاء مستند جديد في وحدة تحكّم Firebase للاطّلاع على كيفية عمل الإضافة.
- في "متصفّح بيانات Firestore"، انتقِل إلى المجموعة
notesوانقر على + إضافة مستند في العمود الأوسط.
- انقر على المعرّف التلقائي لإنشاء معرّف مستند فريد جديد.
- أضِف حقلاً باسم
textمن نوع سلسلة، وألصِق بعض النص في حقل القيمة. من المهم ألا يكون هذا النص عبارة عن نص lorem ipsum أو أي نص عشوائي آخر. اختَر مقالة إخبارية، مثلاً.
- انقر على حفظ.
- لاحظ كيف تضيف الإضافة حقل حالة للإشارة إلى أنّها تعالج البيانات.
- بعد لحظات قليلة، من المفترض أن يظهر حقل جديد
embeddingبالقيمةvector<768>.

تنفيذ طلب بحث
يتضمّن إضافة "البحث المتّجه" في Firestore ميزة صغيرة رائعة تتيح لك طلب البحث في فهرس المستندات بدون الحاجة إلى ربط تطبيق.
- في قسم Firestore ضِمن "وحدة تحكّم Firebase"، انتقِل إلى المستند
_firestore-vector-search/index - انقر على + بدء عملية التحصيل

- أنشئ مجموعة فرعية جديدة باسم
queries - أنشئ مستندًا جديدًا واضبط الحقل
queryعلى نص يظهر في أحد مستنداتك. يعمل هذا الخيار بشكل أفضل مع طلبات البحث الدلالية، مثل "كيف يمكنني ربط مستندات Firestore بلغة Swift؟" (شرط أن تحتوي إحدى الملاحظات التي أضفتها على نص يناقش هذا الموضوع).
- قد يظهر لك خطأ في الحالة

- يرجع ذلك إلى عدم توفّر فهرس. لإعداد إعدادات الفهرس الناقص، انتقِل إلى Google Cloud Console الخاص بمشروعك باتّباع هذا الرابط، ثم اختَر مشروعك من القائمة

- في "مستكشف سجلات Cloud"، من المفترض أن تظهر لك الآن رسالة خطأ تفيد بأنّ "FAILED_PRECONDITION: Missing vector index configuration". يُرجى إنشاء الفهرس المطلوب باستخدام أمر gcloud التالي: ..."

- تحتوي رسالة الخطأ أيضًا على أمر
gcloudيجب تنفيذه لإعداد الفهرس الناقص. - نفِّذ الأمر التالي من سطر الأوامر. إذا لم يكن لديك واجهة سطر الأوامر
gcloudمثبَّتة على جهازك، اتّبِع التعليمات الواردة هنا لتثبيتها. يستغرق إنشاء الفهرس بضع دقائق. يمكنك الاطّلاع على مستوى التقدّم في علامة التبويب الفهارس ضمن قسم Firestore في وحدة تحكّم Firebase.gcloud alpha firestore indexes composite create --project=INSERT-YOUR=PROJECT-ID-HERE --collection-group=notes --query-scope=COLLECTION --field-config=vector-config='{"dimension":"768","flat": "{}"}',field-path=embedding
- بعد إعداد الفهرس، يمكنك إنشاء مستند طلب بحث جديد.
- من المفترض أن تظهر لك الآن قائمة بمعرّفات المستندات المطابقة في حقل النتائج

- انسخ أحد أرقام التعريف هذه، ثم ارجع إلى المجموعة
notes. - استخدِم ⌘+F للبحث عن رقم تعريف المستند الذي نسخته، فهذا المستند هو الأنسب لطلب البحث.

7. تنفيذ البحث الدلالي
حان الوقت أخيرًا لربط تطبيقك على الأجهزة الجوّالة بإضافة "البحث المتّجهي باستخدام Firestore" وتنفيذ ميزة البحث الدلالي التي ستتيح للمستخدمين البحث عن ملاحظاتهم باستخدام طلبات بحث باللغة العادية.
ربط الدالة القابلة للاستدعاء لتنفيذ طلبات البحث
تتضمّن إضافة "البحث المتّجه مع Firestore" دالة Cloud يمكنك استدعاؤها من تطبيقك على الأجهزة الجوّالة لطلب البحث في الفهرس الذي أنشأته سابقًا في هذا الدرس العملي. في هذه الخطوة، ستنشئ اتصالاً بين تطبيقك على الأجهزة الجوّالة وهذه الدالة القابلة للاستدعاء. تتضمّن حزمة تطوير البرامج (SDK) لمنصة Firebase المتوافقة مع Swift واجهات برمجة تطبيقات تسهّل استدعاء الدوال عن بُعد.
- ارجع إلى Xcode وتأكَّد من أنّك في المشروع الذي نسخته في خطوة سابقة من هذا الدرس العملي.
- افتح ملف
NotesRepository.swift. - ابحث عن السطر الذي يتضمّن
private lazy var vectorSearchQueryCallable: Callable= functions.httpsCallable("")
لاستدعاء دالة Cloud قابلة للاستدعاء، عليك تقديم اسم الدالة التي تريد استدعاءها.
- انتقِل إلى "وحدة تحكّم Firebase" الخاصة بمشروعك، وافتح عنصر القائمة الدوال في قسم إنشاء.
- ستظهر لك قائمة بالدوال التي ثبّتتها الإضافة.
- ابحث عن الملف الذي يحمل الاسم
ext-firestore-vector-search-queryCallableوانسخ اسمه. - ألصِق الاسم في الرمز. من المفترض أن يظهر الآن
private lazy var vectorSearchQueryCallable: Callable<String, String> = functions.httpsCallable("ext-firestore-vector-search-queryCallable")
استدعاء دالة طلب البحث
- العثور على الطريقة
performQuery - استدعاء الدالة القابلة للاستدعاء من خلال استدعائها
let result = try await vectorSearchQueryCallable(searchTerm)
بما أنّ هذا الطلب يتم عن بُعد، قد يتعذّر تنفيذه.
- أضِف بعض آليات معالجة الأخطاء الأساسية لرصد أي أخطاء وتسجيلها في وحدة تحكّم Xcode.
private func performQuery(searchTerm: String) async -> [String] { do { let result = try await vectorSearchQueryCallable(searchTerm) return [result] } catch { print(error.localizedDescription) return [] } }
ربط واجهة المستخدم
للسماح للمستخدمين بالبحث في ملاحظاتهم، عليك تنفيذ شريط بحث في شاشة قائمة الملاحظات. عندما يكتب المستخدم عبارة بحث، عليك استدعاء الطريقة performQuery التي نفّذتها في الخطوة السابقة. بفضل معدِّلَي العرض searchable وtask اللذين توفّرهما SwiftUI، لا يتطلّب ذلك سوى بضعة أسطر من الرموز البرمجية.
- افتح
NotesListScreen.swiftأولاً - لإضافة مربّع بحث إلى طريقة عرض القائمة، أضِف معدِّل العرض
.searchable(text: $searchTerm, prompt: "Search")فوق السطر.navigationTitle("Notes")مباشرةً. - بعد ذلك، استدعِ دالة البحث عن طريق إضافة الرمز التالي أدناه مباشرةً:
.task(id: searchTerm, debounce: .milliseconds(800)) {
await notesRepository.semanticSearch(searchTerm: searchTerm)
}
يستدعي مقتطف الرمز هذا طريقتك semanticSearch بشكل غير متزامن. من خلال توفير مهلة تبلغ 800 ملي ثانية، يمكنك توجيه معدِّل المهام إلى إزالة تكرار إدخال المستخدم بمقدار 0.8 ثانية. هذا يعني أنّه لن يتم استدعاء semanticSearch إلا بعد أن يتوقف المستخدم عن الكتابة لأكثر من 0.8 ثانية.
يجب أن تبدو التعليمات البرمجية الآن على النحو التالي:
...
List(repository.notes) { note in
NavigationLink(value: note) {
NoteRowView(note: note)
}
.swipeActions {
Button(role: .destructive, action: { deleteNote(note: note) }) {
Label("Delete", systemImage: "trash")
}
}
}
.searchable(text: $searchTerm, prompt: "Search")
.task(id: searchTerm, debounce: .milliseconds(800)) {
await notesRepository.semanticSearch(searchTerm: searchTerm)
}
.navigationTitle("Notes")
...
تشغيل التطبيق
- اضغط على ⌘ + R (أو انقر على الزر "تشغيل") لتشغيل التطبيق على محاكي iOS
- يجب أن تظهر لك الملاحظات نفسها التي أضفتها في التطبيق سابقًا في هذا الدرس التطبيقي حول الترميز، بالإضافة إلى أي ملاحظات أضفتها من خلال "وحدة تحكّم Firebase".
- من المفترض أن يظهر لك حقل بحث في أعلى قائمة الملاحظات
- اكتب عبارة تظهر في أحد المستندات التي أضفتها. مرة أخرى، تعمل هذه الميزة بشكل أفضل مع طلبات البحث الدلالية، مثل "كيف يمكنني طلب واجهات برمجة تطبيقات Firebase غير متزامنة من Swift" (شرط أن تحتوي ملاحظة واحدة على الأقل من الملاحظات التي أضفتها على نص يناقش هذا الموضوع).
- من المفترض أن تظهر لك نتيجة البحث، ولكن بدلاً من ذلك، تكون طريقة العرض على شكل قائمة فارغة، وتعرض وحدة تحكّم Xcode رسالة خطأ: "تم استدعاء الدالة باستخدام وسيطة غير صالحة".

يعني ذلك أنّك أرسلت البيانات بتنسيق غير صحيح.
تحليل رسالة الخطأ
- لمعرفة المشكلة، انتقِل إلى "وحدة تحكّم Firebase".
- انتقِل إلى قسم الدوال.
- ابحث عن الدالة
ext-firestore-vector-search-queryCallable، وافتح القائمة الكاملة من خلال النقر على النقاط الثلاث الرأسية - انقر على عرض السجلات للانتقال إلى "مستكشف السجلات".
- من المفترض أن يظهر لك خطأ
Unhandled error ZodError: [
{
"code": "invalid_type",
"expected": "object",
"received": "string",
"path": [],
"message": "Expected object, received string"
}
]
يعني ذلك أنّك أرسلت البيانات بتنسيق غير صحيح.
استخدام أنواع البيانات الصحيحة
لمعرفة التنسيق الذي تتوقّع الإضافة أن تكون المَعلمات به، اطّلِع على مستندات الإضافة.
- الانتقال إلى قسم الإضافات في "وحدة تحكّم Firebase"
- انقر على إدارة ->

- في قسم طريقة عمل هذه الإضافة، ستجد مواصفات لمَعلمات الإدخال والإخراج.

- ارجع إلى Xcode وانتقِل إلى
NotesRepository.swift - أضِف الرمز التالي في بداية الملف:يتطابق
private struct QueryRequest: Codable { var query: String var limit: Int? var prefilters: [QueryFilter]? } private struct QueryFilter: Codable { var field: String var `operator`: String var value: String } private struct QueryResponse: Codable { var ids: [String] }QueryRequestمع بنية مَعلمة الإدخال التي تتوقّعها الإضافة، وذلك وفقًا لمستندات الإضافة. يتضمّن أيضًا السمةprefilterالمتداخلة التي ستحتاج إليها لاحقًا.تتطابق السمةQueryResponseمع بنية استجابة الإضافة. - العثور على مواصفات الدالة القابلة للاستدعاء وتعديل أنواع الإدخال والإخراج
private lazy var vectorSearchQueryCallable: Callable<QueryRequest, QueryResponse> = functions.httpsCallable("ext-firestore-vector-search-queryCallable") - تعديل استدعاء الدالة القابلة للاستدعاء في
performQueryprivate func performQuery(searchTerm: String) async -> [String] { do { let queryRequest = QueryRequest(query: searchTerm, limit: 2) let result = try await vectorSearchQueryCallable(queryRequest) print(result.ids) return result.ids } catch { print(error.localizedDescription) return [] } }
تشغيل التطبيق مرة أخرى
- تشغيل التطبيق مرة أخرى
- اكتب طلب بحث يتضمّن عبارات واردة في إحدى ملاحظاتك
- من المفترض أن تظهر الآن قائمة مفلتَرة بالملاحظات

فلترة بيانات المستخدمين مسبقًا
قبل الاحتفال بالرقص، هناك مشكلة في الإصدار الحالي من التطبيق: تحتوي مجموعة النتائج على بيانات من جميع المستخدمين.
يمكنك التأكّد من ذلك عن طريق تشغيل التطبيق على محاكي مختلف وإضافة المزيد من المستندات. لن تظهر المستندات الجديدة إلا في هذا المحاكي، وإذا شغّلت التطبيق مرة أخرى على المحاكي الآخر، لن ترى إلا المستندات التي أنشأتها في المرة الأولى.
إذا أجريت عملية بحث، ستلاحظ أنّ طلب vectorSearchQueryCallable يعرض أرقام تعريف مستندات قد تخص المستخدم الآخر. لمنع حدوث ذلك، علينا استخدام فلتر مسبق.
في performQuery، عدِّل الرمز على النحو التالي:
let prefilters: [QueryFilter] = if let uid = user?.uid {
[QueryFilter(field: "userId", operator: "==", value: uid)]
}
else {
[]
}
let queryRequest = QueryRequest(query: searchTerm,
limit: 2,
prefilters: prefilters)
سيؤدي ذلك إلى فلترة البيانات مسبقًا استنادًا إلى رقم تعريف المستخدم الذي سجّل الدخول. وكما هو متوقّع، يتطلّب ذلك تعديل فهرس Firestore.
نفِّذ الأمر التالي من سطر الأوامر لتحديد فهرس Firestore جديد يتضمّن كلاً من userId وتضمينات المتجهات في الحقل embedding.
gcloud alpha firestore indexes composite create --project=INSERT-YOUR-PROJECT-ID-HERE --collection-group=notes --query-scope=COLLECTION --field-config=order=ASCENDING,field-path=userId --field-config=vector-config='{"dimension":"768","flat": "{}"}',field-path=embedding
بعد الانتهاء من إنشاء الفهرس، شغِّل التطبيق مرة أخرى للتأكّد من أنّه يعمل على النحو المتوقّع.

8. تهانينا
تهانينا على إكمال هذا الدرس التطبيقي حول الترميز بنجاح.
في هذا الدرس العملي، تعلّمت كيفية:
- إعداد قاعدة بيانات Cloud Firestore مع تفعيل البحث الدلالي
- أنشئ تطبيقًا بسيطًا باستخدام SwiftUI للتفاعل مع قاعدة البيانات.
- نفِّذ شريط بحث باستخدام معدِّل العرض القابل للبحث ومعدِّل المهمة في SwiftUI.
- استدعِ إحدى "وظائف السحابة" لإجراء بحث دلالي في قاعدة البيانات باستخدام واجهة Callable في حزمة تطوير البرامج (SDK) الخاصة بخدمة Firestore.
باستخدام المعرفة التي اكتسبتها في هذا الدرس التطبيقي حول الترميز، يمكنك الآن إنشاء تطبيقات فعّالة تستفيد من إمكانات البحث الدلالي في Cloud Firestore لتزويد المستخدمين بتجربة بحث أكثر سهولة وفعالية.
لمزيد من المعلومات حول حقل المتّجه الجديد في Firestore وكيفية احتساب تضمينات المتّجهات، يمكنك الاطّلاع على المستندات.