جارٍ استرداد البيانات

تتناول هذه المستندات أساسيات استرداد البيانات وكيفية ترتيب بيانات 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 =&gt {
        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 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() ، يتم ترتيب البيانات التي تحتوي على مفتاح العنصر الفرعي المحدّد على النحو التالي:

  1. تظهر أولاً العناصر الفرعية التي تكون قيمة مفتاح العنصر الفرعي المحدّد فيها null تأتي أولاً.
  2. تظهر بعد ذلك العناصر الفرعية التي تكون قيمة مفتاح العنصر الفرعي المحدّد فيها false تأتي بعد ذلك. إذا كانت قيمة مفتاح العنصر الفرعي المحدّد في عدة عناصر فرعية هي false، يتم ترتيبها معجميًا حسب المفتاح.
  3. تظهر بعد ذلك العناصر الفرعية التي تكون قيمة مفتاح العنصر الفرعي المحدّد فيها true تأتي بعد ذلك. إذا كانت قيمة مفتاح العنصر الفرعي المحدّد في عدة عناصر فرعية هي true، يتم ترتيبها معجميًا حسب المفتاح.
  4. تظهر بعد ذلك العناصر الفرعية التي لها قيمة رقمية، ويتم ترتيبها تصاعديًا. إذا كانت قيمة مفتاح العنصر الفرعي المحدّد في عدة عناصر فرعية هي نفسها، يتم ترتيبها حسب المفتاح.
  5. تظهر السلاسل بعد الأرقام ويتم ترتيبها معجميًا تصاعديًا. إذا كانت قيمة مفتاح العنصر الفرعي المحدّد في عدة عناصر فرعية هي نفسها، يتم ترتيبها معجميًا حسب المفتاح.
  6. تظهر الكائنات أخيرًا ويتم ترتيبها معجميًا حسب المفتاح تصاعديًا.

OrderByKey

عند استخدام OrderByKey() لترتيب بياناتك، يتم عرض البيانات بترتيب تصاعدي حسب المفتاح.

  1. تظهر أولاً العناصر الفرعية التي يمكن تحليل مفتاحها كعدد صحيح 32 بت، ويتم ترتيبها تصاعديًا.
  2. تظهر بعد ذلك العناصر الفرعية التي تكون قيمة مفتاحها سلسلة، ويتم ترتيبها معجميًا تصاعديًا.

OrderByValue

عند استخدام OrderByValue() ، يتم ترتيب العناصر الفرعية حسب قيمتها. تكون معايير الترتيب هي نفسها في OrderByChild() ، باستثناء أنّه يتم استخدام قيمة العقدة بدلاً من قيمة مفتاح عنصر فرعي محدّد.