این سند اصول بازیابی دادهها و نحوه سفارش و فیلتر کردن دادههای Firebase را پوشش میدهد.
قبل از شروع
مطمئن شوید برنامهتان را راهاندازی کردهاید و میتوانید به پایگاه داده دسترسی داشته باشید، همانطور که در
راهنمای Get Started توضیح داده شده است.
درحال بازیابی داده
دادههای Firebase یا ازطریق یک تماس یکباره به GetValue() یا پیوست کردن به ValueListener در مرجع FirebaseDatabase بازیابی میشود. شنونده مقدار یکبار برای وضعیت اولیه دادهها و دوباره هرزمان که دادهها تغییر کند فراخوانده میشود.
دریافت DatabaseReference
برای نوشتن دادهها در «پایگاه داده»، به نمونهای از DatabaseReference نیاز دارید:
// Get the root reference location of the database. firebase::database::DatabaseReference dbref = database->GetReference();
خواندن دادهها برای یکبار
میتوانید از روش GetValue() برای خواندن عکس آنی ایستا از
محتوا در مسیر مشخصشده استفاده کنید. نتیجه تکلیف حاوی عکس آنی
شامل همه دادههای آن مکان، ازجمله دادههای فرزند، خواهد بود. اگر دادهای وجود نداشته باشد،
عکس آنی برگرداندهشده null است.
firebase::Future<firebase::database::DataSnapshot> result = dbRef.GetReference("Leaders").GetValue();
در نقطهای که درخواست انجام شده است اما باید منتظر بمانیم تا Future تکمیل شود تا بتوانیم مقدار را بخوانیم. ازآنجاییکه بازیها معمولاً در یک حلقه اجرا میشوند و نسبتبه برنامههای دیگر کمتر مبتنی بر فراخوانی برگشتی هستند، معمولاً برای تکمیل نظرسنجی خواهید کرد.
// In the game loop that polls for the result... if (result.status() != firebase::kFutureStatusPending) { if (result.status() != firebase::kFutureStatusComplete) { LogMessage("ERROR: GetValue() returned an invalid result."); // Handle the error... } else if (result.error() != firebase::database::kErrorNone) { LogMessage("ERROR: GetValue() returned error %d: %s", result.error(), result.error_message()); // Handle the error... } else { firebase::database::DataSnapshot snapshot = result.result(); // Do something with the snapshot... } }
این کد برخیاز بررسیهای خطای پایه را نشان میدهد، برای اطلاعات بیشتر درباره بررسی خطا و روشهای تعیین زمان آماده شدن نتیجه، به مرجع firebase::Future مراجعه کنید.
گوش دادن به رویدادها
میتوانید شنوندگانی را برای مشترک شدن در تغییرات دادهها اضافه کنید:
کلاس پایه ValueListener
| پاسخ تماس | استفاده معمول |
|---|---|
OnValueChanged |
خواندن و گوش دادن به تغییرات در کل محتوای یک مسیر. |
کلاس پایه OnChildListener
OnChildAdded
| فهرستهای موارد را بازیابی کنید یا به موارد اضافهشده به فهرست موارد گوش دهید.
استفاده پیشنهادی با OnChildChanged و
OnChildRemoved برای پایش تغییرات فهرستها. |
OnChildChanged |
گوش دادن به تغییرات موارد موجود در فهرست. از OnChildAdded و OnChildRemoved برای نظارت بر تغییرات فهرستها استفاده کنید. |
OnChildRemoved |
به مواردی که از فهرست برداشته میشوند گوش دهید. از OnChildAdded و OnChildChanged برای نظارت بر تغییرات فهرستها استفاده کنید. |
OnChildMoved |
به تغییرات ترتیب موارد در فهرست مرتبشده گوش دهید.
فراخوانیهای برگشتی OnChildMoved همیشه بهدنبال فراخوانیهای برگشتی OnChildChanged میآیند چون ترتیب موارد تغییر میکند (براساس روش بهترتیب کردن فعلی شما). |
کلاس ValueListener
میتوانید از OnValueChanged callbacks برای مشترک شدن در تغییرات
محتوا در مسیر مشخصشده استفاده کنید. این فراخوانی برگشتی یکبار هنگام پیوست شدن شنونده و بار دیگر هر زمان که دادهها، ازجمله فرزندان، تغییر کنند راهاندازی میشود. فراخوانی برگشتی یک عکس آنی حاوی همه دادههای آن مکان، ازجمله دادههای فرزند، را ارسال میکند. اگر دادهای وجود نداشته باشد، عکس آنی برگرداندهشده null است.
مثال زیر نشان میدهد که چگونه یک بازی امتیازات یک جدول ردهبندی را از پایگاه داده بازیابی میکند:
class LeadersValueListener : public firebase::database::ValueListener { public: void OnValueChanged( const firebase::database::DataSnapshot& snapshot) override { // Do something with the data in snapshot... } void OnCancelled(const firebase::database::Error& error_code, const char* error_message) override { LogMessage("ERROR: LeadersValueListener canceled: %d: %s", error_code, error_message); } }; // Elsewhere in the code... LeadersValueListener* listener = new LeadersValueListener(); firebase::Future<firebase::database::DataSnapshot> result = dbRef.GetReference("Leaders").AddValueListener(listener);
نتیجه Future<DataSnapshot> حاوی دادههای موجود در مکان مشخصشده
در پایگاه داده در زمان رویداد است. فراخوانی value() در عکس آنی
Variant را که نشاندهنده دادهها است برمیگرداند.
در این مثال، روش OnCancelled نیز لغو میشود تا ببینیم آیا خواندن لغو شده است یا نه. برای مثال، اگر کارخواه اجازه خواندن از مکان پایگاه داده Firebase را نداشته باشد،
خواندن میتواند لغو شود. database::Error
دلیل عدم موفقیت را نشان میدهد.
کلاس ChildListener
رویدادهای فرزند در پاسخ به عملیات خاصی که برای فرزندان یک گره اتفاق میافتد، راهاندازی میشوند، مانند اضافه شدن یک فرزند جدید ازطریق روش PushChild() یا بهروزرسانی یک فرزند ازطریق روش UpdateChildren(). هرکدام از اینها باهم میتواند برای گوش دادن به تغییرات در گره خاصی در پایگاه داده مفید باشد. برای مثال، یک بازی ممکن است از این روشها
با هم برای نظارت بر فعالیت در نظرات یک جلسه بازی استفاده کند، همانطور که در زیر نشان داده شده است:
class SessionCommentsChildListener : public firebase::database::ChildListener { public: void OnChildAdded(const firebase::database::DataSnapshot& snapshot, const char* previous_sibling) override { // Do something with the data in snapshot ... } void OnChildChanged(const firebase::database::DataSnapshot& snapshot, const char* previous_sibling) override { // Do something with the data in snapshot ... } void OnChildRemoved( const firebase::database::DataSnapshot& snapshot) override { // Do something with the data in snapshot ... } void OnChildMoved(const firebase::database::DataSnapshot& snapshot, const char* previous_sibling) override { // Do something with the data in snapshot ... } void OnCancelled(const firebase::database::Error& error_code, const char* error_message) override { LogMessage("ERROR: SessionCommentsChildListener canceled: %d: %s", error_code, error_message); } }; // elsewhere .... SessionCommentsChildListener* listener = new SessionCommentsChildListener(); firebase::Future<firebase::database::DataSnapshot> result = dbRef.GetReference("GameSessionComments").AddChildListener(listener);
فراخوانی برگشتی OnChildAdded معمولاً برای بازیابی فهرستی از
موارد در پایگاه داده Firebase استفاده میشود. فراخوانی برگشتی OnChildAdded یکبار برای هر فرزند موجود و سپس هربار که فرزند جدیدی به مسیر مشخصشده اضافه میشود فراخوانده میشود. شنونده یک عکس آنی حاوی دادههای فرزند جدید را دریافت میکند.
هر زمان که گره فرزند اصلاح شود، فراخوانی برگشتی OnChildChanged فراخوانده میشود.
این شامل هرگونه تغییر در فرزندان گره فرزند میشود. معمولاً در ارتباط با تماسهای OnChildAdded و OnChildRemoved برای پاسخ دادن به تغییرات فهرست موارد استفاده میشود. عکس آنی ارسالشده به شنونده حاوی دادههای بهروزشده برای فرزند است.
وقتی فرزند مستقیم برداشته میشود، فراخوانی برگشتی OnChildRemoved راهاندازی میشود.
معمولاً همراه با فراخوانیهای برگشتی OnChildAdded و
OnChildChanged استفاده میشود. عکس آنی ارسالشده به callback حاوی
دادههای فرزند حذفشده است.
هرگاه فراخوانی OnChildChanged با بهروزرسانیای که باعث تغییر ترتیب فرزند میشود مطرح شود، فراخوانی برگشتی OnChildMoved راهاندازی میشود. این تابع با دادههایی استفاده میشود که با OrderByChild یا OrderByValue مرتب شدهاند.
مرتبسازی و فیلتر کردن دادهها
میتوانید از کلاس Realtime Database Query برای بازیابی دادههای مرتبشده براساس
کلید، مقدار، یا مقدار فرزند استفاده کنید. همچنین میتوانید
نتیجه مرتبشده را به تعداد خاصی از نتایج یا محدودهای از کلیدها یا
مقادیر فیلتر کنید.
مرتب کردن دادهها
برای بازیابی دادههای مرتبشده، ابتدا یکی از روشهای بهترتیب کردن را برای تعیین نحوه مرتبسازی نتایج مشخص کنید:
| روش | کاربرد |
|---|---|
OrderByChild() |
نتایج را براساس مقدار کلید فرزند مشخصشده مرتب میکند. |
OrderByKey()
| نتایج را براساس کلیدهای فرزند مرتب کنید. |
OrderByValue() |
نتایج را براساس مقادیر فرزند مرتب کنید. |
در هر زمان فقط میتوانید از یک روش بهترتیب کردن استفاده کنید. فراخوانی روش بهترتیب کردن بهدفعات در یک پُرسمان باعث ایجاد خطا میشود.
مثال زیر نشان میدهد که چگونه میتوانید در جدول ردهبندی امتیازها که براساس امتیاز مرتب شده است مشترک شوید.
firebase::database::Query query = dbRef.GetReference("Leaders").OrderByChild("score"); // To get the resulting DataSnapshot either use query.GetValue() and poll the // future, or use query.AddValueListener() and register to handle the // OnValueChanged callback.
این یک firebase::Query را تعریف میکند که وقتی با یک
ValueListener ترکیب میشود، مشتری را با جدول ردهبندی
در پایگاه داده همگامسازی میکند، که براساس امتیاز هر ورودی مرتب شده است.
میتوانید درباره ساختاردهی کارآمد دادههایتان در
ساختاردهی پایگاه داده بیشتر بخوانید.
فراخوانی روش OrderByChild() کلید فرزند را برای مرتبسازی نتایج مشخص میکند. در این حالت، نتایج براساس مقدار "score"
در هر فرزند مرتب میشود. برای اطلاعات بیشتر درباره نحوه مرتبسازی انواع دیگر دادهها،
نحوه مرتبسازی دادههای پُرسمان را ببینید.
فیلتر کردن دادهها
برای فیلتر کردن دادهها، میتوانید هریک از روشهای محدود کردن یا محدوده را با یک روش بهترتیب کردن هنگام ساختن پرسمان ترکیب کنید.
| روش | کاربرد |
|---|---|
LimitToFirst() |
حداکثر تعداد مواردی را که باید از ابتدای فهرست مرتبشده نتایج برگردانده شود تنظیم میکند. |
LimitToLast() |
حداکثر تعداد مواردی را که باید از انتهای فهرست مرتبشده نتایج برگردانده شود تنظیم میکند. |
StartAt() |
موارد بزرگتر یا مساوی با کلید یا مقدار مشخصشده را برمیگرداند بسته به روش بهترتیب کردن انتخابشده. |
EndAt() |
موارد کمتر یا مساوی با کلید یا مقدار مشخصشده را برمیگرداند بسته به روش بهترتیب کردن انتخابشده. |
EqualTo() |
موارد برابر با کلید یا مقدار مشخصشده را بسته به روش بهترتیب کردن انتخابشده برمیگرداند. |
برخلاف روشهای بهترتیب کردن، میتوانید چندین تابع محدوده یا حد را ترکیب کنید.
برای مثال، میتوانید روشهای StartAt() و EndAt() را ترکیب کنید تا
نتایج را به گستره مشخصی از مقادیر محدود کنید.
حتی وقتی فقط یک مورد منطبق برای پُرسمان وجود دارد، خلاصه همچنان یک فهرست است؛ فقط یک مورد دارد.
محدود کردن تعداد نتایج
میتوانید از روشهای LimitToFirst() و LimitToLast() برای تنظیم
حداکثر تعداد فرزندان برای همگامسازی برای یک فراخوانی معین استفاده کنید. برای مثال، اگر
از LimitToFirst() برای تنظیم محدودیت ۱۰۰ استفاده کنید، در ابتدا فقط تا
۱۰۰ OnChildAdded فراخوانی برگشتی دریافت میکنید. اگر کمتر از ۱۰۰ مورد در پایگاه داده Firebase شما ذخیره شده باشد، یک فراخوانی برگشتی OnChildAdded برای هر مورد اجرا میشود.
با تغییر موارد، OnChildAdded فراخوانی برگشتی برای مواردی که وارد پُرسمان میشوند و OnChildRemoved فراخوانی برگشتی برای مواردی که از آن خارج میشوند دریافت میکنید تا تعداد کل روی ۱۰۰ باقی بماند.
برای مثال، کد زیر بالاترین امتیاز را از تابلو پیشتازان برمیگرداند:
firebase::database::Query query = dbRef.GetReference("Leaders").OrderByChild("score").LimitToLast(1); // To get the resulting DataSnapshot either use query.GetValue() and poll the // future, or use query.AddValueListener() and register to handle the // OnValueChanged callback.
فیلتر کردن براساس کلید یا مقدار
میتوانید از StartAt()، EndAt()، و EqualTo() برای انتخاب نقاط شروع، پایان، و معادل دلخواه برای پُرسمانها استفاده کنید. این کار میتواند برای صفحهبندی دادهها یا پیدا کردن موارد دارای فرزند با مقدار خاص مفید باشد.
نحوه مرتبسازی دادههای پُرسمان
این بخش توضیح میدهد که دادهها چگونه توسط هریک از روشهای بهترتیب کردن در کلاس
Query مرتب میشوند.
OrderByChild
هنگام استفاده از OrderByChild()، دادههایی که حاوی کلید فرزند مشخصشده هستند
بهصورت زیر مرتب میشوند:
- فرزندان با مقدار
nullبرای کلید فرزند مشخصشده در ابتدا میآیند. - فرزندان با مقدار
falseبرای کلید فرزند مشخصشده در ردیف بعدی قرار میگیرند. اگر چند فرزند مقدارfalseداشته باشند، براساس کلید بهترتیب الفبایی مرتب میشوند. - فرزندان با مقدار
trueبرای کلید فرزند مشخصشده در ردیف بعدی قرار میگیرند. اگر چند فرزند مقدارtrueداشته باشند، بهترتیب الفبایی براساس کلید مرتب میشوند. - فرزندان با مقدار عددی در ردیف بعدی قرار میگیرند و بهترتیب صعودی مرتب میشوند. اگر چند فرزند مقدار عددی یکسانی برای گره فرزند مشخصشده داشته باشند، براساس کلید مرتب میشوند.
- رشتهها بعداز اعداد میآیند و بهترتیب صعودی واژهنامهای مرتب میشوند. اگر چند فرزند مقدار یکسانی برای گره فرزند مشخصشده داشته باشند، آنها بهصورت واژهنامهای براساس کلید مرتب میشوند.
- اشیا در آخر میآیند و بهترتیب صعودی براساس کلید مرتب میشوند.
OrderByKey
هنگام استفاده از OrderByKey() برای مرتبسازی دادهها، دادهها بهترتیب صعودی
براساس کلید برگردانده میشوند.
- فرزندان با کلیدی که میتواند بهعنوان عدد صحیح ۳۲ بیتی تجزیه شود، ابتدا بهصورت صعودی مرتب میشوند.
- فرزندانی که مقدار رشتهای بهعنوان کلید دارند در ردیف بعدی قرار میگیرند و بهترتیب صعودی واژهنامهای مرتب میشوند.
OrderByValue
هنگام استفاده از OrderByValue()، فرزندان براساس مقدارشان مرتب میشوند. معیارهای ترتیببندی همانند OrderByChild() است، با این تفاوت که بهجای مقدار کلید فرزند مشخصشده، از مقدار گره استفاده میشود.