Veri kaydet

Sen başlamadan önce

Gerçek Zamanlı Veritabanını kullanabilmeniz için şunları yapmanız gerekir:

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

    • Unity projeniz zaten Firebase kullanıyorsa Firebase için zaten kayıtlı ve yapılandırılmıştır.

    • Unity projeniz yoksa örnek bir uygulama indirebilirsiniz.

  • Firebase Unity SDK'sını (özellikle FirebaseDatabase.unitypackage ) Unity projenize 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 Gerçek Zamanlı Veritabanına veri yazmanın beş yöntemi vardır:

Yöntem Yaygın kullanımlar
SetValueAsync() Verileri, users/<user-id>/<username> gibi tanımlanmış bir yola yazın veya değiştirin.
SetRawJsonValueAsync() Verileri, users/<user-id>/<username> gibi ham Json ile yazın veya değiştirin.
Push() Veri listesine ekleyin. Push() öğesini her çağırdığınızda Firebase, user-scores/<user-id>/<unique-score-id> gibi benzersiz bir tanımlayıcı olarak da kullanılabilecek benzersiz bir anahtar oluşturur.
UpdateChildrenAsync() Tüm verileri değiştirmeden, tanımlanmış bir yol için bazı anahtarları güncelleyin.
RunTransaction() Eş zamanlı güncellemeler nedeniyle bozulabilecek karmaşık verileri güncelleyin.

Veritabanı Referansı Alın

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

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 yazın, güncelleyin veya silin

Temel yazma işlemleri

Temel yazma işlemleri için, verileri belirli bir referansa kaydetmek ve o yoldaki mevcut verileri değiştirmek için SetValueAsync() işlevini kullanabilirsiniz. Mevcut 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>

Yazılı bir C# nesnesi kullanıyorsanız, nesneyi ham Json'a dönüştürmek için yerleşik JsonUtility.ToJson() öğesini kullanabilir ve SetRawJsonValueAsync() çağırabilirsiniz. Örneğin, aşağıdaki gibi görünen bir User 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() ile bir kullanıcıyı aşağıdaki gibi 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() nin bu şekilde kullanılması, alt düğümler de dahil olmak üzere belirtilen konumdaki verilerin üzerine yazar. Ancak nesnenin tamamını yeniden yazmadan bir alt öğeyi yine de güncelleyebilirsiniz. Kullanıcıların profillerini güncellemesine 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 ekleme

Çok kullanıcılı uygulamalarda verileri bir listeye 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, birkaç istemci, yazma çakışmaları olmadan aynı anda çocukları aynı konuma ekleyebilir. Push() tarafından oluşturulan benzersiz anahtar bir zaman damgasını temel alır, dolayısıyla liste öğeleri otomatik olarak kronolojik olarak sıralanır.

Alt öğenin otomatik olarak oluşturulan anahtarının değerini veya alt öğe için ayarlanan verileri almak için Push() yöntemi tarafından döndürülen yeni verilere yapılan başvuruyu kullanabilirsiniz. Push() referansında Key ç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 bir düğümün belirli alt öğelerine aynı anda yazmak için UpdateChildrenAsync() yöntemini kullanın.

UpdateChildrenAsync() öğ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 fazla konumda depolanıyorsa, veri yayma özelliğini kullanarak bu verilerin tüm örneklerini güncelleyebilirsiniz. Örneğin, bir oyunun ş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;
    }
}

Bir LeaderboardEntry oluşturmak ve bunu aynı anda güncel puan akışına ve kullanıcının kendi puan listesine güncellemek için oyun şuna benzer 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 örnek, düğümde /scores/$key adresindeki tüm kullanıcılar için girişler içeren bir giriş oluşturmak ve anahtarı Key ile aynı anda almak için Push() işlevini 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 UpdateChildrenAsync() çağrısıyla JSON ağacındaki birden fazla 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 konumuna ilişkin bir referans üzerinden RemoveValue() işlevini çağırmaktır.

Ayrıca SetValueAsync() veya UpdateChildrenAsync() gibi başka bir yazma işleminin değeri olarak null belirterek de silebilirsiniz. Tek bir API çağrısında birden fazla alt öğeyi silmek için bu tekniği UpdateChildrenAsync() ile kullanabilirsiniz.

Verilerinizin ne zaman işlendiğini bilin.

Verilerinizin Firebase Gerçek Zamanlı Veritabanı sunucusuna ne zaman kaydedildiğini bilmek için bir devam ekleyebilirsiniz. Hem SetValueAsync() hem de UpdateChildrenAsync() işlemin ne zaman tamamlandığını bilmenizi sağlayan bir Task döndürür. Çağrı herhangi bir nedenden dolayı başarısız olursa, Tasks IsFaulted hatanın neden oluştuğunu belirten Exception özelliğiyle birlikte doğru olacaktır.

Verileri işlem olarak kaydet

Artan sayaçlar gibi eş zamanlı değişiklikler nedeniyle bozulabilecek verilerle çalışırken işlem işlemini kullanabilirsiniz. Bu işleme bir Func verirsiniz. Bu güncelleme Func verinin mevcut durumunu 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 yeniden çağrılır ve yazma işlemi yeniden denenir.

Örneğin, bir oyunda kullanıcıların en yüksek beş puanı içeren skor tablosunu güncellemesine 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şlemin kullanılması, birden fazla kullanıcının aynı anda puanları kaydetmesi veya istemcinin eski verileri olması durumunda sıralama tablosunun hatalı olmasını önler. İşlem reddedilirse, sunucu mevcut değeri istemciye döndürür ve istemci, işlemi güncellenmiş değerle yeniden çalıştırır. Bu, işlem kabul edilene veya çok fazla deneme yapılana kadar tekrarlanır.

Verileri çevrimdışı yaz

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

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

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

Bağlantı yeniden kurulduğunda uygulamanız uygun olay kümesini alır, böylece istemci herhangi bir özel kod yazmak zorunda kalmadan mevcut sunucu durumuyla senkronize edilir.

Sonraki adımlar