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

Başlamak

Henüz uygulamanızı kurmadıysanız ve veritabanına erişmediyseniz, önce Get Started kılavuzuna bakın.

Veritabanı Referansı Alın

Veritabanına veri yazmak için bir DatabaseReference örneğine ihtiyacınız vardır:

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

Verileri Kaydetme

Firebase Gerçek Zamanlı Veritabanına veri yazmanın dört yöntemi vardır:

Yöntem Yaygın kullanımlar
SetValue() users/<user-id>/<username> gibi tanımlı bir yola veri yazın veya değiştirin.
PushChild() Bir veri listesine ekleyin. Push() öğesini her çağırdığınızda, Firebase user-scores/<user-id>/<unique-score-id> gibi benzersiz tanımlayıcı olarak da kullanılabilen benzersiz bir anahtar 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 referansta veri yazma, güncelleme veya silme

Temel yazma işlemleri

Temel yazma işlemleri için, verileri belirtilen bir referansa kaydetmek ve bu yoldaki varolan verileri değiştirmek için SetValue() kullanabilirsiniz. JSON tarafından kabul edilen türleri aşağıdakileri destekleyen bir Variant türü aracılığıyla geçirmek için bu yöntemi kullanabilirsiniz:

  • Boş (bu, verileri siler)
  • Tamsayılar (64 bit)
  • Çift duyarlıklı kayan noktalı sayılar
  • Boolean'lar
  • Teller
  • Varyantların Vektörleri
  • Dizelerin Varyantlara Eşlenmesi

SetValue() bu şekilde kullanıldığında, alt düğümler de dahil olmak üzere belirtilen konumdaki verilerin üzerine yazılır. Ancak yine de tüm nesneyi yeniden yazmadan bir çocuğu güncelleyebilirsiniz. Kullanıcıların profillerini güncellemelerine izin vermek istiyorsanız, kullanıcı adını aşağıdaki gibi güncelleyebilirsiniz:

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

Bir veri listesine ekleme

Ç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 çocuk eklendiğinde benzersiz bir anahtar oluşturur. Listedeki her yeni öğe için otomatik olarak oluşturulan bu anahtarları kullanarak, birkaç istemci yazma çakışmaları olmadan aynı konuma aynı anda alt öğeler ekleyebilir. PushChild() tarafından oluşturulan benzersiz anahtar, bir zaman damgasına dayalıdır, bu nedenle liste öğeleri otomatik olarak kronolojik olarak sıralanır.

Çocuğun otomatik olarak oluşturulan anahtarının değerini almak veya çocuk için veri ayarlamak için PushChild() yöntemi tarafından döndürülen yeni verilere yapılan başvuruyu kullanabilirsiniz. Bir PushChild() referansında GetKey() çağrılması, otomatik olarak oluşturulan anahtarın değerini döndürü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() öğesini çağırırken, anahtar için bir yol belirterek alt düzey alt değerleri güncelleyebilirsiniz. Veriler daha iyi ölçeklendirmek için birden çok konumda depolanıyorsa, veri yayma özelliğini kullanarak bu verilerin tüm örneklerini güncelleyebilirsiniz. Örneğin, bir oyunun LeaderboardEntry sınıfı şöyle 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;
  }
}

Bir LeaderboardEntry oluşturmak ve aynı anda bunu en son skor beslemesine ve kullanıcının kendi skor listesine güncellemek için oyun aşağıdaki 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 örnek /scores/$key adresindeki tüm kullanıcılar için girişleri içeren düğümde bir giriş oluşturmak ve aynı anda key() ile anahtarı almak için PushChild() kullanır. Anahtar daha sonra kullanıcının /user-scores/$userid/$key adresindeki puanlarında ikinci bir giriş oluşturmak için kullanılabilir.

Bu yolları kullanarak, tek bir UpdateChildren() çağrısıyla JSON ağacındaki birden çok konumda eşzamanlı güncellemeler gerçekleştirebilirsiniz, örneğin bu örneğin her iki konumda da yeni girişi nasıl oluşturduğu gibi. Bu şekilde yapılan eşzamanlı güncellemeler atomiktir: ya tüm güncellemeler başarılı olur ya da tüm güncellemeler başarısız olur.

Verileri sil

Verileri silmenin en basit yolu, söz konusu verinin konumu referans alınarak RemoveValue() öğesini çağırmaktır.

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

Verilerinizin ne zaman işlendiğini öğrenin.

Verilerinizin Firebase Gerçek Zamanlı Veritabanı sunucusuna ne zaman kaydedildiğini öğrenmek için başarı için Gelecek sonucunu kontrol edin.

Verileri işlem olarak kaydet

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

Örneğin, bir oyunda, kullanıcıların en yüksek beş skorla skor tablosunu güncellemesine 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şlemin kullanılması, birden çok kullanıcı aynı anda puanları kaydederse veya müşterinin eski verileri varsa, lider tablosunun yanlış olmasını önler. İşlem reddedilirse sunucu, işlemi güncellenen değerle yeniden çalıştıran istemciye geçerli değeri döndürür. Bu, işlem kabul edilene veya çok fazla girişimde bulunulana kadar tekrarlanır.

Çevrimdışı veri yaz

Bir istemci ağ bağlantısını kaybederse uygulamanız düzgün çalışmaya devam eder.

Bir Firebase veritabanına bağlı her istemci, tüm etkin verilerin kendi dahili sürümünü korur. Veri yazıldığında, önce bu yerel sürüme yazılır. Firebase istemcisi daha sonra bu verileri uzak veritabanı sunucularıyla ve diğer istemcilerle "en iyi çaba" esasına göre senkronize eder.

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

Bağlantı yeniden sağlandıktan sonra uygulamanız, herhangi bir özel kod yazmak zorunda kalmadan istemcinin geçerli sunucu durumuyla eşitlenmesi için uygun olay kümesini alır.

Sonraki adımlar