C++ için Firebase Realtime Database ile Veri Kaydetme

Başlayın

Uygulamanızı henüz ayarlamadıysanız ve veritabanına erişiminiz yoksa önce Get Started kılavuzuna bakın.

Veritabanı Referansı Alma

Veritabanı'na veri yazmak için DatabaseReference örneğinin olması gerekir:

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

Verileri Kaydetme

Firebase Realtime Database'e veri yazmak için dört farklı yöntem kullanabilirsiniz:

Yöntem Yaygın kullanım alanları
SetValue() Verileri users/<user-id>/<username> gibi tanımlı bir yola yazın veya değiştirin.
PushChild() Veri listesine ekleme. Push() her çağırışınızda Firebase, benzersiz tanımlayıcı olarak da kullanılabilecek benzersiz bir anahtar (ör. user-scores/<user-id>/<unique-score-id>) oluşturur.
UpdateChildren() Tüm verileri değiştirmeden, tanımlanmış bir yol için bazı anahtarları güncelleyin.
RunTransaction() Eşzamanlı güncellemelerle bozulabilecek karmaşık verileri güncelleyin.

Bir referanstaki verileri yazma, güncelleme veya silme

Temel yazma işlemleri

Temel yazma işlemlerinde, verileri belirtilen bir referansa kaydetmek ve söz konusu yoldaki mevcut tüm verileri değiştirmek için SetValue() kullanabilirsiniz. JSON tarafından kabul edilen türleri, aşağıdakileri destekleyen bir Varyant türü üzerinden iletmek için bu yöntemi kullanabilirsiniz:

  • Null (bu işlem verileri siler)
  • Tamsayılar (64 bit)
  • Çift duyarlıklı kayan nokta sayıları
  • Boole
  • Dizeler
  • Varyant Vektörleri
  • Dizelerin Varyantlarla haritaları

SetValue() bu şekilde kullanıldığında, tüm alt düğümler de dahil olmak üzere belirtilen konumdaki verilerin üzerine yazılır. Ancak, nesnenin tamamını yeniden yazmadan da alt öğeleri güncelleyebilirsiniz. Kullanıcıların profillerini güncellemelerine izin vermek isterseniz kullanıcı adını aşağıdaki şekilde güncelleyebilirsiniz:

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

Veri listesine ekle

Çok kullanıcılı uygulamalarda bir listeye veri eklemek için PushChild() yöntemini kullanın. PushChild() yöntemi, belirtilen Firebase referansına her yeni alt öğe eklendiğinde benzersiz bir anahtar oluşturur. Listedeki her yeni öğe için otomatik olarak oluşturulan bu anahtarları kullanarak bazı istemciler, yazma çakışmaları olmadan aynı anda aynı konuma alt öğeler ekleyebilir. PushChild() tarafından oluşturulan benzersiz anahtar bir zaman damgasına dayanır. Bu nedenle liste öğeleri otomatik olarak kronolojik olarak sıralanır.

Alt yayıncının otomatik olarak oluşturulan anahtarın değerini almak veya alt öğe için verileri ayarlamak üzere PushChild() yöntemi tarafından döndürülen yeni verilere referansı kullanabilirsiniz. PushChild() referansında GetKey() çağrısı yapıldığında otomatik oluşturulan anahtarın değeri döndürülür.

Belirli alanları güncelle

Diğer alt düğümlerin üzerine yazmadan aynı anda bir düğümün belirli alt öğelerine yazmak için UpdateChildren() yöntemini kullanın.

UpdateChildren() çağrısı yapılırken, anahtarın yolunu belirterek alt düzey alt değerleri güncelleyebilirsiniz. Veriler daha iyi ölçeklendirmek için birden fazla konumda depolanıyorsa veri yayma yöntemini kullanarak bu verilerin tüm örneklerini güncelleyebilirsiniz. Örneğin, bir oyunda şuna benzer bir LeaderboardEntry sınıfı olabilir:

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;
  }
}

Oyun, LeaderboardEntry oluşturup aynı anda son skor feed'i ve kullanıcının kendi skor listesine güncellemek için şu kodu kullanır:

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);
}

Bu örnekte, /scores/$key alanındaki tüm kullanıcıların girişlerini içeren düğümde bir giriş oluşturmak ve key() ile aynı anda anahtarı almak için PushChild() kullanılmaktadır. Daha sonra bu anahtar, /user-scores/$userid/$key adresinde kullanıcının puanlarında ikinci bir giriş oluşturmak için kullanılabilir.

Bu yolları kullanarak, tek bir UpdateChildren() çağrısı yaparak JSON ağacındaki birden fazla konumda eş zamanlı güncellemeler yapabilirsiniz (örneğin, bu örneğin her iki konumda da yeni girişi nasıl oluşturduğu gibi). Bu yaklaşım, eş zamanlı olarak yapılan güncellemelerde çok önemli bir rol oynar: ya tüm güncellemeler başarılı olur ya da başarısız olur.

Verileri silin

Verileri silmenin en basit yolu, söz konusu verilerin konumuna referans vererek RemoveValue() öğesini çağırmaktır.

SetValue() veya UpdateChildren() gibi başka bir yazma işleminin değeri olarak null Variant belirterek de silme işlemini yapabilirsiniz. Tek bir API çağrısında birden çok alt öğeyi silmek için bu tekniği UpdateChildren() ile kullanabilirsiniz.

Verilerinizin kaydedildiği zamanı öğrenin.

Verilerinizin Firebase Realtime Database sunucusuna ne zaman kaydedildiğini öğrenmek için Gelecek sonucuna bakarak başarılı olup olmadığınızı kontrol edin.

Verileri işlem olarak kaydet

Artımlı sayaçlar gibi eşzamanlı değişikliklere göre bozulabilecek verilerle çalışırken işlem işlemi kullanabilirsiniz. Bu işleme bir DoTransaction işlevi verirsiniz. Bu güncelleme işlevi, bağımsız değişken olarak verilerin mevcut durumunu alır ve yazmak istediğiniz yeni durumu döndürür. Başka bir istemci yeni değeriniz başarıyla yazılmadan önce konuma yazarsa güncelleme işleviniz yeni geçerli değerle tekrar çağrılır ve yazma işlemi yeniden denenir.

Örneğin, bir oyunda kullanıcıların bir skor tablosunu en yüksek beş skoruyla güncellemelerine izin verebilirsiniz:

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;
  });
}

Bir işlem kullanmak, birden fazla kullanıcı aynı anda skorları kaydederse veya müşterinin verileri eskiyse skor tablosunun yanlış olmasını önler. İşlem reddedilirse sunucu geçerli değeri istemciye döndürür. İstemci de işlemi güncellenmiş değerle tekrar çalıştırır. Bu işlem, işlem kabul edilene veya çok fazla deneme yapılana kadar tekrar eder.

Çevrimdışı veri yazma

İstemcinin ağ bağlantısı kesilirse uygulamanız düzgün şekilde çalışmaya devam eder.

Firebase veritabanına bağlı her müşteri, tüm etkin verilerin kendi dahili sürümlerini korur. Veriler yazıldığında, öncelikle bu yerel sürüme yazılır. Firebase istemcisi daha sonra bu verileri uzak veritabanı sunucuları ve diğer istemcilerle "en iyi çaba" temelinde senkronize eder.

Sonuç olarak, veritabanına yapılan tüm yazma işlemleri sunucuya herhangi bir veri yazılmadan önce yerel etkinlikleri hemen tetikler. Bu, uygulamanızın ağ gecikmesi veya bağlantıdan bağımsız olarak yanıt vermeye devam edeceği anlamına gelir.

Bağlantı yeniden kurulduktan sonra uygulamanız, uygun etkinlik grubunu alır. Böylece, istemci herhangi bir özel kod yazmak zorunda kalmadan mevcut sunucu durumuyla senkronize edilir.

Sonraki adımlar