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

Cara kerja Aturan Keamanan

Keamanan dapat menjadi salah satu bagian paling kompleks dari teka-teki pengembangan aplikasi. Di sebagian besar aplikasi, pengembang harus membangun dan menjalankan server yang menangani autentikasi (siapa pengguna) dan otorisasi (apa yang dapat dilakukan pengguna).

Aturan Keamanan Firebase menghapus lapisan tengah (server) dan memungkinkan Anda menentukan izin berbasis jalur untuk klien yang terhubung ke data Anda secara langsung. Gunakan panduan ini untuk mempelajari lebih lanjut tentang bagaimana aturan diterapkan pada permintaan yang masuk.

Pilih produk untuk mempelajari lebih lanjut aturannya.

Toko Api Awan

Struktur dasar

Aturan Keamanan Firebase di Cloud Firestore dan Cloud Storage menggunakan struktur dan sintaks berikut:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

Konsep kunci berikut ini penting untuk dipahami saat Anda membuat aturan:

  • Permintaan: Metode atau metode yang dipanggil dalam pernyataan allow . Ini adalah metode yang Anda izinkan untuk dijalankan. Metode standarnya adalah: get , list , create , update , dan delete . Metode kenyamanan read dan write memungkinkan akses baca dan tulis yang luas pada database atau jalur penyimpanan yang ditentukan.
  • Jalur: Database atau lokasi penyimpanan, direpresentasikan sebagai jalur URI.
  • Aturan: Pernyataan allow , yang menyertakan kondisi yang mengizinkan permintaan jika bernilai benar.

Aturan keamanan versi 2

Mulai Mei 2019, aturan keamanan Firebase versi 2 kini tersedia. Aturan versi 2 mengubah perilaku wildcard rekursif {name=**} . Anda harus menggunakan versi 2 jika berencana menggunakan kueri grup koleksi . Anda harus ikut serta ke versi 2 dengan membuat rules_version = '2'; baris pertama dalam aturan keamanan Anda:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

Jalur yang cocok

Semua pernyataan kecocokan harus mengarah ke dokumen, bukan koleksi. Pernyataan kecocokan dapat mengarah ke dokumen tertentu, seperti pada match /cities/SF atau menggunakan wildcard untuk menunjuk ke dokumen apa pun di jalur yang ditentukan, seperti pada match /cities/{city} .

Pada contoh di atas, pernyataan kecocokan menggunakan sintaks karakter pengganti {city} . Ini berarti aturan tersebut berlaku untuk semua dokumen dalam kumpulan cities , seperti /cities/SF atau /cities/NYC . Saat ekspresi allow dalam pernyataan kecocokan dievaluasi, variabel city akan menyelesaikan ke nama dokumen kota, seperti SF atau NYC .

Mencocokkan subkoleksi

Data di Cloud Firestore diatur ke dalam kumpulan dokumen, dan setiap dokumen dapat memperluas hierarki melalui subkoleksi. Penting untuk memahami bagaimana aturan keamanan berinteraksi dengan data hierarkis.

Pertimbangkan situasi di mana setiap dokumen dalam koleksi cities berisi subkoleksi landmarks . Aturan keamanan hanya berlaku pada jalur yang cocok, sehingga kontrol akses yang ditentukan pada kumpulan cities tidak berlaku pada subkoleksi landmarks . Sebagai gantinya, tulis aturan eksplisit untuk mengontrol akses ke subkoleksi:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      allow read, write: if <condition>;

      // Explicitly define rules for the 'landmarks' subcollection
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}

Saat pernyataan match bersarang, jalur pernyataan match dalam selalu relatif terhadap jalur pernyataan match luar. Oleh karena itu, kumpulan aturan berikut setara:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}
service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city}/landmarks/{landmark} {
      allow read, write: if <condition>;
    }
  }
}

Wildcard rekursif

Jika Anda ingin aturan diterapkan ke hierarki dalam yang sewenang-wenang, gunakan sintaks karakter pengganti rekursif, {name=**} :

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

Saat menggunakan sintaks wildcard rekursif, variabel wildcard akan berisi seluruh segmen jalur yang cocok, bahkan jika dokumen berada di subkoleksi bersarang dalam. Misalnya, aturan yang tercantum di atas akan cocok dengan dokumen yang terletak di /cities/SF/landmarks/coit_tower , dan nilai variabel document adalah SF/landmarks/coit_tower .

Perhatikan, bagaimanapun, bahwa perilaku wildcard rekursif bergantung pada versi aturan.

Versi 1

Aturan keamanan menggunakan versi 1 secara default. Di versi 1, wildcard rekursif cocok dengan satu atau beberapa item jalur. Mereka tidak cocok dengan jalur kosong, jadi match /cities/{city}/{document=**} cocok dengan dokumen di subkoleksi tetapi tidak cocok dengan koleksi cities , sedangkan match /cities/{document=**} cocok dengan kedua dokumen di koleksi cities dan subkoleksi.

Wildcard rekursif harus muncul di akhir pernyataan pertandingan.

Versi 2

Di versi 2 aturan keamanan, karakter pengganti rekursif cocok dengan nol atau beberapa item jalur. match/cities/{city}/{document=**} cocok dengan dokumen di subkoleksi mana pun serta dokumen di koleksi cities .

Anda harus ikut serta ke versi 2 dengan menambahkan rules_version = '2'; di bagian atas aturan keamanan Anda:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{city}/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

Anda dapat memiliki paling banyak satu wildcard rekursif per pernyataan kecocokan, tetapi dalam versi 2, Anda dapat menempatkan wildcard ini di mana saja dalam pernyataan kecocokan. Sebagai contoh:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the songs collection group
    match /{path=**}/songs/{song} {
      allow read, write: if <condition>;
    }
  }
}

Jika Anda menggunakan kueri grup koleksi , Anda harus menggunakan versi 2, lihat mengamankan kueri grup koleksi .

Pernyataan pertandingan yang tumpang tindih

Sebuah dokumen mungkin cocok dengan lebih dari satu pernyataan yang match . Dalam kasus di mana beberapa ekspresi yang allow cocok dengan permintaan, akses diizinkan jika salah satu kondisinya true :

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the 'cities' collection.
    match /cities/{city} {
      allow read, write: if false;
    }

    // Matches any document in the 'cities' collection or subcollections.
    match /cities/{document=**} {
      allow read, write: if true;
    }
  }
}

Pada contoh di atas, semua pembacaan dan penulisan ke koleksi cities akan diizinkan karena aturan kedua selalu true , meskipun aturan pertama selalu false .

Batas aturan keamanan

Saat Anda bekerja dengan aturan keamanan, perhatikan batasan berikut:

Membatasi Detail
Jumlah maksimum panggilan existing( exists() , get() , dan getAfter() per permintaan
  • 10 untuk permintaan dokumen tunggal dan permintaan kueri.
  • 20 untuk pembacaan multi-dokumen, transaksi, dan penulisan batch. Batas 10 sebelumnya juga berlaku untuk setiap operasi.

    Misalnya, bayangkan Anda membuat permintaan tulis batch dengan 3 operasi tulis dan aturan keamanan Anda menggunakan 2 panggilan akses dokumen untuk memvalidasi setiap penulisan. Dalam hal ini, setiap penulisan menggunakan 2 dari 10 panggilan aksesnya dan permintaan tulis batch menggunakan 6 dari 20 panggilan aksesnya.

Melebihi salah satu batas akan menyebabkan kesalahan penolakan izin.

Beberapa panggilan akses dokumen mungkin di-cache, dan panggilan yang di-cache tidak diperhitungkan dalam batas.

Kedalaman pernyataan match bersarang maksimum 10
Panjang jalur maksimum, dalam segmen jalur, diizinkan dalam kumpulan pernyataan match bersarang 100
Jumlah maksimum variabel tangkapan jalur yang diizinkan dalam kumpulan pernyataan match bersarang 20
Kedalaman panggilan fungsi maksimum 20
Jumlah maksimum argumen fungsi 7
Jumlah maksimum pengikatan variabel let per fungsi 10
Jumlah maksimum pemanggilan fungsi rekursif atau siklis 0 (tidak diizinkan)
Jumlah maksimum ekspresi yang dievaluasi per permintaan 1.000
Ukuran maksimum kumpulan aturan Kumpulan aturan harus mematuhi dua batas ukuran:
  • batas 256 KB untuk ukuran sumber teks kumpulan aturan yang dipublikasikan dari Firebase console atau dari CLI menggunakan firebase deploy .
  • batas 250 KB untuk ukuran kumpulan aturan terkompilasi yang dihasilkan saat Firebase memproses sumber dan mengaktifkannya di back-end.

Penyimpanan awan

Struktur dasar

Aturan Keamanan Firebase di Cloud Firestore dan Cloud Storage menggunakan struktur dan sintaks berikut:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

Konsep kunci berikut ini penting untuk dipahami saat Anda membuat aturan:

  • Permintaan: Metode atau metode yang dipanggil dalam pernyataan allow . Ini adalah metode yang Anda izinkan untuk dijalankan. Metode standarnya adalah: get , list , create , update , dan delete . Metode kenyamanan read dan write memungkinkan akses baca dan tulis yang luas pada database atau jalur penyimpanan yang ditentukan.
  • Jalur: Database atau lokasi penyimpanan, direpresentasikan sebagai jalur URI.
  • Aturan: Pernyataan allow , yang menyertakan kondisi yang mengizinkan permintaan jika bernilai benar.

Jalur yang cocok

Aturan Keamanan Cloud Storage match dengan jalur file yang digunakan untuk mengakses file di Cloud Storage. Aturan bisa match dengan jalur persis atau jalur wildcard, dan aturan juga bisa bersarang. Jika tidak ada aturan kecocokan yang mengizinkan metode permintaan, atau kondisi bernilai false , permintaan ditolak.

Cocok persis

// Exact match for "images/profilePhoto.png"
match /images/profilePhoto.png {
  allow write: if <condition>;
}

// Exact match for "images/croppedProfilePhoto.png"
match /images/croppedProfilePhoto.png {
  allow write: if <other_condition>;
}

Pertandingan bersarang

// Partial match for files that start with "images"
match /images {
  // Exact match for "images/profilePhoto.png"
  match /profilePhoto.png {
    allow write: if <condition>;
  }

  // Exact match for "images/croppedProfilePhoto.png"
  match /croppedProfilePhoto.png {
    allow write: if <other_condition>;
  }
}

Pertandingan kartu liar

Aturan juga dapat digunakan untuk match pola menggunakan wildcard. Karakter pengganti adalah variabel bernama yang mewakili string tunggal seperti profilePhoto.png , atau beberapa segmen jalur, seperti images/profilePhoto.png .

Wildcard dibuat dengan menambahkan kurung kurawal di sekitar nama wildcard, seperti {string} . Wildcard beberapa segmen dapat dideklarasikan dengan menambahkan =** ke nama wildcard, seperti {path=**} :

// Partial match for files that start with "images"
match /images {
  // Exact match for "images/*"
  // e.g. images/profilePhoto.png is matched
  match /{imageId} {
    // This rule only matches a single path segment (*)
    // imageId is a string that contains the specific segment matched
    allow read: if <condition>;
  }

  // Exact match for "images/**"
  // e.g. images/users/user:12345/profilePhoto.png is matched
  // images/profilePhoto.png is also matched!
  match /{allImages=**} {
    // This rule matches one or more path segments (**)
    // allImages is a path that contains all segments matched
    allow read: if <other_condition>;
  }
}

Jika beberapa aturan cocok dengan file, hasilnya adalah OR dari hasil semua evaluasi aturan. Artinya, jika ada aturan yang cocok dengan file yang dievaluasi menjadi true , hasilnya adalah true .

Pada aturan di atas, file "images/profilePhoto.png" dapat dibaca jika salah satu condition atau other_condition bernilai true, sedangkan file "images/users/user:12345/profilePhoto.png" hanya tunduk pada hasil other_condition .

Variabel wildcard dapat direferensikan dari dalam match memberikan nama file atau otorisasi jalur:

// Another way to restrict the name of a file
match /images/{imageId} {
  allow read: if imageId == "profilePhoto.png";
}

Aturan Keamanan Cloud Storage tidak menurun, dan aturan hanya dievaluasi saat jalur permintaan cocok dengan jalur dengan aturan yang ditentukan.

Minta evaluasi

Upload, download, perubahan metadata, dan penghapusan dievaluasi menggunakan request yang dikirim ke Cloud Storage. Variabel request berisi jalur file tempat permintaan dilakukan, waktu saat permintaan diterima, dan nilai resource baru jika permintaan berupa penulisan. Header HTTP dan status autentikasi juga disertakan.

Objek request juga berisi ID unik pengguna dan muatan Firebase Authentication di objek request.auth , yang akan dijelaskan lebih lanjut di bagian Otentikasi pada dokumen.

Daftar lengkap properti di objek request tersedia di bawah ini:

Properti Jenis Keterangan
auth peta<string, string> Saat pengguna masuk, uid , ID unik pengguna, dan token , peta klaim Firebase Authentication JWT. Jika tidak, itu akan menjadi null .
params peta<string, string> Peta yang berisi parameter kueri permintaan.
path jalur path yang mewakili jalur permintaan sedang dilakukan.
resource peta<string, string> Nilai sumber daya baru, hanya ada pada permintaan write .
time cap waktu Stempel waktu yang mewakili waktu server saat permintaan dievaluasi.

Evaluasi sumber daya

Saat mengevaluasi aturan, Anda mungkin juga ingin mengevaluasi metadata file yang sedang diunggah, diunduh, diubah, atau dihapus. Ini memungkinkan Anda untuk membuat aturan yang kompleks dan kuat yang melakukan hal-hal seperti hanya mengizinkan file dengan tipe konten tertentu untuk diunggah, atau hanya file yang berukuran lebih besar dari ukuran tertentu yang akan dihapus.

Aturan Keamanan Firebase untuk Cloud Storage menyediakan metadata file di objek resource , yang berisi pasangan kunci/nilai dari metadata yang muncul di objek Cloud Storage. Properti ini dapat diperiksa pada permintaan read atau write untuk memastikan integritas data.

Pada permintaan write (seperti unggahan, pembaruan metadata, dan penghapusan), selain objek resource , yang berisi metadata file untuk file yang saat ini ada di jalur permintaan, Anda juga memiliki kemampuan untuk menggunakan objek request.resource , yang berisi subset dari metadata file yang akan ditulis jika penulisan diizinkan. Anda dapat menggunakan kedua nilai ini untuk memastikan integritas data atau menerapkan batasan aplikasi seperti jenis atau ukuran file.

Daftar lengkap properti di objek resource tersedia di bawah ini:

Properti Jenis Keterangan
name rangkaian Nama lengkap objek
bucket rangkaian Nama bucket tempat objek ini berada.
generation int Pembuatan objek Google Cloud Storage dari objek ini.
metageneration int Metagenerasi objek Google Cloud Storage dari objek ini.
size int Ukuran objek dalam byte.
timeCreated cap waktu Stempel waktu yang menunjukkan waktu pembuatan objek.
updated cap waktu Stempel waktu yang menunjukkan waktu objek terakhir diperbarui.
md5Hash rangkaian Hash MD5 dari objek.
crc32c rangkaian Hash crc32c dari objek.
etag rangkaian Etag yang terkait dengan objek ini.
contentDisposition rangkaian Disposisi konten yang terkait dengan objek ini.
contentEncoding rangkaian Encoding konten yang terkait dengan objek ini.
contentLanguage rangkaian Bahasa konten yang terkait dengan objek ini.
contentType rangkaian Jenis konten yang terkait dengan objek ini.
metadata peta<string, string> Pasangan kunci/nilai tambahan, metadata khusus yang ditentukan pengembang.

request.resource berisi semua ini kecuali generation , metageneration , etag , timeCreated , dan updated .

batas Aturan Keamanan

Saat Anda bekerja dengan aturan keamanan, perhatikan batasan berikut:

Membatasi Detail
Jumlah maksimum panggilan firestore.exists() dan firestore.get() per permintaan

2 untuk permintaan dokumen tunggal dan permintaan kueri.

Melebihi batas ini akan menyebabkan kesalahan penolakan izin.

Akses panggilan ke dokumen yang sama mungkin di-cache, dan panggilan yang di-cache tidak diperhitungkan dalam batas.

Contoh Lengkap

Menyatukan semuanya, Anda dapat membuat contoh lengkap aturan untuk solusi penyimpanan gambar:

service firebase.storage {
 match /b/{bucket}/o {
   match /images {
     // Cascade read to any image type at any path
     match /{allImages=**} {
       allow read;
     }

     // Allow write files to the path "images/*", subject to the constraints:
     // 1) File is less than 5MB
     // 2) Content type is an image
     // 3) Uploaded content type matches existing content type
     // 4) File name (stored in imageId wildcard variable) is less than 32 characters
     match /{imageId} {
       allow write: if request.resource.size < 5 * 1024 * 1024
                    && request.resource.contentType.matches('image/.*')
                    && request.resource.contentType == resource.contentType
                    && imageId.size() < 32
     }
   }
 }
}

Basis Data Waktu Nyata

Struktur dasar

Dalam Realtime Database, Aturan Keamanan Firebase terdiri dari ekspresi mirip JavaScript yang terdapat dalam dokumen JSON.

Mereka menggunakan sintaks berikut:

{
  "rules": {
    "<<path>>": {
    // Allow the request if the condition for each method is true.
      ".read": <<condition>>,
      ".write": <<condition>>,
      ".validate": <<condition>>
    }
  }
}

Ada tiga elemen dasar dalam aturan:

  • Path: Lokasi database. Ini mencerminkan struktur JSON basis data Anda.
  • Permintaan: Ini adalah metode yang digunakan aturan untuk memberikan akses. Aturan read dan write memberikan akses baca dan tulis yang luas, sedangkan aturan validate bertindak sebagai verifikasi sekunder untuk memberikan akses berdasarkan data yang masuk atau yang ada.
  • Kondisi: Kondisi yang mengizinkan permintaan jika bernilai benar.

Bagaimana aturan berlaku untuk jalur

Dalam Realtime Database, Aturan berlaku secara atomis, artinya aturan pada node induk tingkat tinggi menggantikan aturan pada node anak yang lebih terperinci dan aturan pada node yang lebih dalam tidak dapat memberikan akses ke jalur induk. Anda tidak dapat menyaring atau mencabut akses pada jalur yang lebih dalam di struktur database Anda jika Anda telah memberikannya untuk salah satu jalur induk.

Pertimbangkan aturan berikut:

{
  "rules": {
     "foo": {
        // allows read to /foo/*
        ".read": "data.child('baz').val() === true",
        "bar": {
          // ignored, since read was allowed already
          ".read": false
        }
     }
  }
}

Struktur keamanan ini memungkinkan /bar/ untuk dibaca kapan pun /foo/ berisi baz anak dengan nilai true . Aturan ".read": false di bawah /foo/bar/ tidak berpengaruh di sini, karena akses tidak dapat dicabut oleh jalur anak.

Meskipun mungkin tidak langsung tampak intuitif, ini adalah bagian yang kuat dari bahasa aturan dan memungkinkan hak akses yang sangat kompleks untuk diimplementasikan dengan sedikit usaha. Ini sangat berguna untuk keamanan berbasis pengguna .

Namun, aturan .validate tidak mengalir. Semua aturan validasi harus dipenuhi di semua tingkat hierarki agar penulisan diizinkan.

Selain itu, karena aturan tidak berlaku kembali ke jalur induk, operasi baca atau tulis gagal jika tidak ada aturan di lokasi yang diminta atau di lokasi induk yang memberikan akses. Bahkan jika setiap jalur anak yang terpengaruh dapat diakses, membaca di lokasi induk akan gagal total. Pertimbangkan struktur ini:

{
  "rules": {
    "records": {
      "rec1": {
        ".read": true
      },
      "rec2": {
        ".read": false
      }
    }
  }
}

Tanpa memahami bahwa aturan dievaluasi secara atomis, sepertinya mengambil jalur /records/ akan mengembalikan rec1 tetapi tidak rec2 . Hasil sebenarnya, bagaimanapun, adalah kesalahan:

JavaScript
var db = firebase.database();
db.ref("records").once("value", function(snap) {
  // success method is not called
}, function(err) {
  // error callback triggered with PERMISSION_DENIED
});
Objective-C
Catatan: Produk Firebase ini tidak tersedia di target Cuplikan Aplikasi.
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[_ref child:@"records"] observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
  // success block is not called
} withCancelBlock:^(NSError * _Nonnull error) {
  // cancel block triggered with PERMISSION_DENIED
}];
Cepat
Catatan: Produk Firebase ini tidak tersedia di target Cuplikan Aplikasi.
var ref = FIRDatabase.database().reference()
ref.child("records").observeSingleEventOfType(.Value, withBlock: { snapshot in
    // success block is not called
}, withCancelBlock: { error in
    // cancel block triggered with PERMISSION_DENIED
})
Jawa
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("records");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    // success method is not called
  }

  @Override
  public void onCancelled(FirebaseError firebaseError) {
    // error callback triggered with PERMISSION_DENIED
  });
});
ISTIRAHAT
curl https://docs-examples.firebaseio.com/rest/records/
# response returns a PERMISSION_DENIED error

Karena operasi baca di /records/ bersifat atomik, dan tidak ada aturan baca yang memberikan akses ke semua data di bawah /records/ , ini akan menimbulkan kesalahan PERMISSION_DENIED . Jika kami mengevaluasi aturan ini di simulator keamanan di konsol Firebase kami, kami dapat melihat bahwa operasi baca ditolak:

Attempt to read /records with auth=Success(null)
    /
    /records

No .read rule allowed the operation.
Read was denied.

Operasi ditolak karena tidak ada aturan baca yang mengizinkan akses ke jalur /records/ , tetapi perhatikan bahwa aturan untuk rec1 tidak pernah dievaluasi karena tidak ada di jalur yang kami minta. Untuk mengambil rec1 , kita perlu mengaksesnya secara langsung:

JavaScript
var db = firebase.database();
db.ref("records/rec1").once("value", function(snap) {
  // SUCCESS!
}, function(err) {
  // error callback is not called
});
Objective-C
Catatan: Produk Firebase ini tidak tersedia di target Cuplikan Aplikasi.
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[ref child:@"records/rec1"] observeSingleEventOfType:FEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
    // SUCCESS!
}];
Cepat
Catatan: Produk Firebase ini tidak tersedia di target Cuplikan Aplikasi.
var ref = FIRDatabase.database().reference()
ref.child("records/rec1").observeSingleEventOfType(.Value, withBlock: { snapshot in
    // SUCCESS!
})
Jawa
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("records/rec1");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    // SUCCESS!
  }

  @Override
  public void onCancelled(FirebaseError firebaseError) {
    // error callback is not called
  }
});
ISTIRAHAT
curl https://docs-examples.firebaseio.com/rest/records/rec1
# SUCCESS!

Variabel lokasi

Aturan Realtime Database mendukung variabel $location untuk mencocokkan segmen jalur. Gunakan awalan $ di depan segmen jalur Anda untuk mencocokkan aturan Anda dengan simpul anak mana pun di sepanjang jalur.

  {
    "rules": {
      "rooms": {
        // This rule applies to any child of /rooms/, the key for each room id
        // is stored inside $room_id variable for reference
        "$room_id": {
          "topic": {
            // The room's topic can be changed if the room id has "public" in it
            ".write": "$room_id.contains('public')"
          }
        }
      }
    }
  }

Anda juga dapat menggunakan $variable secara paralel dengan nama jalur konstan.

  {
    "rules": {
      "widget": {
        // a widget can have a title or color attribute
        "title": { ".validate": true },
        "color": { ".validate": true },

        // but no other child paths are allowed
        // in this case, $other means any key excluding "title" and "color"
        "$other": { ".validate": false }
      }
    }
  }