Ikuti semua informasi yang diumumkan di Firebase Summit, dan pelajari bagaimana Firebase dapat membantu Anda mempercepat pengembangan aplikasi dan menjalankan aplikasi dengan percaya diri. Pelajari Lebih Lanjut

Simpan Data

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

Sebelum kamu memulai

Sebelum dapat menggunakan Realtime Database , Anda perlu:

  • Daftarkan proyek Unity Anda dan konfigurasikan untuk menggunakan Firebase.

    • Jika project Unity Anda sudah menggunakan Firebase, maka project tersebut sudah terdaftar dan dikonfigurasi untuk Firebase.

    • Jika Anda tidak memiliki proyek Unity, Anda dapat mengunduh contoh aplikasi .

  • Tambahkan Firebase Unity SDK (khususnya, FirebaseDatabase.unitypackage ) ke proyek Unity Anda.

Perhatikan bahwa menambahkan Firebase ke proyek Unity Anda melibatkan tugas di konsol Firebase dan di proyek Unity terbuka Anda (misalnya, Anda mengunduh file konfigurasi Firebase dari konsol, lalu memindahkannya ke proyek Unity Anda).

Menyimpan Data

Ada lima metode untuk menulis data ke Firebase Realtime Database:

metode Penggunaan umum
SetValueAsync() Tulis atau ganti data ke jalur yang ditentukan, seperti users/<user-id>/<username> .
SetRawJsonValueAsync() Tulis atau ganti data dengan Json mentah, seperti users/<user-id>/<username> .
Push() Tambahkan ke daftar data. Setiap kali Anda memanggil Push() , Firebase menghasilkan kunci unik yang juga dapat digunakan sebagai pengidentifikasi unik, seperti user-scores/<user-id>/<unique-score-id> .
UpdateChildrenAsync() Perbarui beberapa kunci untuk jalur yang ditentukan tanpa mengganti semua data.
RunTransaction() Perbarui data kompleks yang dapat rusak oleh pembaruan bersamaan.

Dapatkan Referensi Basis Data

Untuk menulis data ke Database, Anda memerlukan instance dari DatabaseReference :

using Firebase;
using Firebase.Database;

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

Tulis, perbarui, atau hapus data pada referensi

Operasi tulis dasar

Untuk operasi tulis dasar, Anda dapat menggunakan SetValueAsync() untuk menyimpan data ke referensi tertentu, menggantikan data yang ada di jalur tersebut. Anda dapat menggunakan metode ini untuk meneruskan tipe yang sesuai dengan tipe JSON yang tersedia sebagai berikut:

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

Jika Anda menggunakan objek C# yang diketik, Anda dapat menggunakan JsonUtility.ToJson() untuk mengonversi objek menjadi Json mentah dan memanggil SetRawJsonValueAsync() . Misalnya, Anda mungkin memiliki kelas Pengguna yang terlihat seperti berikut:

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

    public User() {
    }

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

Anda dapat menambahkan pengguna dengan SetRawJsonValueAsync() sebagai berikut:

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

Menggunakan SetValueAsync() atau SetRawJsonValueAsync() dengan cara ini akan menimpa data di lokasi yang ditentukan, termasuk simpul anak mana pun. Namun, Anda masih dapat memperbarui anak tanpa menulis ulang seluruh objek. Jika Anda ingin mengizinkan pengguna memperbarui profil mereka, Anda dapat memperbarui nama pengguna sebagai berikut:

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

Tambahkan ke daftar data

Gunakan metode Push() untuk menambahkan data ke daftar dalam aplikasi multipengguna. Metode Push() menghasilkan kunci unik setiap kali anak baru ditambahkan ke referensi Firebase yang ditentukan. Dengan menggunakan kunci yang dihasilkan secara otomatis ini untuk setiap elemen baru dalam daftar, beberapa klien dapat menambahkan turunan ke lokasi yang sama pada waktu yang sama tanpa konflik penulisan. Kunci unik yang dihasilkan oleh Push() didasarkan pada stempel waktu, sehingga item daftar secara otomatis diurutkan secara kronologis.

Anda dapat menggunakan referensi ke data baru yang dikembalikan oleh metode Push() untuk mendapatkan nilai kunci anak yang dibuat secara otomatis atau set data untuk anak tersebut. Memanggil Key pada referensi Push() mengembalikan nilai kunci yang dihasilkan secara otomatis.

Perbarui bidang tertentu

Untuk secara bersamaan menulis ke node anak tertentu tanpa menimpa node anak lainnya, gunakan metode UpdateChildrenAsync() .

Saat memanggil UpdateChildrenAsync() , Anda bisa memperbarui nilai anak tingkat rendah dengan menentukan jalur untuk kunci tersebut. Jika data disimpan di beberapa lokasi untuk menskalakan dengan lebih baik, Anda dapat memperbarui semua contoh data tersebut menggunakan data fan-out . Misalnya, game mungkin memiliki kelas LeaderboardEntry seperti ini:

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

Untuk membuat LeaderboardEntry dan memperbaruinya secara bersamaan ke feed skor terbaru dan daftar skor milik pengguna, game menggunakan kode seperti ini:

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

Contoh ini menggunakan Push() untuk membuat entri di node yang berisi entri untuk semua pengguna di /scores/$key dan sekaligus mengambil kunci dengan Key . Kunci kemudian dapat digunakan untuk membuat entri kedua dalam skor pengguna di /user-scores/$userid/$key .

Dengan menggunakan jalur ini, Anda dapat melakukan pembaruan serentak ke beberapa lokasi di pohon JSON dengan satu panggilan ke UpdateChildrenAsync() , seperti bagaimana contoh ini membuat entri baru di kedua lokasi. Pembaruan simultan yang dilakukan dengan cara ini bersifat atomik: semua pembaruan berhasil atau semua pembaruan gagal.

Hapus data

Cara termudah untuk menghapus data adalah dengan memanggil RemoveValue() pada referensi ke lokasi data tersebut.

Anda juga dapat menghapus dengan menentukan null sebagai nilai untuk operasi tulis lainnya seperti SetValueAsync() atau UpdateChildrenAsync() . Anda dapat menggunakan teknik ini dengan UpdateChildrenAsync() untuk menghapus beberapa turunan dalam satu panggilan API.

Ketahui kapan data Anda dikomit.

Untuk mengetahui kapan data Anda dikomit ke server Firebase Realtime Database, Anda dapat menambahkan kelanjutan. SetValueAsync() dan UpdateChildrenAsync() mengembalikan Task yang memungkinkan Anda mengetahui kapan operasi selesai. Jika panggilan tidak berhasil karena alasan apa pun, Tasks IsFaulted akan benar dengan properti Exception yang menunjukkan mengapa kegagalan terjadi.

Simpan data sebagai transaksi

Saat bekerja dengan data yang dapat dirusak oleh modifikasi bersamaan, seperti penghitung inkremental, Anda dapat menggunakan operasi transaksi . Anda memberikan operasi ini Func . Func pembaruan ini mengambil status data saat ini sebagai argumen dan mengembalikan status baru yang diinginkan yang ingin Anda tulis. Jika klien lain menulis ke lokasi sebelum nilai baru Anda berhasil ditulis, fungsi pembaruan Anda dipanggil lagi dengan nilai baru saat ini, dan penulisan dicoba lagi.

Misalnya, dalam game, Anda dapat mengizinkan pengguna memperbarui papan peringkat dengan lima skor tertinggi:

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

Menggunakan transaksi mencegah kesalahan papan peringkat jika beberapa pengguna mencatat skor pada saat yang sama atau klien memiliki data yang sudah usang. Jika transaksi ditolak, server mengembalikan nilai saat ini ke klien, yang menjalankan transaksi lagi dengan nilai yang diperbarui. Ini berulang sampai transaksi diterima atau terlalu banyak upaya telah dilakukan.

Menulis data offline

Jika klien kehilangan koneksi jaringannya, aplikasi Anda akan terus berfungsi dengan benar.

Setiap klien yang terhubung ke database Firebase mempertahankan versi internalnya sendiri dari setiap data aktif. Saat data ditulis, data ditulis ke versi lokal ini terlebih dahulu. Klien Firebase kemudian menyinkronkan data tersebut dengan server basis data jarak jauh dan dengan klien lain berdasarkan "upaya terbaik".

Akibatnya, semua penulisan ke database segera memicu peristiwa lokal, sebelum data apa pun ditulis ke server. Ini berarti aplikasi Anda tetap responsif terlepas dari latensi atau konektivitas jaringan.

Setelah konektivitas dibangun kembali, aplikasi Anda menerima rangkaian peristiwa yang sesuai sehingga klien menyinkronkan dengan status server saat ini, tanpa harus menulis kode khusus apa pun.

Langkah selanjutnya