بازیابی داده‌ها با «پایگاه داده بی‌درنگ Firebase» برای C++‎

این سند اصول اولیه بازیابی داده‌ها و نحوه مرتب‌سازی و فیلتر کردن داده‌های 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&ltfirebase::database::DataSnapshot&gt 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 پاسخ‌برگ‌ها برای مشترک شدن در تغییرات محتوا در یک مسیر معین استفاده کنید. این بازخوانی یک‌بار وقتی شنونده پیوست می‌شود و دوباره هر بار که داده‌ها، ازجمله کودکان، تغییر می‌کند راه‌اندازی می‌شود. یک بازخوان حاوی نمای لحظه‌ای از همه داده‌های آن مکان، ازجمله داده‌های فرزند، ارسال می‌شود. اگر داده‌ای وجود نداشته باشد، عکس آنی برگشتی 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&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("Leaders").AddValueListener(listener);

نتیجه Future&ltDataSnapshot&gt حاوی داده‌های مکان مشخص‌شده در پایگاه داده در زمان رویداد است. فراخوانی 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&ltfirebase::database::DataSnapshot&gt result =
    dbRef.GetReference("GameSessionComments").AddChildListener(listener);

از برگشت به تماس OnChildAdded معمولاً برای بازیابی فهرست موارد در پایگاه داده Firebase استفاده می‌شود. ‫OnChildAdded پاسخ‌گویی یک‌بار برای هر کودک موجود و سپس هر بار که کودک جدیدی به مسیر مشخص‌شده اضافه می‌شود فراخوانده می‌شود. یک نمای فوری حاوی داده‌های فرزند جدید به شنونده منتقل می‌شود.

هر زمان که گره فرزند اصلاح شود، OnChildChanged برگشت‌پذیر فراخوانی می‌شود. این شامل هرگونه تغییر در فرزندان گره کودک می‌شود. این معمولاً همراه با فراخوانی‌های OnChildAdded و OnChildRemoved برای پاسخ دادن به تغییرات فهرست موارد استفاده می‌شود. نمای لحظه‌ای که به شنونده ارسال می‌شود حاوی داده‌های به‌روزشده برای فرزند است.

وقتی فرزند بی‌واسطه‌ای برداشته می‌شود، OnChildRemoved بازخوانی راه‌اندازی می‌شود. معمولاً همراه با OnChildAdded و OnChildChanged پاسخ‌برگ‌ها استفاده می‌شود. نماگذر ارسال‌شده به برگشت‌تماس حاوی داده‌های فرزند برداشته‌شده است.

هرگاه 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()، داده‌هایی که حاوی کلید فرزند مشخص‌شده است به‌صورت زیر مرتب می‌شود:

  1. کودکانی که مقدار null برای کلید کودک مشخص‌شده دارند در ابتدا قرار می‌گیرند.
  2. کودکان با مقدار false برای کلید کودک مشخص‌شده در مرحله بعد قرار دارند. اگر چند فرزند مقدار false داشته باشند، براساس کلید به‌صورت واژه‌نامه‌ای مرتب می‌شوند.
  3. کودکان با مقدار true برای کلید کودک مشخص‌شده در مرحله بعد قرار دارند. اگر چند فرزند مقدار true داشته باشند، براساس کلید به‌صورت واژه‌نامه‌ای مرتب می‌شوند.
  4. کودکان با مقدار عددی در مرحله بعد قرار می‌گیرند و به‌ترتیب صعودی مرتب می‌شوند. اگر چندین فرزند مقدار عددی یکسانی برای گره فرزند مشخص‌شده داشته باشند، براساس کلید مرتب می‌شوند.
  5. رشته‌ها بعداز اعداد می‌آیند و به‌ترتیب صعودی براساس ترتیب واژگانی مرتب می‌شوند. اگر چند کودک مقدار یکسانی برای گره کودک مشخص‌شده داشته باشند، براساس کلید به‌ترتیب الفبایی مرتب می‌شوند.
  6. اشیا در آخر قرار می‌گیرند و براساس کلید به‌ترتیب صعودی واژه‌نامه‌ای مرتب می‌شوند.

OrderByKey

هنگام استفاده از OrderByKey() برای مرتب کردن داده‌ها، داده‌ها به‌ترتیب صعودی برحسب کلید برگردانده می‌شود.

  1. کودکانی که کلیدی دارند که می‌تواند به‌عنوان عدد صحیح ۳۲ بیتی تجزیه شود، در ابتدا قرار می‌گیرند و به‌ترتیب صعودی مرتب می‌شوند.
  2. کودکانی که مقدار رشته‌ای به‌عنوان کلید دارند در مرحله بعد قرار می‌گیرند و به‌ترتیب الفبایی صعودی مرتب می‌شوند.

OrderByValue

هنگام استفاده از OrderByValue()، کودکان براساس مقدارشان مرتب می‌شوند. معیارهای ترتیب‌بندی همانند OrderByChild() است، با این تفاوت که به‌جای مقدار کلید فرزند مشخص‌شده، از مقدار گره استفاده می‌شود.

مراحل بعدی