Możesz użyć Firebase Security Rules, aby warunkowo zapisywać nowe dane na podstawie istniejących danych w bazie danych lub zasobniku pamięci masowej. Możesz też pisać reguły, które wymuszają sprawdzanie poprawności danych, ograniczając zapisywanie na podstawie nowych danych. Przeczytaj ten artykuł, aby dowiedzieć się więcej o regułach, które używają istniejących danych do tworzenia warunków bezpieczeństwa.
Wybierz usługę w każdej sekcji, aby dowiedzieć się więcej o regułach sprawdzania poprawności danych.
prompt AI dla pomocy AI
Aby uzyskać pomoc AI, skopiuj poniższy prompt do swojego agenta kodowania AI (takiego jak Gemini w Android Studio, Antigravity, Claude Code, Codex czy Cursor). Możesz dostosować prompta i wprowadzać zmiany z agentem. Szczegółowe informacje o instalacji znajdziesz w artykule Umiejętności agenta Firebase.
Help me use Firebase in my app.
1. Make sure that **Firebase agent skills** are installed and updated. For Claude Code, Codex, or Cursor agents, help me install the Firebase plugin. For other agents, run `npx skills add firebase/agent-skills`. Always try to use **Firebase agent skills** for Firebase-related tasks.
2. Help me write, validate, and deploy Firebase Security Rules to protect my app's data.
Ograniczenia dotyczące nowych danych
Cloud Firestore
Jeśli chcesz mieć pewność, że dokument zawierający określone pole nie zostanie utworzony, możesz uwzględnić to pole w warunku allow. Jeśli na przykład chcesz uniemożliwić tworzenie dokumentów zawierających pole ranking, możesz je zablokować w warunku create.
service cloud.firestore {
match /databases/{database}/documents {
// Disallow
match /cities/{city} {
allow create: if !("ranking" in request.resource.data)
}
}
}
Realtime Database
Jeśli chcesz mieć pewność, że dane zawierające określone wartości nie zostaną dodane do bazy danych, uwzględnij tę wartość w regułach i nie zezwalaj na jej zapisywanie. Jeśli na przykład chcesz odrzucić wszystkie zapisy zawierające wartości ranking, możesz zablokować zapisywanie wszystkich dokumentów z wartościami ranking.
{
"rules": {
// Write is allowed for all paths
".write": true,
// Allows writes only if new data doesn't include a `ranking` child value
".validate": "!newData.hasChild('ranking')
}
}
Cloud Storage
Jeśli chcesz mieć pewność, że plik zawierający określone metadane nie zostanie utworzony, możesz uwzględnić te metadane w warunku allow. Jeśli na przykład chcesz zablokować tworzenie plików zawierających metadane ranking, możesz to zrobić w warunku create.
service firebase.storage {
match /b/{bucket}/o {
match /files/{fileName} {
// Disallow
allow create: if !("ranking" in request.resource.metadata)
}
}
}
Użyj istniejących danych w: Firebase Security Rules
Cloud Firestore
Wiele aplikacji przechowuje informacje o kontroli dostępu jako pola w dokumentach w bazie danych. Cloud Firestore Security Rules może dynamicznie zezwalać na dostęp lub go odmawiać na podstawie danych dokumentu:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to read data if the document has the 'visibility'
// field set to 'public'
match /cities/{city} {
allow read: if resource.data.visibility == 'public';
}
}
}
Zmienna resource odnosi się do żądanego dokumentu, a resource.data to mapa wszystkich pól i wartości przechowywanych w dokumencie. Więcej informacji o zmiennej resource znajdziesz w dokumentacji referencyjnej.
Podczas zapisywania danych możesz porównać dane przychodzące z istniejącymi. Dzięki temu możesz na przykład sprawdzić, czy pole nie uległo zmianie, czy wartość pola wzrosła tylko o 1 lub czy nowa wartość jest oddalona o co najmniej tydzień w przyszłość.
W takim przypadku, jeśli Twój zestaw reguł zezwala na oczekujący zapis, zmienna request.resource zawiera przyszły stan dokumentu. W przypadku operacji update, które modyfikują tylko podzbiór pól dokumentu, zmienna request.resource będzie zawierać stan oczekującego dokumentu po operacji. Aby zapobiec niechcianym lub niespójnym aktualizacjom danych, możesz sprawdzić wartości pól w request.resource:
service cloud.firestore {
match /databases/{database}/documents {
// Make sure all cities have a positive population and
// the name is not changed
match /cities/{city} {
allow update: if request.resource.data.population > 0
&& request.resource.data.name == resource.data.name;
}
}
}
Realtime Database
W Realtime Database używaj reguł .validate, aby wymuszać struktury danych oraz sprawdzać format i zawartość danych. Security Rules uruchamia reguły .validate po sprawdzeniu, czy reguła .write przyznaje dostęp.
Reguły .validate nie są kaskadowe. Jeśli jakakolwiek reguła sprawdzania poprawności nie powiedzie się na dowolnej ścieżce lub ścieżce podrzędnej w regule, cała operacja zapisu zostanie odrzucona.
Dodatkowo definicje walidacji sprawdzają tylko wartości inne niż null, a następnie ignorują wszystkie żądania, które usuwają dane.
Weź pod uwagę te reguły .validate:
{
"rules": {
// write is allowed for all paths
".write": true,
"widget": {
// a valid widget must have attributes "color" and "size"
// allows deleting widgets (since .validate is not applied to delete rules)
".validate": "newData.hasChildren(['color', 'size'])",
"size": {
// the value of "size" must be a number between 0 and 99
".validate": "newData.isNumber() &&
newData.val() >= 0 &&
newData.val() <= 99"
},
"color": {
// the value of "color" must exist as a key in our mythical
// /valid_colors/ index
".validate": "root.child('valid_colors/' + newData.val()).exists()"
}
}
}
}
Żądania zapisu do bazy danych z poprzednimi regułami mają następujące wyniki:
JavaScript
var ref = db.ref("/widget"); // PERMISSION_DENIED: does not have children color and size ref.set('foo'); // PERMISSION DENIED: does not have child color ref.set({size: 22}); // PERMISSION_DENIED: size is not a number ref.set({ size: 'foo', color: 'red' }); // SUCCESS (assuming 'blue' appears in our colors list) ref.set({ size: 21, color: 'blue'}); // If the record already exists and has a color, this will // succeed, otherwise it will fail since newData.hasChildren(['color', 'size']) // will fail to validate ref.child('size').set(99);
Objective-C
FIRDatabaseReference *ref = [[[FIRDatabase database] reference] child: @"widget"]; // PERMISSION_DENIED: does not have children color and size [ref setValue: @"foo"]; // PERMISSION DENIED: does not have child color [ref setValue: @{ @"size": @"foo" }]; // PERMISSION_DENIED: size is not a number [ref setValue: @{ @"size": @"foo", @"color": @"red" }]; // SUCCESS (assuming 'blue' appears in our colors list) [ref setValue: @{ @"size": @21, @"color": @"blue" }]; // If the record already exists and has a color, this will // succeed, otherwise it will fail since newData.hasChildren(['color', 'size']) // will fail to validate [[ref child:@"size"] setValue: @99];
Swift
var ref = FIRDatabase.database().reference().child("widget") // PERMISSION_DENIED: does not have children color and size ref.setValue("foo") // PERMISSION DENIED: does not have child color ref.setValue(["size": "foo"]) // PERMISSION_DENIED: size is not a number ref.setValue(["size": "foo", "color": "red"]) // SUCCESS (assuming 'blue' appears in our colors list) ref.setValue(["size": 21, "color": "blue"]) // If the record already exists and has a color, this will // succeed, otherwise it will fail since newData.hasChildren(['color', 'size']) // will fail to validate ref.child("size").setValue(99);
Java
FirebaseDatabase database = FirebaseDatabase.getInstance(); DatabaseReference ref = database.getReference("widget"); // PERMISSION_DENIED: does not have children color and size ref.setValue("foo"); // PERMISSION DENIED: does not have child color ref.child("size").setValue(22); // PERMISSION_DENIED: size is not a number Map<String,Object> map = new HashMap<String, Object>(); map.put("size","foo"); map.put("color","red"); ref.setValue(map); // SUCCESS (assuming 'blue' appears in our colors list) map = new HashMap<String, Object>(); map.put("size", 21); map.put("color","blue"); ref.setValue(map); // If the record already exists and has a color, this will // succeed, otherwise it will fail since newData.hasChildren(['color', 'size']) // will fail to validate ref.child("size").setValue(99);
REST
# PERMISSION_DENIED: does not have children color and size
curl -X PUT -d 'foo' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json
# PERMISSION DENIED: does not have child color
curl -X PUT -d '{"size": 22}' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json
# PERMISSION_DENIED: size is not a number
curl -X PUT -d '{"size": "foo", "color": "red"}' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json
# SUCCESS (assuming 'blue' appears in our colors list)
curl -X PUT -d '{"size": 21, "color": "blue"}' \
https://docs-examples.firebaseio.com/rest/securing-data/example.json
# If the record already exists and has a color, this will
# succeed, otherwise it will fail since newData.hasChildren(['color', 'size'])
# will fail to validate
curl -X PUT -d '99' \
https://docs-examples.firebaseio.com/rest/securing-data/example/size.jsonCloud Storage
Podczas oceniania 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 zaawansowane reguły, które pozwalają na przykład na przesyłanie tylko plików o określonych typach treści lub usuwanie tylko plików o określonym rozmiarze.
Obiekt resource zawiera pary klucz-wartość z metadanymi pliku wyświetlanymi w obiekcie Cloud Storage. Te właściwości można sprawdzić w żądaniach read lub write, aby zapewnić integralność danych. Obiekt resource sprawdza metadane istniejących plików w zasobniku Cloud Storage.
service firebase.storage {
match /b/{bucket}/o {
match /images {
match /{fileName} {
// Allow reads if a custom 'visibility' field is set to 'public'
allow read: if resource.metadata.visibility == 'public';
}
}
}
}
Możesz też użyć obiektu request.resource w żądaniach write (takich jak przesyłanie, aktualizowanie metadanych i usuwanie). Obiekt request.resource pobiera metadane z pliku, który zostanie zapisany, jeśli write jest dozwolony.
Możesz użyć tych 2 wartości, aby zapobiec niechcianym lub niespójnym aktualizacjom albo wymusić ograniczenia aplikacji, takie jak typ lub rozmiar pliku.
service firebase.storage {
match /b/{bucket}/o {
match /images {
// 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) Filename (stored in imageId wildcard variable) is less than 32 characters
match /{imageId} {
allow read;
allow write: if request.resource.size < 5 * 1024 * 1024
&& request.resource.contentType.matches('image/.*')
&& request.resource.contentType == resource.contentType
&& imageId.size() < 32
}
}
}
}
Pełną listę właściwości obiektu resource znajdziesz w dokumentacji.