Verileri Kaydet

Başlamadan önce

Realtime Database'i kullanabilmeniz için önce şunları yapmanız gerekir:

  • Unity projenizi kaydedin ve Firebase'i kullanacak şekilde yapılandırın.

    • Unity projeniz zaten Firebase'i kullanıyorsa Firebase için kaydedilmiş ve yapılandırılmış demektir.

    • Unity projeniz yoksa örnek bir uygulama indirebilirsiniz.

  • Unity projenize Firebase Unity SDK'yı (özellikle FirebaseDatabase.unitypackage) ekleyin.

Firebase'i Unity projenize eklemenin hem Firebase konsolundaki hem de açık Unity projenizdeki görevleri içerdiğini unutmayın (örneğin, Firebase yapılandırma dosyalarını konsoldan indirir ve ardından bunları Unity projenize taşırsınız).

Verileri Kaydetme

Firebase Realtime Database'e veri yazmak için beş yöntem vardır:

Yöntem Yaygın kullanım alanları
SetValueAsync() Verileri users/<user-id>/<username> gibi tanımlı bir yola yazın veya değiştirin.
SetRawJsonValueAsync() Verileri ham Json ile yazın veya değiştirin (ör. users/<user-id>/<username>).
Push() 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.
UpdateChildrenAsync() 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.

Veritabanı Referansı Alma

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

using Firebase;
using Firebase.Database;

public class MyScript: MonoBehaviour {
  void Start() {
    // Get the root reference location of the database.
    DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
  }
}

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 SetValueAsync() kullanabilirsiniz. Kullanılabilir JSON türlerine karşılık gelen türleri aşağıdaki gibi iletmek için bu yöntemi kullanabilirsiniz:

  • string
  • long
  • double
  • bool
  • Dictionary<string, Object>
  • List<Object>

Türü belirtilmiş bir C# nesnesi kullanıyorsanız nesneyi ham Json'a dönüştürmek ve SetRawJsonValueAsync() çağrısı yapmak için yerleşik JsonUtility.ToJson() kullanabilirsiniz. Örneğin, aşağıdaki gibi görünen bir Kullanıcı sınıfınız olabilir:

public class User {
    public string username;
    public string email;

    public User() {
    }

    public User(string username, string email) {
        this.username = username;
        this.email = email;
    }
}

SetRawJsonValueAsync() uygulamasına sahip bir kullanıcıyı aşağıdaki şekilde ekleyebilirsiniz:

private void writeNewUser(string userId, string name, string email) {
    User user = new User(name, email);
    string json = JsonUtility.ToJson(user);

    mDatabaseRef.Child("users").Child(userId).SetRawJsonValueAsync(json);
}

SetValueAsync() veya SetRawJsonValueAsync() bu şekilde kullanıldığında, belirtilen konumdaki tüm alt düğümler dahil verilerin üzerine yazılır. Ancak, nesnenin tamamını yeniden yazmadan da bir alt öğeyi güncelleyebilirsiniz. Kullanıcıların profillerini güncellemelerine izin vermek istiyorsanız kullanıcı adını aşağıdaki şekilde güncelleyebilirsiniz:

mDatabaseRef.Child("users").Child(userId).Child("username").SetValueAsync(name);

Veri listesine ekle

Çok kullanıcılı uygulamalarda bir listeye veri eklemek için Push() yöntemini kullanın. Push() 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. Push() 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 öğrenmek veya alt öğe için verileri ayarlamak üzere Push() yöntemi tarafından döndürülen yeni verilere referansı kullanabilirsiniz. Push() referansında Key ç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 UpdateChildrenAsync() yöntemini kullanın.

UpdateChildrenAsync() ç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:

public class LeaderboardEntry {
    public string uid;
    public int score = 0;

    public LeaderboardEntry() {
    }

    public LeaderboardEntry(string uid, int score) {
        this.uid = uid;
        this.score = score;
    }

    public Dictionary<string, Object> ToDictionary() {
        Dictionary<string, Object> result = new Dictionary<string, Object>();
        result["uid"] = uid;
        result["score"] = score;

        return result;
    }
}

Skor Tablosu girişi oluşturup aynı anda son skor feed'ine ve kullanıcının kendi skor listesine güncellemek için oyun aşağıdaki gibi bir kod kullanır:

private void WriteNewScore(string userId, int score) {
    // Create new entry at /user-scores/$userid/$scoreid and at
    // /leaderboard/$scoreid simultaneously
    string key = mDatabase.Child("scores").Push().Key;
    LeaderBoardEntry entry = new LeaderBoardEntry(userId, score);
    Dictionary<string, Object> entryValues = entry.ToDictionary();

    Dictionary<string, Object> childUpdates = new Dictionary<string, Object>();
    childUpdates["/scores/" + key] = entryValues;
    childUpdates["/user-scores/" + userId + "/" + key] = entryValues;

    mDatabase.UpdateChildrenAsync(childUpdates);
}

Bu örnekte, /scores/$key alanındaki tüm kullanıcılar için girişler içeren düğümde bir giriş oluşturmak ve Key ile aynı anda anahtarı almak üzere Push() 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 UpdateChildrenAsync() ç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.

SetValueAsync() veya UpdateChildrenAsync() gibi başka bir yazma işlemi için null değerini belirterek de silme işlemini yapabilirsiniz. Tek bir API çağrısında birden çok alt öğeyi silmek için bu tekniği UpdateChildrenAsync() ile kullanabilirsiniz.

Verilerinizin kaydedildiği zamanı öğrenin.

Verilerinizin Firebase Realtime Database sunucusuna ne zaman kaydedildiğini öğrenmek için devamlılık ekleyebilirsiniz. Hem SetValueAsync() hem de UpdateChildrenAsync(), işlemin tamamlandığını anlamanızı sağlayan bir Task döndürür. Çağrı herhangi bir nedenle başarısız olursa Görevler IsFaulted, hatanın neden oluştuğunu belirten Exception özelliği ile birlikte etkinleştirilir.

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 Func verirsiniz. Bu güncelleme Func, verilerin mevcut durumunu bağımsız değişken olarak 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:

private void AddScoreToLeaders(string email, 
                               long score,
                               DatabaseReference leaderBoardRef) {

    leaderBoardRef.RunTransaction(mutableData => {
      List<object> leaders = mutableData.Value as List<object>

      if (leaders == null) {
        leaders = new List<object>();
      } else if (mutableData.ChildrenCount >= MaxScores) {
        long minScore = long.MaxValue;
        object minVal = null;
        foreach (var child in leaders) {
          if (!(child is Dictionary<string, object>)) continue;
          long childScore = (long)
                      ((Dictionary<string, object>)child)["score"];
          if (childScore < minScore) {
            minScore = childScore;
            minVal = child;
          }
        }
        if (minScore > score) {
          // The new score is lower than the existing 5 scores, abort.
          return TransactionResult.Abort();
        }

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

      // Add the new high score.
      Dictionary<string, object> newScoreMap =
                       new Dictionary<string, object>();
      newScoreMap["score"] = score;
      newScoreMap["email"] = email;
      leaders.Add(newScoreMap);
      mutableData.Value = leaders;
      return TransactionResult.Success(mutableData);
    });
}

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