العمل مع قوائم البيانات على منصات Apple

احصل على FIRDatabaseReference

لقراءة البيانات أو كتابتها من قاعدة البيانات ، تحتاج إلى مثيل FIRDatabaseReference :

سويفت

ملاحظة: منتج Firebase هذا غير متاح في هدف مقطع التطبيق.
var ref: DatabaseReference!

ref = Database.database().reference()

ج موضوعية

ملاحظة: منتج Firebase هذا غير متاح في هدف مقطع التطبيق.
@property (strong, nonatomic) FIRDatabaseReference *ref;

self.ref = [[FIRDatabase database] reference];

قوائم القراءة والكتابة

إلحاق بقائمة البيانات

استخدم طريقة childByAutoId لإلحاق البيانات بقائمة في تطبيقات متعددة المستخدمين. تنشئ طريقة childByAutoId مفتاحًا فريدًا في كل مرة تتم فيها إضافة طفل جديد إلى مرجع Firebase المحدد. باستخدام هذه المفاتيح التي تم إنشاؤها تلقائيًا لكل عنصر جديد في القائمة ، يمكن للعديد من العملاء إضافة توابع إلى نفس الموقع في نفس الوقت دون تعارض في الكتابة. يعتمد المفتاح الفريد الذي تم إنشاؤه بواسطة childByAutoId على طابع زمني ، لذلك يتم ترتيب عناصر القائمة تلقائيًا ترتيبًا زمنيًا.

يمكنك استخدام المرجع إلى البيانات الجديدة التي يتم إرجاعها بواسطة طريقة childByAutoId للحصول على قيمة مفتاح الطفل الذي تم إنشاؤه تلقائيًا أو تعيين البيانات للطفل. يؤدي استدعاء getKey على مرجع childByAutoId إلى إرجاع المفتاح الذي تم إنشاؤه تلقائيًا.

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

استمع لأحداث الأطفال

يتم تشغيل الأحداث الفرعية استجابةً لعمليات معينة تحدث لأبناء عقدة من عملية مثل إضافة طفل جديد من خلال طريقة childByAutoId أو طفل يتم تحديثه من خلال طريقة updateChildValues .

نوع الحدث استخدام نموذجي
FIRDataEventTypeChildAdded استرجع قوائم العناصر أو استمع للإضافات إلى قائمة العناصر. يتم تشغيل هذا الحدث مرة واحدة لكل طفل موجود ثم مرة أخرى في كل مرة يتم فيها إضافة طفل جديد إلى المسار المحدد. يمرر المستمع لقطة تحتوي على بيانات الطفل الجديد.
FIRDataEventTypeChildChanged استمع إلى التغييرات التي تم إجراؤها على العناصر الموجودة في القائمة. يتم تشغيل هذا الحدث في أي وقت يتم فيه تعديل عقدة فرعية. يتضمن هذا أي تعديلات على أحفاد العقدة الفرعية. تحتوي اللقطة التي تم تمريرها إلى مستمع الحدث على البيانات المحدثة للطفل.
FIRDataEventTypeChildRemoved استمع للعناصر التي يتم إزالتها من القائمة. يتم تشغيل هذا الحدث عند إزالة طفل مباشر. تحتوي اللقطة التي تم تمريرها إلى كتلة رد الاتصال على بيانات الطفل الذي تمت إزالته.
FIRDataEventTypeChildMoved استمع إلى التغييرات في ترتيب العناصر في قائمة مرتبة. يتم تشغيل هذا الحدث عندما يتسبب التحديث في إعادة ترتيب الطفل. يتم استخدامه مع البيانات التي يتم ترتيبها بواسطة queryOrderedByChild أو queryOrderedByValue .

يمكن أن يكون كل من هؤلاء معًا مفيدًا للاستماع إلى التغييرات التي تطرأ على عقدة معينة في قاعدة البيانات. على سبيل المثال ، قد يستخدم تطبيق التدوين الاجتماعي هذه الطرق معًا لمراقبة النشاط في تعليقات المنشور ، كما هو موضح أدناه:

سويفت

ملاحظة: منتج Firebase هذا غير متاح في هدف مقطع التطبيق.
// Listen for new comments in the Firebase database
commentsRef.observe(.childAdded, with: { (snapshot) -> Void in
  self.comments.append(snapshot)
  self.tableView.insertRows(
    at: [IndexPath(row: self.comments.count - 1, section: self.kSectionComments)],
    with: UITableView.RowAnimation.automatic
  )
})
// Listen for deleted comments in the Firebase database
commentsRef.observe(.childRemoved, with: { (snapshot) -> Void in
  let index = self.indexOfMessage(snapshot)
  self.comments.remove(at: index)
  self.tableView.deleteRows(
    at: [IndexPath(row: index, section: self.kSectionComments)],
    with: UITableView.RowAnimation.automatic
  )
})

ج موضوعية

ملاحظة: منتج Firebase هذا غير متاح في هدف مقطع التطبيق.
// Listen for new comments in the Firebase database
[_commentsRef
              observeEventType:FIRDataEventTypeChildAdded
              withBlock:^(FIRDataSnapshot *snapshot) {
                [self.comments addObject:snapshot];
                [self.tableView insertRowsAtIndexPaths:@[
                  [NSIndexPath indexPathForRow:self.comments.count - 1 inSection:kSectionComments]
                ]
                                      withRowAnimation:UITableViewRowAnimationAutomatic];
              }];
// Listen for deleted comments in the Firebase database
[_commentsRef
 observeEventType:FIRDataEventTypeChildRemoved
 withBlock:^(FIRDataSnapshot *snapshot) {
   int index = [self indexOfMessage:snapshot];
   [self.comments removeObjectAtIndex:index];
   [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:kSectionComments]]
                         withRowAnimation:UITableViewRowAnimationAutomatic];
 }];

استمع إلى الأحداث القيمة

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

سيؤدي إرفاق مراقب FIRDataEventTypeValue بقائمة من البيانات إلى إرجاع قائمة البيانات بأكملها باعتبارها DataSnapshot واحدة ، والتي يمكنك بعد ذلك تكرارها للوصول إلى الأطفال الفرديين.

حتى في حالة وجود تطابق واحد فقط للاستعلام ، تظل اللقطة قائمة ؛ يحتوي فقط على عنصر واحد. للوصول إلى العنصر ، تحتاج إلى تكرار النتيجة:

سويفت

ملاحظة: منتج Firebase هذا غير متاح في هدف مقطع التطبيق.
_commentsRef.observe(.value) { snapshot in
  for child in snapshot.children {
    ...
  }
}

ج موضوعية

ملاحظة: منتج Firebase هذا غير متاح في هدف مقطع التطبيق.
[_commentsRef
              observeEventType:FIRDataEventTypeValue
              withBlock:^(FIRDataSnapshot *snapshot) {
                // Loop over children
                NSEnumerator *children = [snapshot children];
                FIRDataSnapshot *child;
                while (child = [children nextObject]) {
                  // ...
                }
              }];

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

فرز البيانات وتصفيتها

يمكنك استخدام فئة Realtime Database FIRDatabaseQuery لاسترداد البيانات التي تم فرزها حسب المفتاح أو القيمة أو قيمة الطفل. يمكنك أيضًا تصفية النتيجة التي تم فرزها إلى عدد محدد من النتائج أو نطاق من المفاتيح أو القيم.

فرز البيانات

لاسترداد البيانات التي تم فرزها ، ابدأ بتحديد إحدى طرق الترتيب لتحديد كيفية ترتيب النتائج:

طريقة إستعمال
queryOrderedByKey ترتيب النتائج عن طريق المفاتيح الفرعية.
queryOrderedByValue ترتيب النتائج حسب القيم الفرعية.
queryOrderedByChild ترتيب النتائج حسب قيمة مفتاح فرعي محدد أو مسار فرعي متداخل.

يمكنك استخدام طريقة طلب واحدة فقط في كل مرة. يؤدي استدعاء طريقة ترتيب حسب عدة مرات في نفس الاستعلام إلى حدوث خطأ.

يوضح المثال التالي كيف يمكنك استرداد قائمة بأهم مشاركات المستخدم مرتبة حسب عدد النجوم:

سويفت

ملاحظة: منتج Firebase هذا غير متاح في هدف مقطع التطبيق.
// My top posts by number of stars
let myTopPostsQuery = ref.child("user-posts").child(getUid()).queryOrdered(byChild: "starCount")

ج موضوعية

ملاحظة: منتج Firebase هذا غير متاح في هدف مقطع التطبيق.
// My top posts by number of stars
FIRDatabaseQuery *myTopPostsQuery = [[[self.ref child:@"user-posts"]
                                      child:[super getUid]]
                                     queryOrderedByChild:@"starCount"];

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

يحدد استدعاء الأسلوب queryOrderedByChild لترتيب النتائج حسب. في هذا المثال ، يتم فرز المشاركات حسب قيمة العنصر "starCount" في كل مشاركة. يمكن أيضًا ترتيب الاستعلامات بواسطة العناصر الأبناء المتداخلة ، في حال كان لديك بيانات تبدو كالتالي:

"posts": {
  "ts-functions": {
    "metrics": {
      "views" : 1200000,
      "likes" : 251000,
      "shares": 1200,
    },
    "title" : "Why you should use TypeScript for writing Cloud Functions",
    "author": "Doug",
  },
  "android-arch-3": {
    "metrics": {
      "views" : 900000,
      "likes" : 117000,
      "shares": 144,
    },
    "title" : "Using Android Architecture Components with Firebase Realtime Database (Part 3)",
    "author": "Doug",
  }
},

في هذه الحالة ، يمكننا ترتيب عناصر قائمتنا حسب القيم المتداخلة تحت مفتاح metrics عن طريق تحديد المسار النسبي للطفل المتداخل في queryOrderedByChild طلبنا طلبنا.

سويفت

ملاحظة: منتج Firebase هذا غير متاح في هدف مقطع التطبيق.
 
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")

ج موضوعية

ملاحظة: منتج Firebase هذا غير متاح في هدف مقطع التطبيق.
 
FIRDatabaseQuery *postsByMostPopular = [[ref child:@"posts"] queryOrderedByChild:@"metrics/views"];

لمزيد من المعلومات حول كيفية ترتيب أنواع البيانات الأخرى ، راجع كيفية ترتيب بيانات الاستعلام .

تصفية البيانات

لتصفية البيانات ، يمكنك دمج أي من أساليب الحد أو النطاق مع طريقة الترتيب حسب عند إنشاء استعلام.

طريقة إستعمال
queryLimitedToFirst يضبط الحد الأقصى لعدد العناصر المراد إرجاعها من بداية قائمة النتائج المرتبة.
queryLimitedToLast يضبط الحد الأقصى لعدد العناصر المراد إرجاعها من نهاية قائمة النتائج المرتبة.
queryStartingAtValue إرجاع العناصر الأكبر من أو تساوي المفتاح أو القيمة المحددة ، اعتمادًا على طريقة الترتيب حسب المختار.
queryStartingAfterValue إرجاع العناصر الأكبر من المفتاح أو القيمة المحددة ، بناءً على طريقة الترتيب التي تم اختيارها.
queryEndingAtValue إرجاع العناصر التي تقل عن أو تساوي المفتاح أو القيمة المحددة ، بناءً على طريقة الترتيب التي تم اختيارها.
queryEndingBeforeValue إرجاع العناصر الأقل من المفتاح أو القيمة المحددة ، اعتمادًا على طريقة الترتيب التي تم اختيارها.
queryEqualToValue إرجاع العناصر التي تساوي المفتاح أو القيمة المحددة ، اعتمادًا على طريقة الترتيب التي تم اختيارها.

على عكس طرق الترتيب حسب ، يمكنك الجمع بين عدة وظائف حد أو نطاق. على سبيل المثال ، يمكنك دمج queryStartingAtValue و queryEndingAtValue لتقييد النتائج بنطاق محدد من القيم.

حدد عدد النتائج

يمكنك استخدام queryLimitedToFirst و queryLimitedToLast لتعيين الحد الأقصى لعدد الأطفال المراد مزامنتهم لاستدعاء معين. على سبيل المثال ، إذا كنت تستخدم queryLimitedToFirst لتعيين حد 100 ، فإنك في البداية تتلقى فقط ما يصل إلى 100 رد FIRDataEventTypeChildAdded . إذا كان لديك أقل من 100 عنصر مخزّن في قاعدة بيانات Firebase ، فسيتم تنشيط رد FIRDataEventTypeChildAdded لكل عنصر.

عندما تتغير العناصر ، تتلقى عمليات رد FIRDataEventTypeChildAdded للعناصر التي تدخل الاستعلام و FIRDataEventTypeChildRemoved للعناصر التي تسقط منه بحيث يبقى العدد الإجمالي عند 100.

يوضح المثال التالي كيف يمكن لتطبيق تدوين كمثال استرداد قائمة بأحدث 100 منشور بواسطة جميع المستخدمين:

سويفت

ملاحظة: منتج Firebase هذا غير متاح في هدف مقطع التطبيق.
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
let recentPostsQuery = (ref?.child("posts").queryLimited(toFirst: 100))!

ج موضوعية

ملاحظة: منتج Firebase هذا غير متاح في هدف مقطع التطبيق.
// Last 100 posts, these are automatically the 100 most recent
// due to sorting by push() keys
FIRDatabaseQuery *recentPostsQuery = [[self.ref child:@"posts"] queryLimitedToFirst:100];

تصفية حسب المفتاح أو القيمة

يمكنك استخدام queryStartingAtValue ، و queryStartingAfterValue ، و queryEndingAtValue ، و queryEndingBeforeValue ، و queryEqualToValue في اختيار نقاط بداية ونهاية وتكافؤ عشوائية للاستعلامات. يمكن أن يكون هذا مفيدًا في ترقيم البيانات أو البحث عن عناصر لها قيمة محددة.

كيف يتم ترتيب البيانات الاستعلام

يشرح هذا القسم كيف يتم فرز البيانات حسب كل طريقة ترتيب حسب في فئة FIRDatabaseQuery .

queryOrderedByKey

عند استخدام queryOrderedByKey لفرز بياناتك ، يتم إرجاع البيانات بترتيب تصاعدي حسب المفتاح.

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

queryOrderedByValue

عند استخدام queryOrderedByValue ، يتم ترتيب العناصر الفرعية حسب قيمتها. معايير الترتيب هي نفسها الموجودة في queryOrderedByChild ، باستثناء قيمة العقدة المستخدمة بدلاً من قيمة المفتاح الفرعي المحدد.

queryOrderedByChild

عند استخدام queryOrderedByChild ، يتم ترتيب البيانات التي تحتوي على المفتاح الفرعي المحدد على النحو التالي:

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

افصل المستمعين

لا يتوقف المراقبون تلقائيًا عن مزامنة البيانات عندما تترك ViewController . إذا لم تتم إزالة المراقب بشكل صحيح ، فسيستمر في مزامنة البيانات مع الذاكرة المحلية وسيحتفظ بأي كائنات تم التقاطها في إغلاق معالج الحدث ، مما قد يتسبب في حدوث تسرب للذاكرة. عندما لا تكون هناك حاجة إلى مراقب ، قم بإزالته بتمرير FIRDatabaseHandle المرتبط إلى طريقة removeObserverWithHandle .

عند إضافة كتلة رد اتصال إلى مرجع ، يتم إرجاع FIRDatabaseHandle . يمكن استخدام هذه المقابض لإزالة كتلة رد الاتصال.

إذا تمت إضافة مستمعين متعددين إلى مرجع قاعدة البيانات ، فسيتم استدعاء كل مستمع عند رفع الحدث. لإيقاف مزامنة البيانات في هذا الموقع ، يجب عليك إزالة جميع المراقبين في موقع ما عن طريق استدعاء طريقة removeAllObservers .

لا يؤدي استدعاء removeObserverWithHandle أو removeAllObservers على المستمع إلى إزالة المستمعين المسجلين في العقد التابعة له تلقائيًا ؛ يجب عليك أيضًا تتبع تلك المراجع أو المقابض لإزالتها.

الخطوات التالية