يتناول هذا المستند أساسيات استرداد البيانات وكيفية ترتيب بيانات Firebase وتصفيتها.
قبل البدء
قبل أن تتمكّن من استخدام Realtime Database، عليك تنفيذ ما يلي:
سجِّل مشروع Unity الخاص بك وأعدَّه لاستخدام Firebase.
إذا كان مشروع Unity يستخدم Firebase، يكون قد تم تسجيله وإعداده لاستخدام Firebase.
إذا لم يكن لديك مشروع Unity، يمكنك تنزيل نموذج تطبيق.
أضِف Firebase Unity SDK (
FirebaseDatabase.unitypackageتحديدًا) إلى مشروع Unity.
يُرجى العِلم أنّ إضافة Firebase إلى مشروع Unity يتضمّن مهامًا في كل من وحدة تحكّم Firebase ومشروع Unity المفتوح (على سبيل المثال، يمكنك تنزيل ملفات إعداد Firebase من وحدة التحكّم، ثم نقلها إلى مشروع Unity).
جارٍ استرداد البيانات
يتم استرداد بيانات Firebase إما من خلال طلب GetValueAsync() لمرة واحدة أو من خلال ربطها بحدث في مرجع FirebaseDatabase. يتم استدعاء متتبِّع الأحداث مرة واحدة للحالة الأولية للبيانات، ومرة أخرى كلما تغيّرت البيانات.
الحصول على DatabaseReference
لقراءة البيانات من قاعدة البيانات، تحتاج إلى مثيل من DatabaseReference:
using Firebase; using Firebase.Database; using Firebase.Extensions.TaskExtension; // for ContinueWithOnMainThread public class MyScript: MonoBehaviour { void Start() { // Get the root reference location of the database. DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference; } }
قراءة البيانات مرة واحدة
يمكنك استخدام طريقة GetValueAsync
لقراءة لقطة ثابتة للمحتوى في مسار معيّن مرة واحدة. ستحتوي نتيجة المهمة على لقطة
تتضمّن جميع البيانات في ذلك الموقع الجغرافي، بما في ذلك بيانات الطفل. في حال عدم توفّر بيانات، ستكون اللقطة المعروضة null.
FirebaseDatabase.DefaultInstance .GetReference("Leaders") .GetValueAsync().ContinueWithOnMainThread(task => { if (task.IsFaulted) { // Handle the error... } else if (task.IsCompleted) { DataSnapshot snapshot = task.Result; // Do something with snapshot... } });
الاستماع إلى الأحداث
يمكنك إضافة أدوات معالجة الأحداث للاشتراك في التغييرات التي تطرأ على البيانات:
| الحدث | الاستخدام النموذجي |
|---|---|
ValueChanged |
قراءة التغييرات في المحتوى الكامل لمسار معيّن والاستماع إليها |
ChildAdded
| استرداد قوائم العناصر أو الاستماع إلى عمليات الإضافة إلى قائمة العناصر
يُقترح استخدامها مع ChildChanged وChildRemoved لتتبُّع التغييرات التي تطرأ على القوائم |
ChildChanged |
الاستماع إلى التغييرات التي تطرأ على العناصر في قائمة استخدِمها مع ChildAdded وChildRemoved لتتبُّع التغييرات في القوائم. |
ChildRemoved |
الاستماع إلى العناصر التي تتم إزالتها من قائمة، ويُستخدَم مع
ChildAdded وChildChanged لتتبُّع التغييرات في القوائم. |
ChildMoved |
الاستماع إلى التغييرات في ترتيب العناصر في قائمة مرتبة
تتبع أحداث ChildMoved دائمًا حدث ChildChanged الذي تسبّب في تغيير ترتيب العنصر (استنادًا إلى طريقة الترتيب الحالية). |
حدث ValueChanged
يمكنك استخدام حدث ValueChanged للاشتراك في التغييرات التي تطرأ على المحتوى في مسار معيّن. يتم تشغيل هذا الحدث مرة واحدة عند ربط أداة معالجة الأحداث، ومرة أخرى في كل مرة تتغير فيها البيانات، بما في ذلك البيانات الفرعية. يتم تمرير لقطة إلى دالة معاودة الاتصال الخاصة بالحدث، وتحتوي هذه اللقطة على جميع البيانات في ذلك الموقع، بما في ذلك بيانات العناصر التابعة. إذا لم تتوفّر بيانات، ستكون اللقطة المعروضة null.
يوضّح المثال التالي لعبة تسترجع نتائج لوحة الصدارة من قاعدة البيانات:
FirebaseDatabase.DefaultInstance .GetReference("Leaders") .ValueChanged += HandleValueChanged; } void HandleValueChanged(object sender, ValueChangedEventArgs args) { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } // Do something with the data in args.Snapshot }
يحتوي ValueChangedEventArgs على DataSnapshot يحتوي على البيانات في الموقع الجغرافي المحدّد في قاعدة البيانات في وقت وقوع الحدث. يؤدي استدعاء Value على لقطة إلى عرض Dictionary<string, object> يمثّل البيانات.
إذا لم تتوفّر أي بيانات في الموقع الجغرافي، سيؤدي طلب Value إلى عرض null.
في هذا المثال، يتم فحص args.DatabaseError أيضًا لمعرفة ما إذا تم إلغاء القراءة. على سبيل المثال، يمكن إلغاء عملية قراءة إذا لم يكن لدى العميل إذن بالقراءة من موقع قاعدة بيانات Firebase. ستوضّح DatabaseError سبب حدوث الخطأ.
يمكنك لاحقًا إلغاء الاشتراك في الحدث باستخدام أي DatabaseReference يتضمّن المسار نفسه. تكون مثيلات DatabaseReference مؤقتة ويمكن اعتبارها طريقة للوصول إلى أي مسار وطلب بحث.
FirebaseDatabase.DefaultInstance .GetReference("Leaders") .ValueChanged -= HandleValueChanged; // unsubscribe from ValueChanged. }
الأحداث الثانوية
يتم تشغيل أحداث العناصر التابعة استجابةً لعمليات معيّنة تحدث للعناصر التابعة لعقدة من عملية مثل إضافة عنصر تابع جديد من خلال الطريقة Push() أو تعديل عنصر تابع من خلال الطريقة UpdateChildrenAsync(). ويمكن أن يكون كلّ من هذه العناصر مفيدًا للاستماع إلى التغييرات التي تطرأ على عقدة معيّنة في قاعدة بيانات. على سبيل المثال، قد تستخدم إحدى الألعاب هذه الطرق معًا لمراقبة النشاط في تعليقات جلسة اللعب، كما هو موضّح أدناه:
var ref = FirebaseDatabase.DefaultInstance .GetReference("GameSessionComments"); ref.ChildAdded += HandleChildAdded; ref.ChildChanged += HandleChildChanged; ref.ChildRemoved += HandleChildRemoved; ref.ChildMoved += HandleChildMoved; } void HandleChildAdded(object sender, ChildChangedEventArgs args) { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } // Do something with the data in args.Snapshot } void HandleChildChanged(object sender, ChildChangedEventArgs args) { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } // Do something with the data in args.Snapshot } void HandleChildRemoved(object sender, ChildChangedEventArgs args) { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } // Do something with the data in args.Snapshot } void HandleChildMoved(object sender, ChildChangedEventArgs args) { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } // Do something with the data in args.Snapshot }
يُستخدَم حدث ChildAdded عادةً لاسترداد قائمة بالعناصر في قاعدة بيانات Firebase. يتم إطلاق الحدث ChildAdded مرة واحدة لكل عنصر فرعي حالي، ثم مرة أخرى في كل مرة تتم فيها إضافة عنصر فرعي جديد إلى المسار المحدّد. يتم تمرير لقطة إلى المستمع تحتوي على بيانات العنصر الفرعي الجديد.
يتم تنشيط الحدث ChildChanged في كل مرة يتم فيها تعديل عقدة فرعية، ويشمل ذلك أي تعديلات على العناصر التابعة للعقدة الفرعية. ويتم استخدام هذا الحدث عادةً مع الحدثين ChildAdded وChildRemoved للاستجابة للتغييرات التي تطرأ على قائمة عناصر. يحتوي اللقطة التي يتم تمريرها إلى متتبِّع الأحداث على البيانات المعدَّلة للعنصر الفرعي.
يتم تشغيل الحدث ChildRemoved عند إزالة عنصر فرعي مباشر، ويتم استخدامه عادةً مع عمليات الرجوع ChildAdded وChildChanged. يحتوي اللقطة التي تم تمريرها إلى عملية الرجوع الخاصة بالحدث على بيانات العنصر الفرعي الذي تمت إزالته.
يتم تشغيل الحدث ChildMoved كلما تم إنشاء الحدث ChildChanged من خلال تعديل يؤدي إلى إعادة ترتيب العنصر الفرعي. ويتم استخدامه مع البيانات التي يتم ترتيبها باستخدام OrderByChild أو OrderByValue.
فرز البيانات وتصفيتها
يمكنك استخدام فئة Realtime Database Query لاسترداد البيانات التي تم ترتيبها حسب المفتاح أو القيمة أو قيمة عنصر فرعي. يمكنك أيضًا فلترة النتيجة المرتبة لتحديد عدد معيّن من النتائج أو نطاق من المفاتيح أو القيم.
ترتيب البيانات
لاسترداد البيانات التي تم فرزها، ابدأ بتحديد إحدى طرق الترتيب حسب لتحديد كيفية ترتيب النتائج:
| الطريقة | الاستخدام |
|---|---|
OrderByChild() |
ترتيب النتائج حسب قيمة مفتاح فرعي محدّد |
OrderByKey()
| ترتيب النتائج حسب المفاتيح الفرعية |
OrderByValue() |
ترتيب النتائج حسب القيم الفرعية |
يمكنك استخدام طريقة ترتيب واحدة فقط في كل مرة، ويؤدي استدعاء طريقة ترتيب عدة مرات في طلب البحث نفسه إلى حدوث خطأ.
يوضّح المثال التالي كيف يمكنك الاشتراك في قائمة الصدارة الخاصة بالنتائج المرتبة حسب النتيجة.
FirebaseDatabase.DefaultInstance .GetReference("Leaders").OrderByChild("score") .ValueChanged += HandleValueChanged; } void HandleValueChanged(object sender, ValueChangedEventArgs args) { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } // Do something with the data in args.Snapshot }
يحدّد هذا الرمز طلب بحث، وعند دمجه مع متتبِّع أحداث valuechanged، تتم مزامنة العميل مع قائمة الصدارة في قاعدة البيانات، ويتم ترتيبها حسب نتيجة كل إدخال. يمكنك الاطّلاع على مزيد من المعلومات حول تنظيم بياناتك بكفاءة في مقالة تنظيم قاعدة البيانات.
يحدّد طلب الطريقة OrderByChild() مفتاح العنصر الفرعي لترتيب النتائج حسبه. في هذه الحالة، يتم ترتيب النتائج حسب قيمة "score"
القيمة في كل عنصر فرعي. لمزيد من المعلومات حول كيفية ترتيب أنواع البيانات الأخرى، اطّلِع على كيفية ترتيب بيانات الطلبات.
تصفية البيانات
لفلترة البيانات، يمكنك الجمع بين أي من طرق الحد أو النطاق وطريقة order-by عند إنشاء طلب بحث.
| الطريقة | الاستخدام |
|---|---|
LimitToFirst() |
تضبط هذه السمة الحد الأقصى لعدد العناصر المطلوب عرضها من بداية القائمة المرتبة للنتائج. |
LimitToLast() |
تضبط هذه السمة الحد الأقصى لعدد العناصر المطلوب عرضها من نهاية قائمة النتائج المرتبة. |
StartAt() |
عرض العناصر الأكبر من المفتاح أو القيمة المحدّدة أو التي تساويها، وذلك استنادًا إلى طريقة الترتيب المحدّدة |
EndAt() |
عرض السلع التي تقلّ عن المفتاح أو القيمة المحدّدة أو تساويها استنادًا إلى طريقة الترتيب المحدّدة |
EqualTo() |
عرض العناصر التي تساوي المفتاح أو القيمة المحدّدة استنادًا إلى طريقة الترتيب حسب التي تم اختيارها |
على عكس طرق الترتيب حسب، يمكنك الجمع بين عدة دوال للحدّ أو النطاق.
على سبيل المثال، يمكنك الجمع بين الطريقتَين StartAt() وEndAt() لحصر النتائج في نطاق محدّد من القيم.
حتى عندما يكون هناك تطابق واحد فقط مع طلب البحث، تظل اللقطة عبارة عن قائمة، ولكنها تحتوي على عنصر واحد فقط.
وضع حدّ لعدد النتائج
يمكنك استخدام الطريقتَين LimitToFirst() وLimitToLast() لضبط الحد الأقصى لعدد العناصر الفرعية التي تتم مزامنتها مع دالة ردّ الاتصال المحدّدة. على سبيل المثال، إذا استخدمت LimitToFirst() لضبط حد يبلغ 100، لن تتلقّى في البداية سوى ما يصل إلى 100 دالة ردّ اتصال ChildAdded. وإذا كان لديك أقل من 100 عنصر مخزّن في قاعدة بيانات Firebase، سيتم تشغيل دالة ردّ اتصال ChildAdded لكل عنصر.
عندما تتغير العناصر، ستتلقّى عمليات ردّ الاتصال ChildAdded للعناصر التي تدخل طلب البحث وعمليات ردّ الاتصال ChildRemoved للعناصر التي تخرج منه، وذلك ليبقى العدد الإجمالي 100.
على سبيل المثال، تعرض التعليمة البرمجية أدناه أعلى نتيجة من قائمة الصدارة:
FirebaseDatabase.DefaultInstance .GetReference("Leaders").OrderByChild("score").LimitToLast(1) .ValueChanged += HandleValueChanged; } void HandleValueChanged(object sender, ValueChangedEventArgs args) { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } // Do something with the data in args.Snapshot }
الفلترة حسب المفتاح أو القيمة
يمكنك استخدام StartAt() وEndAt() وEqualTo() لاختيار نقاط بداية ونهاية وتكافؤ عشوائية للطلبات.
يمكن أن يكون ذلك مفيدًا لتقسيم البيانات إلى صفحات أو العثور على عناصر تتضمّن عناصر فرعية لها قيمة محدّدة.
كيفية ترتيب بيانات طلب البحث
يوضّح هذا القسم كيفية ترتيب البيانات حسب كل طريقة من طرق الترتيب في فئة Query.
OrderByChild
عند استخدام OrderByChild()
، يتم ترتيب البيانات التي تحتوي على مفتاح العنصر الفرعي المحدّد على النحو التالي:
- يتم عرض الأطفال الذين لديهم قيمة
nullلمفتاح الطفل المحدّد أولاً. - يأتي بعد ذلك الأطفال الذين لديهم القيمة
falseلمفتاح الطفل المحدّد. إذا كان لدى عدة عناصر فرعية القيمةfalse، يتم ترتيبها معجميًا حسب المفتاح. - يأتي بعد ذلك الأطفال الذين لديهم القيمة
trueلمفتاح الطفل المحدّد. إذا كان لدى عدة عناصر فرعية القيمةtrue، يتم ترتيبها معجميًا حسب المفتاح. - تأتي بعد ذلك العناصر الفرعية التي تتضمّن قيمة رقمية، ويتم ترتيبها بترتيب تصاعدي. إذا كان لدى عدة عناصر فرعية القيمة الرقمية نفسها لعقدة الطفل المحددة، يتم ترتيبها حسب المفتاح.
- تأتي السلاسل بعد الأرقام ويتم ترتيبها معجميًا بترتيب تصاعدي. إذا كان لدى عدة عناصر فرعية القيمة نفسها للعقدة الفرعية المحدّدة، يتم ترتيبها معجميًا حسب المفتاح.
- تأتي العناصر في النهاية ويتم ترتيبها معجميًا حسب المفتاح بترتيب تصاعدي.
OrderByKey
عند استخدام OrderByKey() لفرز بياناتك، يتم عرض البيانات بترتيب تصاعدي حسب المفتاح.
- يتم ترتيب الأطفال الذين لديهم مفتاح يمكن تحليله كعدد صحيح 32 بت أولاً بترتيب تصاعدي.
- يأتي بعد ذلك الأطفال الذين لديهم قيمة سلسلة كمفتاح، ويتم ترتيبهم معجميًا بترتيب تصاعدي.
OrderByValue
عند استخدام OrderByValue()
، يتم ترتيب العناصر الفرعية حسب قيمتها. وتكون معايير الترتيب هي نفسها الواردة في OrderByChild()، باستثناء أنّه يتم استخدام قيمة العقدة بدلاً من قيمة مفتاح عنصر فرعي محدّد.