الحصول على مرجع قاعدة بيانات
لقراءة البيانات أو كتابتها من قاعدة البيانات، تحتاج إلى مثيل من
firebase.database.Reference
:
Web
import { getDatabase } from "firebase/database"; const database = getDatabase();
Web
var database = firebase.database();
قوائم القراءة والكتابة
إلحاق البيانات بقائمة بيانات
استخدِم الطريقة push()
لإلحاق البيانات بقائمة في تطبيقات متعددة المستخدمين.
تُنشئ طريقة push()
مفتاحًا فريدًا في كل مرة تتم فيها إضافة عنصر فرعي جديد إلى
مرجع Firebase المحدّد. باستخدام مفاتيح التشفير هذه التي يتم إنشاؤها تلقائيًا لكل عنصر
جديد في القائمة، يمكن لعدة عملاء إضافة عناصر فرعية إلى الموقع الجغرافي نفسه
في الوقت نفسه بدون حدوث تعارضات في الكتابة. يستند المفتاح الفريد الذي تم إنشاؤه بواسطة push()
إلى طابع زمني، لذلك يتم ترتيب عناصر القائمة تلقائيًا
بشكل كرونولوجي.
يمكنك استخدام إشارة إلى البيانات الجديدة التي تعرضها الطريقة push()
للحصول على
قيمة مفتاح الطفل الذي تم إنشاؤه تلقائيًا أو ضبط البيانات للطفل. يحتوي الحقل
.key
في مرجع push()
على المفتاح الذي تم إنشاؤه تلقائيًا.
يمكنك استخدام مفاتيح الربط هذه التي يتم إنشاؤها تلقائيًا لتبسيط تسطيح بنية البيانات. لمزيد من المعلومات، يُرجى الاطّلاع على مثال توسيع نطاق البيانات.
على سبيل المثال، يمكن استخدام push()
لإضافة مشاركة جديدة إلى قائمة المشاركات
في تطبيق اجتماعي:
Web
import { getDatabase, ref, push, set } from "firebase/database"; // Create a new post reference with an auto-generated id const db = getDatabase(); const postListRef = ref(db, 'posts'); const newPostRef = push(postListRef); set(newPostRef, { // ... });
Web
// Create a new post reference with an auto-generated id var postListRef = firebase.database().ref('posts'); var newPostRef = postListRef.push(); newPostRef.set({ // ... });
الاستماع إلى أحداث الطفل
يتم بدء أحداث العناصر الفرعية استجابةً لعمليات معيّنة تحدث ل
العناصر الفرعية لعقدة من عملية، مثل إضافة عنصر فرعي جديد من خلال الأسلوب
push()
أو تعديل عنصر فرعي من خلال الأسلوب update()
.
الحدث | الاستخدام المعتاد |
---|---|
child_added |
استرداد قوائم بالعناصر أو الاستماع إلى الإضافات إلى قائمة بالعناصر يتم بدء هذا الحدث مرة واحدة لكل عنصر فرعي حالي ثم مرة أخرى في كل مرة تتم فيها إضافة عنصر فرعي جديد إلى المسار المحدّد. يتم إرسال لقطة إلى المستمع تحتوي على بيانات الطفل الجديد. |
child_changed |
الاستماع إلى التغييرات في العناصر ضمن قائمة يتم تشغيل هذا الحدث في أي وقت يتم فيه تعديل عقدة فرعية. ويشمل ذلك أي تعديلات على العناصر الفرعية للعقدة الفرعية. تحتوي اللقطة التي تم تمريرها إلى مستمع الحدث على البيانات المعدَّلة للعنصر الطفل. |
child_removed |
استمع إلى العناصر التي تتم إزالتها من قائمة. يتم بدء هذا الحدث عند إزالة عنصر فرعي مباشر.تحتوي اللقطة التي تم تمريرها إلى كتلة الاستدعاء على بيانات العنصر الفرعي الذي تمّت إزالته. |
child_moved |
استمع إلى التغييرات في ترتيب العناصر في قائمة مرتبة.
تتبع أحداث child_moved دائمًا حدث
child_changed الذي أدّى إلى
تغيير ترتيب السلعة (استنادًا إلى طريقة الترتيب الحالية).
|
يمكن أن يكون كلّ من هذه الأدوات مفيدًا معًا للاستماع إلى التغييرات التي تطرأ على node معيّنة في قاعدة بيانات. على سبيل المثال، قد يستخدم تطبيق التدوين الاجتماعي هذه الطرق معًا لمراقبة النشاط في تعليقات إحدى المشاركات، كما هو موضّح أدناه:
Web
import { getDatabase, ref, onChildAdded, onChildChanged, onChildRemoved } from "firebase/database"; const db = getDatabase(); const commentsRef = ref(db, 'post-comments/' + postId); onChildAdded(commentsRef, (data) => { addCommentElement(postElement, data.key, data.val().text, data.val().author); }); onChildChanged(commentsRef, (data) => { setCommentValues(postElement, data.key, data.val().text, data.val().author); }); onChildRemoved(commentsRef, (data) => { deleteComment(postElement, data.key); });
Web
var commentsRef = firebase.database().ref('post-comments/' + postId); commentsRef.on('child_added', (data) => { addCommentElement(postElement, data.key, data.val().text, data.val().author); }); commentsRef.on('child_changed', (data) => { setCommentValues(postElement, data.key, data.val().text, data.val().author); }); commentsRef.on('child_removed', (data) => { deleteComment(postElement, data.key); });
رصد أحداث القيم
على الرغم من أنّ رصد الأحداث الفرعية هو الطريقة المُقترَحة لقراءة قوائم البيانات، فهناك حالات يكون فيها رصد أحداث القيمة في مرجع قائمة مفيدًا.
سيؤدي إرفاق مراقب value
بقائمة بيانات إلى عرض
القائمة الكاملة للبيانات كنبذة واحدة يمكنك بعد ذلك تكرارها
للوصول إلى الأطفال الفرديين.
حتى في حال توفّر مطابقة واحدة فقط لطلب البحث، تظلّ اللقطة قائمة، ولكنها تحتوي على عنصر واحد فقط. للوصول إلى العنصر، عليك تكرار قراءة النتيجة:
Web
import { getDatabase, ref, onValue } from "firebase/database"; const db = getDatabase(); const dbRef = ref(db, '/a/b/c'); onValue(dbRef, (snapshot) => { snapshot.forEach((childSnapshot) => { const childKey = childSnapshot.key; const childData = childSnapshot.val(); // ... }); }, { onlyOnce: true });
Web
ref.once('value', (snapshot) => { snapshot.forEach((childSnapshot) => { var childKey = childSnapshot.key; var childData = childSnapshot.val(); // ... }); });
يمكن أن يكون هذا النمط مفيدًا عندما تريد جلب جميع العناصر الفرعية لقائمة في عملية واحدة، بدلاً من الاستماع إلى أحداث إضافية لإضافة عنصر فرعي.
فرز البيانات وتصفيتها
يمكنك استخدام فئة Realtime Database Query
لاسترداد البيانات التي تم ترتيبها حسب
المفتاح أو القيمة أو قيمة العنصر الفرعي. يمكنك أيضًا فلترة
النتيجة المرتبطة بعدد معيّن من النتائج أو نطاق من المفاتيح أو
القيم.
ترتيب البيانات
لاسترداد البيانات المفروَضة، ابدأ بتحديد إحدى طرق "الترتيب حسب" لتحديد كيفية ترتيب النتائج:
الطريقة | الاستخدام |
---|---|
orderByChild() |
ترتيب النتائج حسب قيمة مفتاح فرعي محدّد أو مسار فرعي متداخل |
orderByKey()
| ترتيب النتائج حسب مفاتيح العناصر الفرعية |
orderByValue() |
ترتيب النتائج حسب قيم السمات الثانوية |
يمكنك استخدام طريقة واحدة فقط لترتيب النتائج في كل مرة. يؤدي استدعاء طريقة ترتيب بالاستناد إلى عمود معيّن مرارًا وتكرارًا في طلب البحث نفسه إلى ظهور خطأ.
يوضّح المثال التالي كيفية استرداد قائمة بأحد مستخدمي Flickr أهم مشاركاته مرتبة حسب عدد النجوم:
Web
import { getDatabase, ref, query, orderByChild } from "firebase/database"; import { getAuth } from "firebase/auth"; const db = getDatabase(); const auth = getAuth(); const myUserId = auth.currentUser.uid; const topUserPostsRef = query(ref(db, 'user-posts/' + myUserId), orderByChild('starCount'));
Web
var myUserId = firebase.auth().currentUser.uid; var topUserPostsRef = firebase.database().ref('user-posts/' + myUserId).orderByChild('starCount');
يحدِّد هذا طلب بحث يتم من خلاله عند دمجه مع مستمع فرعي مزامنة العميل مع المشاركات الخاصة بالمستخدم من المسار في قاعدة البيانات استنادًا إلى معرّف المستخدم، وترتيبها حسب عدد النجوم التي حصلت عليها كل مشاركة. تُعرف تقنية استخدام المعرّفات كمفاتيح الفهرس باسم "توسيع نطاق البيانات"، ويمكنك الاطّلاع علىمزيد من المعلومات حولها في مقالة تنظيم قاعدة بياناتك.
تحدِّد الدعوة إلى طريقة orderByChild()
مفتاح الطفل لترتيب
النتائج. في هذه الحالة، يتم ترتيب المشاركات حسب قيمة "starCount"
child الخاصة بها. يمكن أيضًا ترتيب طلبات البحث حسب العناصر المُدمجة
التابعة، في حال كانت لديك بيانات بالشكل التالي:
"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
من خلال تحديد المسار النسبي للعنصر الثانوي المُدمج في طلب
orderByChild()
.
Web
import { getDatabase, ref, query, orderByChild } from "firebase/database"; const db = getDatabase(); const mostViewedPosts = query(ref(db, 'posts'), orderByChild('metrics/views'));
Web
var mostViewedPosts = firebase.database().ref('posts').orderByChild('metrics/views');
لمزيد من المعلومات عن كيفية ترتيب أنواع البيانات الأخرى، اطّلِع على كيفية ترتيب بيانات طلبات البحث.
تصفية البيانات
لفلترة البيانات، يمكنك دمج أيّ من طرق الحدّ أو النطاق مع طريقة order-by عند إنشاء طلب بحث.
الطريقة | الاستخدام |
---|---|
limitToFirst() |
تُستخدَم لضبط الحد الأقصى لعدد العناصر التي سيتم عرضها من بداية القائمة المرتبة للنتائج. |
limitToLast() |
تُستخدَم لضبط الحد الأقصى لعدد العناصر التي سيتم عرضها من نهاية قائمة النتائج مرتبةً. |
startAt() |
عرض العناصر التي تكون أكبر من أو تساوي المفتاح أو القيمة المحدّدة، استنادًا إلى طريقة الترتيب المحدّدة |
startAfter() |
عرض العناصر التي تكون أكبر من المفتاح أو القيمة المحدّدة استنادًا إلى طريقة الترتيب التي تم اختيارها |
endAt() |
عرض السلع التي تكون قيمتها أقل من أو مساوية للمفتاح أو القيمة المحدّدة، استنادًا إلى طريقة الترتيب التي تم اختيارها |
endBefore() |
عرض العناصر التي تقلّ عن المفتاح أو القيمة المحدّدة استنادًا إلى طريقة الترتيب التي تم اختيارها |
equalTo() |
عرض العناصر التي تساوي المفتاح أو القيمة المحدّدة، استنادًا إلى طريقة الترتيب التي تم اختيارها |
على عكس طرق order-by، يمكنك دمج عدّة دوالّ حدّ أو نطاق.
على سبيل المثال، يمكنك دمج الطريقتَين startAt()
وendAt()
للحدّ من
النتائج إلى نطاق محدّد من القيم.
الحد من عدد النتائج
يمكنك استخدام الطريقتَين limitToFirst()
وlimitToLast()
لتحديد
الحد الأقصى لعدد العناصر الفرعية التي سيتم مزامنتها لحدث معيّن. على سبيل المثال، إذا
كنت تستخدم limitToFirst()
لضبط حدّ أقصى يبلغ 100، لن تتلقّى في البداية سوى ما يصل إلى
100 حدث child_added
. إذا كان لديك أقل من 100 عنصر مخزّن في قاعدة بيانات
Firebase، يتمّ بدء حدث child_added
لكلّ عنصر.
عندما تتغيّر العناصر، تتلقّى child_added
حدثًا للعناصر التي تدخل
الطلب وchild_removed
حدثًا للعناصر التي تخرج منه كي يظل
إجمالي العدد 100.
يوضّح المثال التالي كيفية تحديد تطبيق التدوين مثالًا طلب بحث ل retrieving list of the 100 most recent posts by all users:
Web
import { getDatabase, ref, query, limitToLast } from "firebase/database"; const db = getDatabase(); const recentPostsRef = query(ref(db, 'posts'), limitToLast(100));
Web
var recentPostsRef = firebase.database().ref('posts').limitToLast(100);
يحدِّد هذا المثال طلب بحث فقط، ولكن لمزامنة البيانات فعليًا، يجب أن يكون لديه مستمع مرفق.
الفلترة حسب المفتاح أو القيمة
يمكنك استخدام startAt()
وstartAfter()
وendAt()
وendBefore()
و
equalTo()
لاختيار نقاط بداية وانتهاء ومعادلة عشوائية
للطلبات. يمكن أن يكون ذلك مفيدًا لتقسيم البيانات إلى صفحات أو العثور على عناصر لها عناصر فرعية
تتضمن قيمة معيّنة.
كيفية ترتيب بيانات طلبات البحث
يوضّح هذا القسم كيفية ترتيب البيانات حسب كل طريقة من طرق "الترتيب حسب" في فئة
Query
.
orderByChild
عند استخدام orderByChild()
، يتم ترتيب البيانات التي تحتوي على مفتاح فرعي محدّد
على النحو التالي:
- تظهر أولاً العناصر الفرعية التي تحتوي على قيمة
null
لمفتاح العنصر الفرعي المحدّد. - تأتي بعد ذلك القيم التي تحتوي على
false
لمفتاح الطفل المحدّد. إذا كانت قيمة عناصر متعددة هيfalse
، يتم ترتيبها ألفبائيًا حسب المفتاح. - تأتي بعد ذلك القيم التي تحتوي على
true
لمفتاح الطفل المحدّد. إذا كانت قيمة عناصر فرعية متعدّدة هيtrue
، يتم ترتيبها أبجديًا حسب المفتاح. - تأتي العناصر الفرعية التي تحتوي على قيمة رقمية بعد ذلك، ويتم ترتيبها تصاعديًا. إذا كانت عدّة عناصر فرعية لها القيمة الرقمية نفسها لعنصر فرعي محدّد، يتم ترتيبها حسب المفتاح.
- تأتي السلاسل بعد الأرقام ويتم ترتيبها أبجديًا بترتيب تصاعدي. إذا كانت عدّة عناصر فرعية لها القيمة نفسها لعنصر فرعي محدّد، يتم ترتيبها أبجديًا حسب المفتاح.
- تظهر العناصر في آخر القائمة ويتم ترتيبها أبجديًا حسب المفتاح بترتيب تصاعدي.
orderByKey
عند استخدام orderByKey()
لترتيب بياناتك، يتم عرض البيانات بترتيب تصاعدي
حسب المفتاح.
- تظهر أولاً العناصر الفرعية التي تحتوي على مفتاح يمكن تحليله كعدد صحيح 32 بت، ويتم ترتيبها تصاعديًا.
- تأتي بعد ذلك العناصر الفرعية التي تحتوي على قيمة سلسلة كمفتاح لها، ويتم ترتيبها أبجديًا بترتيب تصاعدي.
orderByValue
عند استخدام orderByValue()
، يتم ترتيب العناصر الفرعية حسب قيمتها. تكون معايير الترتيب
نفسها كما في orderByChild()
، باستثناء أنّه يتم استخدام قيمة العقدة بدلاً من قيمة مفتاح فرعي محدّد.
فصل المستمعين
تتم إزالة طلبات إعادة الاتصال من خلال استدعاء طريقة off()
في
مرجع قاعدة بيانات Firebase.
يمكنك إزالة مستمع واحد من خلال تمريره كمَعلمة إلى off()
.
يؤدي استدعاء off()
على الموقع الجغرافي بدون وسيطات إلى إزالة جميع المستمعين في ذلك
الموقع الجغرافي.
لا يؤدي استدعاء off()
في مستمع رئيسي إلى
إزالة المستمعين المسجَّلين في العقد الفرعية تلقائيًا،
ويجب أيضًا استدعاء off()
في أي مستمعين فرعيين
لإزالة طلب الاستدعاء.