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

الحصول على FIRDatabaseReference

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

Swift

ملاحظة: لا يتوفّر منتج Firebase هذا في هدف App Clip.
var ref: DatabaseReference!

ref = Database.database().reference()

Objective-C

ملاحظة: لا يتوفّر منتج Firebase هذا في هدف App Clip.
@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.

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

Swift

ملاحظة: لا يتوفّر منتج Firebase هذا في هدف App Clip.
// 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
  )
})

Objective-C

ملاحظة: لا يتوفّر منتج Firebase هذا في هدف App Clip.
// 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 بقائمة بيانات إلى عرض قائمة كاملة بالبيانات باعتبارها لقطة بيانات واحدة، والتي يمكنك بعد ذلك تكرارها إلى الوصول إلى أطفال معينين.

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

Swift

ملاحظة: لا يتوفّر منتج Firebase هذا في هدف App Clip.
_commentsRef.observe(.value) { snapshot in
  for child in snapshot.children {
    ...
  }
}

Objective-C

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

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

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

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

فرز البيانات

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

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

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

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

Swift

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

Objective-C

ملاحظة: لا يتوفّر منتج Firebase هذا في هدف App Clip.
// 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.

Swift

ملاحظة: لا يتوفّر منتج Firebase هذا في هدف App Clip.
 
let postsByMostPopular = ref.child("posts").queryOrdered(byChild: "metrics/views")

Objective-C

ملاحظة: لا يتوفّر منتج Firebase هذا في هدف App Clip.
 
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 مشاركة من جميع المستخدمين:

Swift

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

Objective-C

ملاحظة: لا يتوفّر منتج Firebase هذا في هدف App Clip.
// 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 من خلال مستمع عدم إزالة المستمعين المسجَّلين في العُقد الفرعية تلقائيًا يجب عليك أيضًا تتبُّع هذه المراجع أو الأسماء المعرِّفة لإزالتها.

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