C++ के लिए, Firebase रीयल टाइम डेटाबेस की मदद से डेटा सेव करना

शुरू करें

अगर आपके पास नहीं है, तो पहले Get Started गाइड देखें आपने ऐप्लिकेशन को सेट अप किया हो और डेटाबेस को ऐक्सेस किया हो.

DatabaseReference पाएं

डेटाबेस में डेटा लिखने के लिए, आपको DatabaseReference का एक इंस्टेंस चाहिए:

    // Get the root reference location of the database.
    firebase::database::DatabaseReference dbref = database->GetReference();

डेटा सहेजा जा रहा है

Firebase रीयल टाइम डेटाबेस में डेटा लिखने के चार तरीके हैं:

तरीका सामान्य तौर पर क्वेरी की सूची का इस्तेमाल इस तरह किया जाता है
SetValue() किसी तय पाथ में डेटा लिखें या बदलें, जैसे कि users/<user-id>/<username>.
PushChild() डेटा की सूची में जोड़ें. हर बार कॉल करने पर Push(), Firebase एक खास कुंजी जनरेट करता है, जिसका इस्तेमाल भी किया जा सकता है एक यूनीक आइडेंटिफ़ायर के तौर पर मिलता है, जैसे कि user-scores/<user-id>/<unique-score-id>.
UpdateChildren() तय किए गए पाथ के लिए, कुछ कुंजियों को अपडेट करें के लिए इस्तेमाल किया जा सकता है.
RunTransaction() वह कॉम्प्लेक्स डेटा अपडेट करें जिसमें एक साथ कई अपडेट होने की वजह से गड़बड़ी हो सकती है.

किसी रेफ़रंस के लिए डेटा लिखना, उसे अपडेट करना या मिटाना

लिखने से जुड़ी बुनियादी कार्रवाइयां

लिखने की बेसिक कार्रवाइयों के लिए, SetValue() का इस्तेमाल करके बताया गया है, जो उस पथ के किसी भी मौजूदा डेटा को बदल देगा. आप इसका इस्तेमाल कर सकते हैं का इस्तेमाल करने का तरीका:

  • शून्य (इससे डेटा मिट जाता है)
  • पूर्णांक (64-बिट)
  • डबल सटीक फ़्लोटिंग पॉइंट नंबर
  • बूलियन
  • स्ट्रिंग्स
  • वैरिएंट के वेक्टर
  • स्ट्रिंग के अलग-अलग वैरिएंट के लिए मैप

SetValue() का इस तरह इस्तेमाल करने से, बताई गई जगह के डेटा को ओवरराइट कर दिया जाता है, इसमें सभी चाइल्ड नोड शामिल हैं. हालांकि, बच्चे के खाते को इनके बिना भी अपडेट किया जा सकता है पूरे ऑब्जेक्ट को फिर से लिखना. अगर आपको उपयोगकर्ताओं को उनकी प्रोफ़ाइल अपडेट करने की अनुमति देनी है तो आप उपयोगकर्ता नाम को इस प्रकार अपडेट कर सकते हैं:

dbref.Child("users").Child(userId).Child("username").SetValue(name);

डेटा की सूची में जोड़ें

एक से ज़्यादा उपयोगकर्ताओं वाले ऐप्लिकेशन की किसी सूची में डेटा जोड़ने के लिए, PushChild() तरीके का इस्तेमाल करें. PushChild() तरीका, हर बार नई कुंजी जनरेट करता है चाइल्ड को तय किए गए Firebase रेफ़रंस में जोड़ दिया जाता है. इनका इस्तेमाल करके सूची के हर नए एलिमेंट के लिए अपने-आप जनरेट होने वाली कुंजियों का इस्तेमाल करके, कई क्लाइंट बच्चों को एक ही समय पर एक ही जगह पर जोड़ दें. इससे, उन्हें लिखने में परेशानी नहीं होगी. कॉन्टेंट बनाने PushChild() से जनरेट की गई यूनीक कुंजी, टाइमस्टैंप पर आधारित है. इसलिए, सूची के आइटम वह समय के हिसाब से अपने-आप ऑर्डर हो जाएगा.

PushChild() तरीके से मिले नए डेटा के रेफ़रंस का इस्तेमाल किया जा सकता है का इस्तेमाल किया जा सकता है. PushChild() संदर्भ पर GetKey() को कॉल करने से की अपने-आप जनरेट होती है.

खास फ़ील्ड अपडेट करें

अन्य को ओवरराइट किए बिना नोड के खास चिल्ड्रेन को एक साथ लिखने के लिए चाइल्ड नोड के लिए, UpdateChildren() तरीके का इस्तेमाल करें.

को दबाकर रखें UpdateChildren() को कॉल करते समय, लोअर-लेवल की चाइल्ड वैल्यू को इस तरह अपडेट किया जा सकता है कुंजी के लिए पाथ तय कर रहा है. अगर डेटा को बढ़ाने के लिए कई जगहों पर सेव किया जाता है बेहतर है, तो आप इसका इस्तेमाल करके उस डेटा के सभी इंस्टेंस को डेटा फ़ैन-आउट का विकल्प चुनें. उदाहरण के लिए, गेम की LeaderboardEntry क्लास इस तरह की हो सकती है:

class LeaderboardEntry {
  std::string uid;
  int score = 0;

 public:
  LeaderboardEntry() {
  }

  LeaderboardEntry(std::string uid, int score) {
    this->uid = uid;
    this->score = score;
  }

  std::map<std::string, Object> ToMap() {
    std::map<string, Variant> result = new std::map<string, Variant>();
    result["uid"] = Variant(uid);
    result["score"] = Variant(score);

    return result;
  }
}

LeaderboardEntry बनाने और इसके साथ-साथ हाल के स्कोर में अपडेट करने के लिए फ़ीड और उपयोगकर्ता के स्कोर की सूची से मेल खाता है, तो गेम इस कोड का इस्तेमाल करता है:

void WriteNewScore(std::string userId, int score) {
  // Create new entry at /user-scores/$userid/$scoreid and at
  // /leaderboard/$scoreid simultaneously
  std::string key = dbref.Child("scores").PushChild().GetKey();
  LeaderBoardEntry entry = new LeaderBoardEntry(userId, score);
  std::map<std::string, Variant> entryValues = entry.ToMap();

  std::map<string, Variant> childUpdates = new std::map<string, Variant>();
  childUpdates["/scores/" + key] = entryValues;
  childUpdates["/user-scores/" + userId + "/" + key] = entryValues;

  dbref.UpdateChildren(childUpdates);
}

इस उदाहरण में, शामिल नोड में एंट्री बनाने के लिए PushChild() का इस्तेमाल किया गया है /scores/$key पर सभी उपयोगकर्ताओं के लिए एंट्री और साथ ही साथ कुंजी को key(). इसके बाद कुंजी का इस्तेमाल उपयोगकर्ता की /user-scores/$userid/$key में स्कोर.

इन पाथ का इस्तेमाल करके, आप इसमें कई जगहों के लिए एक साथ अपडेट कर सकते हैं: JSON ट्री, जिससे UpdateChildren() को एक बार कॉल किया गया हो, जैसे कि उदाहरण के ज़रिए दोनों जगहों में नई एंट्री बनाई जा सकती है. इसके साथ-साथ अपडेट किए गए परमाणु होते हैं: या तो सभी अपडेट सफल होते हैं या सभी अपडेट विफल हो जाते हैं.

डेटा मिटाना

डेटा हटाने का सबसे आसान तरीका यह है किRemoveValue() की जगह पर हो सकता है.

वैल्यू के तौर पर null Variant को तय करके भी मिटाया जा सकता है SetValue() या UpdateChildren() जैसी कार्रवाई. आप इसका इस्तेमाल कर सकते हैं ऐसी तकनीक जिसमें UpdateChildren() की मदद से एक ही एपीआई में एक से ज़्यादा चिल्ड्रेन की जानकारी मिटाई जा सकती है कॉल.

जानें कि आपका डेटा कब अपलोड किया जाता है.

आपका डेटा, Firebase रीयल टाइम डेटाबेस सर्वर के साथ कब शेयर होता है, यह जानने के लिए सफलता का आने वाला नतीजा है.

डेटा को लेन-देन के तौर पर सेव करें

ऐसे डेटा के साथ काम करते समय जिसमें एक साथ गड़बड़ी हो सकती है जैसे कि इंंक्रीमेंटल काउंटर को शामिल किया है, तो लेन-देन की कार्रवाई. इस कार्रवाई को DoTransaction फ़ंक्शन दिया जाता है. इस अपडेट फ़ंक्शन को डेटा की मौजूदा स्थिति को तर्क के तौर पर दिखाता है और अपने हिसाब से नई स्थिति दिखाता है जिसे आपको लिखना है. यदि कोई अन्य क्लाइंट आपके नया मान सफलतापूर्वक लिखा गया है, तो आपका अपडेट फ़ंक्शन इस नया वर्तमान मान दर्ज करता है, और लिखने का पुनः प्रयास किया जाता है.

उदाहरण के लिए, किसी गेम में आप उपयोगकर्ताओं को लीडरबोर्ड अपडेट करने की अनुमति दे सकते हैं पांच सबसे ज़्यादा स्कोर:

void AddScoreToLeaders(std::string email,
                       long score,
                       DatabaseReference leaderBoardRef) {
  leaderBoardRef.RunTransaction([](firebase::database::MutableData* mutableData) {
    if (mutableData.children_count() >= MaxScores) {
      long minScore = LONG_MAX;
      MutableData *minVal = null;
      std::vector<MutableData> children = mutableData.children();
      std::vector<MutableData>::iterator it;
      for (it = children.begin(); it != children.end(); ++it) {
        if (!it->value().is_map())
          continue;
        long childScore = (long)it->Child("score").value().int64_value();
        if (childScore < minScore) {
          minScore = childScore;
          minVal = &*it;
        }
      }
      if (minScore > score) {
        // The new score is lower than the existing 5 scores, abort.
        return kTransactionResultAbort;
      }

      // Remove the lowest score.
      children.Remove(minVal);
    }

    // Add the new high score.
    std::map<std::string, Variant> newScoreMap =
      new std::map<std::string, Variant>();
    newScoreMap["score"] = score;
    newScoreMap["email"] = email;
    children.Add(newScoreMap);
    mutableData->set_value(children);
    return kTransactionResultSuccess;
  });
}

अगर एक से ज़्यादा बार लेन-देन किया जाता है, तो लीडरबोर्ड गलत नहीं होगा उपयोगकर्ता एक ही समय पर स्कोर रिकॉर्ड करते हैं या क्लाइंट के पास पुराना डेटा था. अगर ट्रांज़ैक्शन अस्वीकार हो जाने पर, सर्वर क्लाइंट को मौजूदा वैल्यू दिखाता है. जो अपडेट की गई वैल्यू के साथ ट्रांज़ैक्शन को फिर से चलाता है. यह प्रक्रिया इस समय तक दोहराई जाती है: लेन-देन स्वीकार कर लिया गया है या कई बार कोशिश की जा चुकी है.

डेटा को ऑफ़लाइन सेव करने की अनुमति दें

अगर किसी क्लाइंट का इंटरनेट कनेक्शन बंद हो जाता है, तो आपका ऐप्लिकेशन काम करता रहेगा सही तरीके से.

Firebase डेटाबेस से जुड़े हर क्लाइंट का अपना इंटरनल वर्शन होता है सक्रिय डेटा का एक उदाहरण है. जब डेटा लिखा जाता है, तो वह इस लोकल वर्शन में लिखा जाता है चुनें. इसके बाद, Firebase क्लाइंट उस डेटा को रिमोट डेटाबेस के साथ सिंक करता है सर्वर और अन्य क्लाइंट के साथ "बेहतरीन कोशिश" करने पर आधार पर.

इस वजह से, डेटाबेस में मौजूद सभी कॉलम, लोकल इवेंट को ट्रिगर करते हैं किसी भी तरह का डेटा सर्वर पर सेव किया जाता है. इसका मतलब है कि आपका ऐप्लिकेशन फिर चाहे वह नेटवर्क में लगने वाले समय या कनेक्टिविटी की परवाह किए बिना रिस्पॉन्सिव हो.

कनेक्टिविटी वापस आने के बाद, आपके ऐप्लिकेशन को ज़रूरत के मुताबिक इवेंट दिखाए जाते हैं, ताकि क्लाइंट बिना किसी परेशानी के सर्वर की मौजूदा स्थिति के साथ सिंक हो जाए कोई कस्टम कोड लिखें.

अगले चरण