Walidacja danych

Możesz używać Firebase Security Rules do warunkowego zapisywania nowych danych na podstawie istniejących danych w bazie danych lub zasobniku pamięci. Możesz też pisać reguły, które wymuszają weryfikację danych, ograniczając zapisywanie na podstawie nowych zapisywanych danych. Czytaj dalej, aby dowiedzieć się więcej o regułach, które wykorzystują istniejące dane do tworzenia warunków bezpieczeństwa.

Wybierz produkt w każdej sekcji, aby dowiedzieć się więcej o regułach sprawdzania poprawności danych.

Aby uzyskać pomoc AI, skopiuj poniższy prompt do agenta kodowania AI (np. Gemini w Android Studio, Antigravity, Claude Code, Codex i Cursor). Możesz dostosować prompta i współpracować 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 zabronić tworzenia dokumentów zawierających pole ranking, musisz to zrobić 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 zablokuj zapisywanie. Jeśli na przykład chcesz odrzucić wszystkie zapisy zawierające wartości ranking, musisz zabronić zapisywania 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 zabronić tworzenia plików zawierających metadane ranking, musisz 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żywanie 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.

Podczas zapisywania danych możesz chcieć porównać dane przychodzące z danymi już istniejącymi. Dzięki temu możesz na przykład sprawdzić, czy pole nie zostało zmienione, czy zwiększyło się tylko o 1 lub czy nowa wartość jest co najmniej o tydzień późniejsza. W takim przypadku, jeśli 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 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 .validate reguł, aby wymuszać struktury danych i weryfikować format oraz zawartość danych. Security Rules uruchamiaj .validate reguły po sprawdzeniu, czy .write reguła przyznaje dostęp.

Reguły .validate nie są kaskadowe. Jeśli w przypadku dowolnej ścieżki lub podścieżki w regule nie powiedzie się żadna reguła weryfikacji, cała operacja zapisu zostanie odrzucona. Dodatkowo definicje weryfikacji sprawdzają tylko wartości inne niż null, a następnie ignorują wszystkie żądania usuwania danych.

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 w bazie danych z powyższymi regułami dałyby te 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
Uwaga: ta usługa Firebase nie jest dostępna w przypadku klipów z aplikacji.
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
Uwaga: ta usługa Firebase nie jest dostępna w przypadku klipów z aplikacji.
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.json

Cloud Storage

Podczas oceny reguł możesz też oceniać metadane pliku przesyłanego, pobieranego, modyfikowanego lub usuwanego. Dzięki temu możesz tworzyć złożone i zaawansowane reguły, które np. zezwalają 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, które są wyświetlane 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 w istniejących plikach 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żywać obiektu request.resource w przypadku żądań 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.