Bezpieczeństwo to jeden z najbardziej złożonych elementów układanki tworzenia aplikacji. W większości aplikacji deweloperzy muszą utworzyć i uruchomić serwer obsługujący uwierzytelnianie (to, kim jest użytkownik) i autoryzację (co może robić użytkownik).
Firebase Security Rules usuwa warstwę środkową (serwer) i umożliwia określenie uprawnień opartych na ścieżce dla klientów łączących się bezpośrednio z Twoimi danymi. Z tego przewodnika dowiesz się więcej o stosowaniu reguł do żądań przychodzących.
Wybierz usługę, aby dowiedzieć się więcej o jej zasadach.
Cloud Firestore
Struktura podstawowa
Parametry Firebase Security Rules w funkcjach Cloud Firestore i Cloud Storage używają tej struktury i składni:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
Podczas tworzenia reguł warto znać te kluczowe pojęcia:
- Request: metoda lub metody wywołane w instrukcji
allow
. To metody, które zezwalasz na uruchamianie. Standardowe metody to:get
,list
,create
,update
idelete
. Metodyread
iwrite
umożliwiają szeroki dostęp do odczytu i zapisu w określonej bazie danych lub ścieżce magazynu. - Ścieżka: baza danych lub lokalizacja magazynu reprezentowana jako ścieżka URI.
- Reguła: instrukcja
allow
, która zawiera warunek zezwalający na żądanie, jeśli zostanie on uznany za prawdziwy.
Reguły zabezpieczeń (wersja 2)
Od maja 2019 roku dostępna jest wersja 2 reguł zabezpieczeń Firebase. Wersja 2 tych reguł zmienia działanie rekurencyjnych symboli wieloznacznych {name=**}
. Jeśli planujesz używać zapytań dotyczących grup kolekcji, musisz użyć wersji 2. Musisz wyrazić zgodę na wersję 2, ustawiając rules_version = '2';
jako pierwszy wiersz w regułach bezpieczeństwa:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
Ścieżki dopasowania
Wszystkie oświadczenia o dopasowaniu powinny wskazywać dokumenty, a nie kolekcje. Instrukcja dopasowania może wskazywać konkretny dokument, np. match /cities/SF
, lub używać symboli wieloznacznych do wskazywania dowolnego dokumentu w danej ścieżce, np. match /cities/{city}
.
W powyższym przykładzie instrukcja dopasowania używa składni zastępnika {city}
.
Oznacza to, że reguła dotyczy każdego dokumentu w kolekcji cities
, np. /cities/SF
lub /cities/NYC
. Podczas oceniania wyrażeń allow
w instrukcjach dopasowania zmienna city
zwróci nazwę dokumentu miasta, np. SF
lub NYC
.
Pasujące kolekcje podrzędne
Dane w usłudze Cloud Firestore są porządkowane w kolekcje dokumentów, a każdy dokument może rozszerzać hierarchię za pomocą podkolekcji. Ważne jest, aby zrozumieć, jak reguły zabezpieczeń współdziałają z danymi hierarchicznymi.
Weź pod uwagę sytuację, w której każdy dokument w kolekcji cities
zawiera kolekcję podrzędną landmarks
. Reguły bezpieczeństwa mają zastosowanie tylko w przypadku dopasowanej ścieżki, więc mechanizmy kontroli dostępu zdefiniowane w zbiorze cities
nie mają zastosowania do podzbioru landmarks
. Zamiast tego napisz wyraźne reguły, które będą kontrolować dostęp do podzbiorów:
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>;
}
}
}
}
Gdy zagnieżdżasz instrukcje match
, ścieżka wewnętrznej instrukcji match
jest zawsze względna względem ścieżki zewnętrznej instrukcji match
. Dlatego te zestawy reguł są równoważne:
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>;
}
}
}
Rekurencyjne symbole wieloznaczne
Jeśli chcesz, aby reguły były stosowane do dowolnej głębokiej hierarchii, użyj rekurencyjnej składni z symbolami wieloznacznymi, {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>;
}
}
}
Gdy używasz rekurencyjnej składni symboli wieloznacznych, zmienna symbolu wieloznacznego zawiera cały pasujący segment ścieżki, nawet jeśli dokument znajduje się w głęboko zagnieżdżonym podzbiorze. Wymienione powyżej reguły będą na przykład pasować do dokumentu znajdującego się pod adresem /cities/SF/landmarks/coit_tower
, a wartość zmiennej document
będzie wynosić SF/landmarks/coit_tower
.
Pamiętaj jednak, że działanie symboli wieloznacznych rekurencyjnych zależy od wersji reguł.
Wersja 1
Reguły zabezpieczeń domyślnie używają wersji 1. W wersji 1 rekurencyjne symbole wieloznaczne pasują do co najmniej 1 elementu ścieżki. Nie pasują do pustej ścieżki, więc reguła match /cities/{city}/{document=**}
dopasowuje dokumenty w kolekcjach podrzędnych, ale nie do kolekcji cities
, natomiast match /cities/{document=**}
pasuje zarówno do dokumentów w kolekcji cities
, jak i w kolekcjach podrzędnych.
Rekurencyjne symbole wieloznaczne muszą znajdować się na końcu oświadczenia o dopasowaniu.
Wersja 2
W wersji 2 reguł zabezpieczeń symbole wieloznaczne w regułach rekurencyjnych pasują do 0 lub więcej elementów ścieżki. match/cities/{city}/{document=**}
dopasowuje dokumenty ze wszystkich podkolekcji oraz dokumenty z kolekcji cities
.
Musisz zaakceptować wersję 2, dodając rules_version = '2';
u góry reguł zabezpieczeń:
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>;
}
}
}
W każdej instrukcji dopasowania można użyć maksymalnie 1 rekurencyjnego symbolu wieloznacznego, ale w wersji 2 możesz go umieścić w dowolnym miejscu w instrukcji dopasowania. Przykład:
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>;
}
}
}
Jeśli używasz zapytań dotyczących grup kolekcji, musisz używać wersji 2. Więcej informacji znajdziesz w sekcji Zabezpieczanie zapytań dotyczących grup kolekcji.
Nakładające się instrukcje dopasowania
Dokument może pasować do więcej niż jednej instrukcji match
. Jeśli wiele wyrażeń allow
pasuje do żądania, dostęp jest udzielany, jeśli co najmniej jedno z tych wyrażeń jest 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;
}
}
}
W powyższym przykładzie wszystkie operacje odczytu i zapisu do kolekcji cities
będą dozwolone, ponieważ druga reguła jest zawsze true
, mimo że pierwsza reguła jest zawsze false
.
Ograniczenia reguł zabezpieczeń
Podczas pracy z regułami zabezpieczeń pamiętaj o tych ograniczeniach:
Limit | Szczegóły |
---|---|
Maksymalna liczba wywołań funkcji exists() , get() i getAfter() na żądanie |
Przekroczenie któregokolwiek z tych limitów spowoduje błąd dotyczący braku uprawnień. Niektóre wywołania dostępu do dokumentu mogą być przechowywane w pamięci podręcznej, a wywołania z pamięci podręcznej nie wliczają się do limitów. |
Maksymalna głębokość zagnieżdżonego wyrażenia match |
10 |
Maksymalna długość ścieżki (w segmentach ścieżki) dozwolona w zbiorze ujęć zagnieżdżonych match |
100 |
Maksymalna liczba zmiennych przechwytywania ścieżki dozwolonych w zestawie zagnięć match |
20 |
Maksymalna głębokość wywołania funkcji | 20 |
Maksymalna liczba argumentów funkcji | 7 |
Maksymalna liczba powiązań zmiennych na funkcję (let ) |
10 |
Maksymalna liczba rekurencyjnych lub cyklicznych wywołań funkcji | 0 (niedozwolone) |
Maksymalna liczba wyrażeń ocenianych na żądanie | 1000 |
Maksymalny rozmiar zbioru reguł | Reguły muszą spełniać 2 limity rozmiaru:
|
Cloud Storage
Struktura podstawowa
Parametry Firebase Security Rules w funkcjach Cloud Firestore i Cloud Storage używają tej struktury i składni:
service <<name>> {
// Match the resource path.
match <<path>> {
// Allow the request if the following conditions are true.
allow <<methods>> : if <<condition>>
}
}
Podczas tworzenia reguł warto znać te kluczowe pojęcia:
- Request: metoda lub metody wywołane w instrukcji
allow
. To metody, które zezwalasz na uruchamianie. Standardowe metody to:get
,list
,create
,update
idelete
. Metodyread
iwrite
umożliwiają szeroki dostęp do odczytu i zapisu w określonej bazie danych lub ścieżce magazynu. - Ścieżka: baza danych lub lokalizacja magazynu reprezentowana jako ścieżka URI.
- Reguła: instrukcja
allow
zawierająca warunek, który zezwala na żądanie, jeśli zostanie ono spełnione.
Pasujące ścieżki
Cloud Storage Security Rules match
ścieżki do plików używane do uzyskiwania dostępu do plików w Cloud Storage. Reguły mogą match
określać dokładne ścieżki lub ścieżki z symbolami wieloznacznymi, a także mogą być zagnieżdżone. Jeśli reguła „Brak dopasowania” zezwala na metodę żądania lub warunek zwraca wartość false
, żądanie jest odrzucane.
Dopasowania ścisłe
// 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>; }
Zagnieżdżone dopasowania
// 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>; } }
Dopasowania z użyciem symboli wieloznacznych
Reguły mogą też służyć do match
wzorca za pomocą symboli wieloznacznych. Symbol wieloznaczny to nazwana zmienna, która reprezentuje pojedynczy ciąg znaków, np. profilePhoto.png
, lub wiele segmentów ścieżki, np. images/profilePhoto.png
.
Symbol wieloznaczny można utworzyć przez dodanie nawiasów klamrowych wokół nazwy symbolu wieloznacznego, np. {string}
. Symbol wieloznaczny dla wielu segmentów można zadeklarować, dodając do nazwy z symbolem wieloznacznym =**
, np. {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>; } }
Jeśli do pliku pasuje wiele reguł, wynik to OR
wyniku wszystkich reguł. Oznacza to, że jeśli dowolna reguła, która pasuje do pliku, ma wartość true
, wynik jest true
.
W powyższych regułach plik „images/profilePhoto.png” można odczytać, jeśli condition
lub other_condition
ma wartość prawda, a plik „images/users/user:12345/profilePhoto.png” podlega jedynie wynikowi other_condition
.
Dostęp do pliku match
można ograniczyć za pomocą nazwy pliku lub ścieżki za pomocą zmiennej wieloznacznej:
// Another way to restrict the name of a file match /images/{imageId} { allow read: if imageId == "profilePhoto.png"; }
Cloud Storage Security Rules nie są stosowane kaskadowo, a reguły są oceniane tylko wtedy, gdy ścieżka żądania pasuje do ścieżki ze zdefiniowanymi regułami.
Poproś o ocenę
Przesyłanie, pobieranie, zmiany metadanych i usuwanie są oceniane za pomocą request
wysłanego do Cloud Storage. Zmienna request
zawiera ścieżkę do pliku, w którym wykonywane jest żądanie, czas otrzymania żądania oraz nową wartość resource
, jeśli żądanie dotyczy zapisu. Obejmują one też nagłówki HTTP i stan uwierzytelniania.
Obiekt request
zawiera też unikalny identyfikator użytkownika oraz dane Firebase Authentication w obiekcie request.auth
, co zostanie wyjaśnione w sekcji Uwierzytelnianie w dokumentacji.
Pełna lista właściwości obiektu request
znajduje się poniżej:
Właściwość | Typ | Opis |
---|---|---|
auth |
mapa<ciąg, ciąg> | Gdy użytkownik jest zalogowany, przekazuje uid , czyli swój unikalny identyfikator, oraz token , czyli mapę Firebase Authentication deklaracji JWT. W przeciwnym razie będzie to:null . |
params |
map<string, string> | Mapa zawierająca parametry zapytania żądania. |
path |
ścieżka | path reprezentujący ścieżkę, po której wykonywane jest żądanie. |
resource |
mapa<ciąg, ciąg> | Nowa wartość zasobu, obecna tylko w przypadku żądań write .
|
time |
sygnatura czasowa | Znak czasowy określający czas serwera, w którym żądanie zostało ocenione. |
Ocena zasobów
Podczas oceny reguł możesz też ocenić metadane pliku, który jest przesyłany, pobierany, modyfikowany lub usuwany. Dzięki temu możesz tworzyć złożone i skuteczne reguły, które na przykład zezwalają na przesyłanie tylko plików z określonymi typami treści lub usuwanie tylko plików o większym rozmiarze.
Firebase Security Rules dla Cloud Storage udostępnia metadane pliku w obiekcie resource
, który zawiera pary klucz-wartość metadanych wyświetlanych w obiekcie Cloud Storage. Te właściwości można sprawdzić w prośbach read
lub write
, aby zapewnić integralność danych.
W przypadku żądań write
(takich jak przesyłanie, aktualizowanie metadanych i usuwanie) oprócz obiektu resource
, który zawiera metadane pliku znajdującego się obecnie na ścieżce żądania, możesz też użyć obiektu request.resource
, który zawiera podzbiór metadanych pliku do zapisania, jeśli zapis jest dozwolony. Możesz użyć tych 2 wartości, aby zapewnić integralność danych lub zastosować ograniczenia aplikacji, takie jak typ lub rozmiar pliku.
Pełną listę właściwości obiektu resource
znajdziesz poniżej:
Właściwość | Typ | Opis |
---|---|---|
name |
ciąg znaków | Pełna nazwa obiektu. |
bucket |
ciąg znaków | Nazwa zasobnika, w którym znajduje się ten obiekt. |
generation |
int, | Google Cloud Storagegeneracja obiektu tego obiektu. |
metageneration |
int, | Metageneracja obiektu Google Cloud Storage tego obiektu. |
size |
int, | Rozmiar obiektu w bajtach. |
timeCreated |
sygnatura czasowa | Sygnatura czasowa reprezentująca czas utworzenia obiektu. |
updated |
sygnatura czasowa | Sygnatura czasowa określająca, kiedy obiekt został ostatnio zaktualizowany. |
md5Hash |
ciąg znaków | Skrót MD5 obiektu. |
crc32c |
ciąg znaków | Hasz CRC32C obiektu. |
etag |
ciąg znaków | Etag powiązany z tym obiektem. |
contentDisposition |
ciąg znaków | Dyspozycja treści powiązana z tym obiektem. |
contentEncoding |
ciąg znaków | Kodowanie treści powiązane z tym obiektem. |
contentLanguage |
ciąg znaków | Język treści powiązany z tym obiektem. |
contentType |
ciąg znaków | Typ treści powiązany z tym obiektem. |
metadata |
mapa<ciąg, ciąg> | Pary klucz-wartość dodatkowych metadanych niestandardowych określonych przez dewelopera. |
request.resource
zawiera wszystkie te opcje oprócz generation
,
metageneration
, etag
, timeCreated
i updated
.
Ograniczenia reguł zabezpieczeń
Podczas pracy z regułami zabezpieczeń pamiętaj o tych ograniczeniach:
Limit | Szczegóły |
---|---|
Maksymalna liczba wywołań funkcji firestore.exists() i firestore.get() na żądanie |
2 w przypadku żądań dotyczących pojedynczego dokumentu i zapytań. Przekroczenie tego limitu powoduje błąd braku uprawnień. Dostęp do tych samych dokumentów może być zapisany w pamięci podręcznej, a wywołania z pamięci podręcznej nie są wliczane do limitów. |
Pełny przykład
Łącząc wszystkie te elementy, możesz utworzyć pełny przykład reguł dla rozwiązania do przechowywania obrazów:
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 } } } }
Realtime Database
Struktura podstawowa
W elementach Realtime Database wyrażenia Firebase Security Rules są wyrażeniami podobnymi do wyrażeń JavaScript zawartych w dokumencie JSON.
Używają one tej składni:
{
"rules": {
"<<path>>": {
// Allow the request if the condition for each method is true.
".read": <<condition>>,
".write": <<condition>>,
".validate": <<condition>>
}
}
}
Reguła składa się z 3 podstawowych elementów:
- Ścieżka: lokalizacja bazy danych. Odzwierciedla to strukturę JSON bazy danych.
- Żądanie: to metody, których reguła używa do przyznawania dostępu. Reguły
read
iwrite
przyznają szeroki dostęp do odczytu i zapisu, a regułyvalidate
pełnią rolę weryfikacji dodatkowej, aby przyznać dostęp na podstawie danych przychodzących lub istniejących. - Warunek: warunek, który zezwala na żądanie, jeśli jest prawdziwy.
Jak reguły są stosowane do ścieżek
W Realtime Database zasada Rules jest stosowana atomowo, co oznacza, że reguły w węzłach nadrzędnych wyższego poziomu zastępują reguły na bardziej szczegółowych węzłach podrzędnych, a reguły w głębszych węzłach nie mogą przyznawać dostępu do ścieżki nadrzędnej. Nie możesz zawęzić ani cofnąć dostępu na ścieżce niższej w strukturze bazy danych, jeśli masz już przyznane uprawnienia na jednej ze ścieżek nadrzędnych.
Weź pod uwagę te reguły:
{ "rules": { "foo": { // allows read to /foo/* ".read": "data.child('baz').val() === true", "bar": { // ignored, since read was allowed already ".read": false } } } }
Ta struktura zabezpieczeń umożliwia odczyt z /bar/
zawsze wtedy, gdy /foo/
zawiera element podrzędny baz
o wartości true
.
Reguła ".read": false
w poziomie /foo/bar/
nie ma tu zastosowania, ponieważ dostęp nie może zostać cofnięty przez ścieżkę podrzędną.
Chociaż może się to wydawać nieintuicyjne, jest to potężna część języka reguł, która umożliwia wdrażanie bardzo złożonych uprawnień dostępu z minimalnym wysiłkiem. Jest to szczególnie przydatne w przypadku zabezpieczeń opartych na użytkownikach.
.validate
reguł nie działają jednak kaskadowo. Aby zapis był dozwolony, wszystkie reguły weryfikacyjne muszą być spełnione na wszystkich poziomach hierarchii.
Dodatkowo, ponieważ reguły nie są stosowane do ścieżki nadrzędnej, operacja odczytu lub zapisu zakończy się niepowodzeniem, jeśli nie ma reguły w żądanej lokalizacji lub w lokalizacji nadrzędnej, która przyznaje dostęp. Nawet jeśli wszystkie ścieżki podrzędne są dostępne, odczyt w miejscu nadrzędnym zakończy się całkowitym niepowodzeniem. Rozważ tę strukturę:
{ "rules": { "records": { "rec1": { ".read": true }, "rec2": { ".read": false } } } }
Jeśli nie rozumiesz, że reguły są oceniane indywidualnie, możesz sądzić, że pobranie ścieżki /records/
zwróci wartość rec1
, a nie rec2
. Rzeczywisty wynik to jednak błąd:
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
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 }];
Swift
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 })
Java
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 }); });
REST
curl https://docs-examples.firebaseio.com/rest/records/ # response returns a PERMISSION_DENIED error
Operacja odczytu w miejscu /records/
jest atomowa i nie ma reguły odczytu, która przyznaje dostęp do wszystkich danych w miejscu /records/
, więc zostanie zwrócony błąd PERMISSION_DENIED
. Jeśli sprawdzimy tę regułę w symulatorze bezpieczeństwa w konsoli Firebase, zobaczymy, że operacja odczytu została odrzucona:
Attempt to read /records with auth=Success(null) / /records No .read rule allowed the operation. Read was denied.
Operacja została odrzucona, ponieważ żadna reguła dostępu do odczytu nie zezwalała na dostęp do ścieżki /records/
. Pamiętaj, że reguła dla ścieżki rec1
nigdy nie została zweryfikowana, ponieważ nie znajdowała się na ścieżce, której dotyczyło żądanie. Aby pobrać rec1
, musimy uzyskać do niego bezpośredni dostęp:
JavaScript
var db = firebase.database(); db.ref("records/rec1").once("value", function(snap) { // SUCCESS! }, function(err) { // error callback is not called });
Objective-C
FIRDatabaseReference *ref = [[FIRDatabase database] reference]; [[ref child:@"records/rec1"] observeSingleEventOfType:FEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) { // SUCCESS! }];
Swift
var ref = FIRDatabase.database().reference() ref.child("records/rec1").observeSingleEventOfType(.Value, withBlock: { snapshot in // SUCCESS! })
Java
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 } });
REST
curl https://docs-examples.firebaseio.com/rest/records/rec1 # SUCCESS!
Zmienna lokalizacji
Realtime Database Rules obsługuje zmienną $location
do dopasowywania segmentów ścieżki. Użyj prefiksu $
przed segmentem ścieżki, aby dopasować regułę do dowolnych węzłów podrzędnych na ścieżce.
{
"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')"
}
}
}
}
}
Możesz też używać $variable
równolegle z stałymi nazwami ścieżek.
{
"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 }
}
}
}