يتناول هذا المستند أساسيات استرداد البيانات وكيفية ترتيب بيانات Firebase وتصفيتها.
قبل البدء
قبل أن تتمكّن من استخدام Realtime Database, عليك تنفيذ ما يلي:
سجِّل مشروع Unity الخاص بك وأعدَّه لاستخدام Firebase.
إذا كان مشروع Unity يستخدم Firebase حاليًا، يكون قد تم تسجيله وإعداده لاستخدام Firebase.
إذا لم يكن لديك مشروع Unity، يمكنك تنزيل نموذج تطبيق.
أضِف حزمة Firebase Unity SDK (تحديدًا
FirebaseDatabase.unitypackage) إلى مشروع Unity الخاص بك.
يُرجى العِلم أنّ إضافة Firebase إلى مشروع Unity تتضمّن مهامًا في كلّ من الـ Firebase console ومشروع 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"
في كل عنصر ثانوي. لمزيد من المعلومات حول كيفية ترتيب أنواع البيانات الأخرى،
اطّلِع على مقالة كيفية ترتيب بيانات طلب البحث.
تصفية البيانات
لتصفية البيانات، يمكنك دمج أي من طرق الحدّ أو النطاق مع طريقة ترتيب عند إنشاء طلب بحث.
| الطريقة | الاستخدام |
|---|---|
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() ، باستثناء أنّه يتم استخدام قيمة العقدة بدلاً من قيمة مفتاح عنصر ثانوي محدّد.