دریافت مرجع پایگاه داده
برای خواندن یا نوشتن دادهها از پایگاه داده، به یک نمونه از 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 | بازیابی لیست آیتمها یا گوش دادن به موارد اضافه شده به لیست آیتمها. این رویداد یک بار برای هر فرزند موجود و سپس هر بار که فرزند جدیدی به مسیر مشخص شده اضافه میشود، فعال میشود. به شنونده یک snapshot حاوی دادههای فرزند جدید ارسال میشود. |
child_changed | به تغییرات در موارد موجود در یک لیست گوش دهید. این رویداد هر زمان که یک گره فرزند تغییر کند، فعال میشود. این شامل هرگونه تغییر در فرزندان گره فرزند نیز میشود. تصویر لحظهای ارسال شده به شنونده رویداد، حاوی دادههای بهروزرسانی شده برای فرزند است. |
child_removed | به حذف شدن آیتمها از یک لیست گوش دهید. این رویداد زمانی فعال میشود که یک فرزند فوری حذف شود. تصویر لحظهای ارسال شده به بلوک فراخوانی شامل دادههای فرزند حذف شده است. |
child_moved | به تغییرات در ترتیب آیتمها در یک لیست مرتب گوش دهید. رویدادهای child_moved همیشه پس از رویداد child_changed که باعث تغییر ترتیب آیتم شده است (بر اساس روش مرتبسازی فعلی شما) رخ میدهند. |
هر یک از این روشها در کنار هم میتوانند برای گوش دادن به تغییرات یک گره خاص در پایگاه داده مفید باشند. به عنوان مثال، یک برنامه وبلاگ نویسی اجتماعی ممکن است از این روشها با هم برای نظارت بر فعالیت در نظرات یک پست استفاده کند، همانطور که در زیر نشان داده شده است:
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 به لیستی از دادهها، کل لیست دادهها را به عنوان یک تصویر لحظهای واحد برمیگرداند که میتوانید برای دسترسی به فرزندان منفرد، آن را مرور کنید.
حتی وقتی فقط یک مورد منطبق برای کوئری وجود دارد، snapshot هنوز یک لیست است؛ فقط شامل یک مورد است. برای دسترسی به مورد، باید روی نتیجه حلقه بزنید:
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 برای بازیابی دادههای مرتبشده بر اساس کلید، مقدار یا مقدار یک فرزند استفاده کنید. همچنین میتوانید نتیجه مرتبشده را به تعداد مشخصی از نتایج یا طیف وسیعی از کلیدها یا مقادیر فیلتر کنید.
مرتبسازی دادهها
برای بازیابی دادههای مرتبشده، با مشخص کردن یکی از روشهای order-by برای تعیین نحوهی مرتبسازی نتایج شروع کنید:
| روش | کاربرد |
|---|---|
orderByChild() | نتایج را بر اساس مقدار یک کلید فرزند مشخص شده یا مسیر فرزند تو در تو مرتب میکند. | orderByKey() | نتایج را بر اساس کلیدهای فرزند مرتب کنید. |
orderByValue() | نتایج را بر اساس مقادیر فرزند مرتب کنید. |
شما فقط میتوانید از یک متد order-by در یک زمان استفاده کنید. فراخوانی چندین بارهی یک متد order-by در یک query باعث ایجاد خطا میشود.
مثال زیر نشان میدهد که چگونه میتوانید لیستی از برترین پستهای یک کاربر را که بر اساس تعداد ستارههایش مرتب شدهاند، بازیابی کنید:
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');
این یک کوئری تعریف میکند که وقتی با یک شنونده فرزند ترکیب میشود، کلاینت را با پستهای کاربر از مسیر موجود در پایگاه داده بر اساس شناسه کاربری آنها، که بر اساس تعداد ستارههایی که هر پست دریافت کرده است، مرتب شده است، همگامسازی میکند. این تکنیک استفاده از شناسهها به عنوان کلیدهای اندیس، data fan out نامیده میشود، میتوانید اطلاعات بیشتر در مورد آن را در Structure Your Database بخوانید.
فراخوانی متد orderByChild() کلید فرزند را برای مرتبسازی نتایج بر اساس آن مشخص میکند. در این حالت، پستها بر اساس مقدار فرزند "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 مرتب کنیم، این کار با مشخص کردن مسیر نسبی به فرزند تو در تو در فراخوانی 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');
برای اطلاعات بیشتر در مورد نحوه مرتبسازی انواع دادههای دیگر، به نحوه مرتبسازی دادههای پرسوجو مراجعه کنید.
فیلتر کردن دادهها
برای فیلتر کردن دادهها، میتوانید هنگام ساخت یک پرسوجو، هر یک از روشهای محدودیت یا محدوده را با یک روش مرتبسازی ترکیب کنید.
| روش | کاربرد |
|---|---|
limitToFirst() | حداکثر تعداد اقلامی را که از ابتدای لیست مرتبشدهی نتایج برگردانده میشوند، تنظیم میکند. |
limitToLast() | حداکثر تعداد اقلامی را که از انتهای لیست مرتبشدهی نتایج برگردانده میشوند، تنظیم میکند. |
startAt() | بسته به روش مرتبسازی انتخابشده، اقلامی را که بزرگتر یا مساوی کلید یا مقدار مشخصشده هستند، برمیگرداند. |
startAfter() | بسته به روش مرتبسازی انتخابشده، اقلامی را که بزرگتر از کلید یا مقدار مشخصشده هستند، برمیگرداند. |
endAt() | بسته به روش مرتبسازی انتخابشده، اقلام کوچکتر یا مساوی با کلید یا مقدار مشخصشده را برمیگرداند. |
endBefore() | بسته به روش مرتبسازی انتخابشده، اقلامی را که کمتر از کلید یا مقدار مشخصشده هستند، برمیگرداند. |
equalTo() | بسته به روش مرتبسازی انتخابشده، اقلامی را که برابر با کلید یا مقدار مشخصشده هستند، برمیگرداند. |
برخلاف متدهای مرتبسازی بر اساس، میتوانید چندین تابع محدودکننده یا محدودهای را با هم ترکیب کنید. برای مثال، میتوانید متدهای startAt() و endAt() را برای محدود کردن نتایج به یک محدوده مشخص از مقادیر ترکیب کنید.
محدود کردن تعداد نتایج
شما میتوانید از متدهای limitToFirst() و limitToLast() برای تعیین حداکثر تعداد فرزندهایی که باید برای یک رویداد مشخص همگامسازی شوند، استفاده کنید. برای مثال، اگر از limitToFirst() برای تعیین محدودیت ۱۰۰ استفاده کنید، در ابتدا فقط تا ۱۰۰ رویداد child_added دریافت خواهید کرد. اگر کمتر از ۱۰۰ مورد در پایگاه داده Firebase خود ذخیره کرده باشید، یک رویداد child_added برای هر مورد فعال میشود.
با تغییر آیتمها، برای آیتمهایی که وارد کوئری میشوند، رویدادهای child_added و برای آیتمهایی که از آن حذف میشوند، رویدادهای child_removed دریافت میکنید تا تعداد کل روی ۱۰۰ باقی بماند.
مثال زیر نشان میدهد که چگونه example blogging app یک کوئری برای بازیابی لیستی از ۱۰۰ پست اخیر همه کاربران تعریف میکند:
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);
این مثال فقط یک کوئری تعریف میکند، برای همگامسازی دادهها، به یک شنونده (listener) متصل نیاز دارد.
فیلتر بر اساس کلید یا مقدار
شما میتوانید از startAt() ، startAfter() ، endAt() ، endBefore() و equalTo() برای انتخاب نقاط شروع، پایان و همارزی دلخواه برای کوئریها استفاده کنید. این میتواند برای صفحهبندی دادهها یا یافتن مواردی با فرزندهایی که مقدار خاصی دارند مفید باشد.
نحوه مرتب سازی داده های پرس و جو
این بخش توضیح میدهد که چگونه دادهها بر اساس هر یک از متدهای order-by در کلاس Query مرتب میشوند.
orderByChild
هنگام استفاده از orderByChild() ، دادههایی که حاوی کلید فرزند مشخص شده هستند به صورت زیر مرتب میشوند:
- فرزندانی که مقدار
nullبرای کلید فرزند مشخص شده دارند، در اولویت قرار میگیرند. - فرزندانی که مقدار
falseبرای کلید فرزند مشخص شده دارند، در مرحله بعد قرار میگیرند. اگر چندین فرزند مقدارfalseداشته باشند، بر اساس کلید به صورت لغوی مرتب میشوند. - فرزندانی که مقدار
trueبرای کلید فرزند مشخص شده دارند، در مرحله بعد قرار میگیرند. اگر چندین فرزند مقدارtrueداشته باشند، بر اساس کلید به صورت لغوی مرتب میشوند. - فرزندانی که مقدار عددی دارند، در مرحله بعد قرار میگیرند و به ترتیب صعودی مرتب میشوند. اگر چندین فرزند برای گره فرزند مشخص شده، مقدار عددی یکسانی داشته باشند، بر اساس کلید مرتب میشوند.
- رشتهها بعد از اعداد میآیند و به صورت لغوی و به ترتیب صعودی مرتب میشوند. اگر چندین فرزند برای گره فرزند مشخص شده مقدار یکسانی داشته باشند، بر اساس کلید به صورت لغوی مرتب میشوند.
- اشیاء در آخر میآیند و از نظر لغوی بر اساس کلید به ترتیب صعودی مرتب میشوند.
orderByKey
هنگام استفاده از orderByKey() برای مرتبسازی دادهها، دادهها بر اساس کلید به صورت صعودی مرتب میشوند.
- فرزندانی که کلیدی دارند که میتواند به عنوان یک عدد صحیح ۳۲ بیتی تجزیه شود، ابتدا به صورت صعودی مرتب میشوند.
- فرزندانی که کلیدشان یک مقدار رشتهای است، در مرحلهی بعد قرار میگیرند و به صورت لغوی و به ترتیب صعودی مرتب شدهاند.
orderByValue
هنگام استفاده از orderByValue() ، فرزندان بر اساس مقدارشان مرتب میشوند. معیارهای مرتبسازی مشابه orderByChild() هستند، با این تفاوت که به جای مقدار یک کلید فرزند مشخص، از مقدار گره استفاده میشود.
جدا کردن شنوندگان
فراخوانیهای برگشتی با فراخوانی متد off() در مرجع پایگاه داده Firebase شما حذف میشوند.
شما میتوانید با ارسال یک شنونده به عنوان پارامتر به off() آن را حذف کنید. فراخوانی off() در مکانی که هیچ آرگومانی ندارد، تمام شنوندههای موجود در آن مکان را حذف میکند.
فراخوانی تابع off() در یک شنوندهی والد، شنوندههای ثبتشده در گرههای فرزند آن را بهطور خودکار حذف نمیکند؛ همچنین باید off() در هر شنوندهی فرزندی فراخوانی شود تا فراخوانی برگشتی حذف شود.