← Vissza a cikkekhez
technologytutorial

Security Rules — az utolsó vonal

Zsaga
#featured#firebase#security-rules#firestore#authentication#authorization#custom-claims#multi-tenancy#testing#emulator
Firebase Security Rules — kliens kérés a szabálymotoron át allow vagy PERMISSION_DENIED kimenetelig
A Security Rules három kérdésre felel: ki vagy, mit kérsz, és milyen formában
Mit tanulsz
  • security-rulesBevezető

01 — Az architektúrában

A Rules helye — egyedüli vonal a kliens előtt

A klasszikus webalkalmazásban a kliens egy backend API-val kommunikál, és ott van a jogosultságkezelés. Firebase-ben a kliens közvetlenül a Firestore-ral beszél — nincs köztük réteg. A Security Rules tehát nem egy „extra védelem" valami más mellett, hanem maga az összes védelem.
Ez egy olyan gondolati ugrás, amit sokan nem tesznek meg azonnal. A megszokás az, hogy a kliens kódjára azt mondjuk: „úgyis ellenőrzöm backenden". Firebase-ben ez nincs — ami a kliensben van, az közvetlenül megy a Firestore-ra. Ha a kliensben azt írod, hogy updateDoc(orderRef, { status: 'paid' }), akkor pontosan ez a kérés érkezik a szerverhez. Ha a Rules nem mondja meg, hogy ezt kinek szabad, akkor bárki, aki ki tudja olvasni a kliens-konfigurációdat, bárki helyett bármit írhat.

Mit lát a Firestore minden kérésnél?

A Firestore minden kérésnél két dolgot kap a klienstől:
  1. A kérés tartalmát — milyen kollekció, milyen dokumentum, milyen művelet (read/create/update/delete), és írásnál milyen mezők.
  2. Egy auth tokent — egy JWT-t, amit a Firebase Auth bocsátott ki, és ami tartalmazza a felhasználó UID-jét, custom claimjeit, és a Firebase szerver kulcsa aláírja.
A Rules ezt a két dolgot vizsgálja meg, és eldönti: allow vagy deny. Nincs lehetőség arra, hogy a Rules visszaszóljon a kliensnek hibakóddal, hogy pl. „nem volt elég jogosultságod" vs. „a mező típusa rossz" — minden hiba ugyanaz: permission-denied. Ezt érdemes észben tartani: a Rules nem üzleti logika, csak hozzáférés-szabályozás.
Fontos
A Firebase Admin SDK (szerveroldali kód) kihagyja a Security Rules-t. A Cloud Function-ben futó admin.firestore() hívások mindig minden joggal mennek át. Ez egyszerre jó (kell, hogy a backend funkciók működjenek) és kockázatos (egy rosszul írt Cloud Function megkerülheti a Rules-t). Ezért a fontos validációkat a Cloud Function-ben is meg kell csinálni.
Mit tanulsz
  • security-rulesBevezető

02 — A nyelv

A szabálynyelv alapjai

A Rules egy saját, deklaratív DSL — Common Expression Language alapú, JavaScript-szerű szintaxissal. A felépítés mindig ugyanaz: szolgáltatás, match path-ek, és allow utasítások.
firestore.rulesplaintext
rules_version = '2';                       // always 2 on new projects

service cloud.firestore {                  // which service
  match /databases/{database}/documents {  // root

    match /posts/{postId} {                // collection + doc
      allow read:   if true;               // anyone can read
      allow create: if request.auth != null;
      allow update: if request.auth.uid == resource.data.authorId;
      allow delete: if request.auth.token.role == 'admin';
    }
  }
}

A négy alap-művelet és a két csoport

A Rules-ban négy alap-művelet van, és kettő összevont csoport, amik kombinálják őket:
MűveletMit takar
getEgyetlen dokumentum lekérése (single doc fetch)
listLekérdezés egy kollekcióra (több doc)
createÚj dokumentum létrehozása
updateMeglévő dokumentum módosítása
deleteDokumentum törlése
readget + list együtt
writecreate + update + delete együtt
A get és list különválasztása fontos: lehet, hogy egy dokumentumot csak akkor szabad olvasni, ha valaki konkrétan kéri az ID-jén keresztül, de listázni nem szabad. Pl. egy felhasználói profil: ha tudod a userId-t, akkor láthatod, de listázni az összeset nem szabad.
Tipp
A list szabály a teljes listára vonatkozik egyben. Ha a kliens egy where('public', '==', true) lekérdezést indít, és a Rules csak akkor enged listázást, ha minden dokumentum publikus, akkor a Firestore először megnézi, hogy az egész kollekció ezt teljesíti-e. Általában nem teljesíti. A megoldás: a Rules-ban is le kell írni ugyanazt a szűrést — a Rules ellenőrzi a query-t, és csak akkor engedi át, ha a query maga is csak publikus dokumentumokra szűkít.
Mit tanulsz
  • security-rulesKözéphaladó

03 — Path-ek

Match path patterns

A Rules-ban a path nem csak egy szöveg, hanem egy mintázat — wildcardokkal, többszintű egyezésekkel, és az adatszerkezetből származó változókkal. Ez a szabályrendszer legerősebb eszköze.

Egy szegmensű wildcard

match-singleplaintext
match /users/{uid} {
  allow read, write: if request.auth.uid == uid;
}
A {uid} egy változó: ide bármilyen érték illeszkedik, és ezt belülről változóként használhatod. Az uid név önkényes — bármi lehetne —, de érdemes beszédes nevet adni, mert hat hónap múlva, amikor a saját kódodat olvasod, ez számít.

Többszintű wildcard

match-multiplaintext
match /tenants/{tid}/orders/{oid} {
  allow read: if request.auth.token.tenantId == tid;
}
A subcollection-ig lemenő path. Mindkét szegmens változó, és mindkettőre lehet hivatkozni.

Recursive wildcard

match-recursiveplaintext
match /tenants/{tid}/{document=**} {
  allow read: if request.auth.token.tenantId == tid;
}
A {document=**} minden mélységű subdocumentumra illik — a tenant alatti összes adatra. Nagyon kényelmes, de óvatosan kell vele bánni: ha valamelyik subcollection kivételes szabályt igényel, akkor azt külön match-csel felül kell írni.

Több match egymásba ágyazva

match-nestedplaintext
match /tenants/{tid} {
  // Only members can read the tenant doc
  allow read: if isMember(tid);

  match /orders/{oid} {
    allow read: if isMember(tid);
    allow write: if isAdmin(tid);
  }

  match /products/{pid} {
    allow read: if isMember(tid);
    allow write: if isAdmin(tid);
  }
}
A belső match magától örökli a külső path változóit (tid), és ezt használhatod a függvényhívásban. Ez a struktúra jól tükrözi az adatmodell hierarchiáját.
Megjegyzés
A több allow utasítás OR-rel van összekapcsolva: ha bármelyik igaz, a kérés engedélyezett. Tehát ha azt akarod, hogy egy művelet csak akkor legyen engedélyezett, ha több feltétel együtt teljesül, akkor azt egyetlen allow-ban kell &&-vel összekötni.
Mit tanulsz
  • security-rulesKözéphaladó

04 — Az objektumok

Request és resource — kettő, nem egy

A Rules-ban két objektum hordozza az információt: a request a beérkező kérésről, a resource az adatbázisban már meglévő dokumentumról. A kettő összekeverése a leggyakoribb szabály-bug forrása.
MezőMit jelent
request.authA kérést küldő felhasználó (uid, token, claims). null, ha nincs bejelentkezve.
request.auth.uidA felhasználó UID-je
request.auth.tokenA teljes JWT — beleértve a custom claimeket
request.resource.dataAz új érték írásnál — amit a kliens küld
request.methodget, list, create, update, delete
request.timeA kérés érkezésének időpontja a szerveren
resource.dataA jelenlegi érték az adatbázisban — frissítés vagy törlés előtt

Az írás művelet különbsége

A leggyakoribb hiba: create-nél nincs resource, mert a dokumentum még nem létezik. update-nél van resource (a régi érték) és request.resource (az új érték). delete-nél csak resource van.
resource-vs-requestplaintext
match /orders/{oid} {
  // CREATE — no resource yet, only request.resource
  allow create: if request.auth != null
             && request.resource.data.userId == request.auth.uid
             && request.resource.data.status == 'pending';

  // UPDATE — both resource (old) and request.resource (new)
  allow update: if resource.data.userId == request.auth.uid                 // owner only
             && request.resource.data.userId == resource.data.userId;       // userId must not change

  // DELETE — only resource is present
  allow delete: if resource.data.userId == request.auth.uid;
}
A 9. sor egy nagyon fontos minta: változatlanság ellenőrzése. Akkor is ellenőrizzük, hogy a userId nem változott-e, ha a kliensnek elvileg nem lenne miért átírni — mert nem bízhatunk abban, hogy a kliens nem teszi meg.
Mit tanulsz
  • custom-claimsKözéphaladó

05 — Authentication

Authentication és custom claims

A felhasználó identitása a JWT-ben utazik, és minden Rules-ban hozzáférhető. A Firebase Auth alapból ad neked egy uid-t és néhány standard mezőt — és lehetőséget arra, hogy szerveroldalról saját mezőket írj a tokenbe.

Az alap auth-ellenőrzés

basic-authplaintext
// Anyone signed in
allow read: if request.auth != null;

// Only this specific user
allow read: if request.auth.uid == resource.data.ownerId;

// Only verified-email users
allow read: if request.auth.token.email_verified == true;

Custom claims a Rules-ban

A custom claims-eket szerveroldalon állítod (Firebase Admin SDK-ból, lásd az Authentication szekciót az átfogó cikkben), és a Rules-ban a request.auth.token alatt találod őket:
custom-claims-rulesplaintext
match /admin/{document=**} {
  allow read, write: if request.auth.token.role == 'admin';
}

match /tenants/{tid}/{document=**} {
  allow read, write: if request.auth.token.tenantId == tid
                  && request.auth.token.role in ['admin', 'member'];
}
Token frissítés
Custom claims változás után a felhasználónak új tokent kell kérnie, hogy az új claimek életbe lépjenek a Rules-ban. Kliens oldalon: await user.getIdToken(true) erőlteti a frissítést. Egyébként az új claim csak a következő automatikus token-frissítéskor (~1 órán belül) lesz látható.
Mit tanulsz
  • validationKözéphaladó

06 — Validáció

Adatvalidáció — típus, érték, alak

A Rules nem csak hozzáférést szabályoz, hanem ellenőrzi az adat formáját is. Ez fontos: ha valaki egyéni klienst használ (pl. egy szkriptet), akkor az nem garantálja, hogy a TypeScript típusok teljesülnek. A Rules itt is az utolsó vonal.

Típusellenőrzés

type-checkplaintext
// The field exists and is a string
request.resource.data.title is string

// The field is a number between 0 and 1000
request.resource.data.price is number
&& request.resource.data.price >= 0
&& request.resource.data.price <= 1000

// The field exists at all
request.resource.data.keys().hasAll(['title', 'price'])

// Only these fields may be present (no extras)
request.resource.data.keys().hasOnly(['title', 'price', 'authorId'])

Hossz és minta ellenőrzés

size-and-patternplaintext
// Title between 5 and 200 characters
request.resource.data.title.size() >= 5
&& request.resource.data.title.size() <= 200

// Email regex
request.resource.data.email.matches('^[^@]+@[^@]+\\.[^@]+$')

// Slug format
request.resource.data.slug.matches('^[a-z0-9]+(-[a-z0-9]+)*$')

Változatlan mezők (immutable)

Egy nagyon hasznos minta: bizonyos mezők létrehozáskor beállíthatók, de utána sosem módosíthatók. Pl. a createdAt, userId, tenantId:
immutable-fieldsplaintext
match /orders/{oid} {
  allow update: if request.auth != null
             && request.resource.data.userId == resource.data.userId
             && request.resource.data.createdAt == resource.data.createdAt
             && request.resource.data.tenantId == resource.data.tenantId;
}
Vagy egy elegánsabb forma a diff() függvénnyel — megnézi, mely mezők változtak meg:
immutable-via-diffplaintext
// Only the 'status' and 'updatedAt' fields may change
allow update: if request.resource.data.diff(resource.data)
                .affectedKeys()
                .hasOnly(['status', 'updatedAt']);
Mit tanulsz
  • security-rulesHaladó

07 — Cross-document

Cross-document lookup — get és exists

A Rules-ban néha más dokumentumok adatait is meg kell vizsgálni a döntéshez. Pl. „a felhasználó akkor írhat egy tenantba, ha tagja annak". Erre van a get() és az exists() — de van ára.
cross-docplaintext
match /tenants/{tid}/orders/{oid} {
  // Only if the user is a member of the tenant (member doc exists)
  allow read: if exists(/databases/$(database)/documents/tenants/$(tid)/members/$(request.auth.uid));

  // Only if the member is in the admin role
  allow write: if get(/databases/$(database)/documents/tenants/$(tid)/members/$(request.auth.uid))
                .data.role == 'admin';
}

A költség

Minden get() hívás egy plusz olvasásnak számít a számlán. list műveletnél ez minden visszaadott dokumentumra alkalmazódik. Ha tehát egy listában 100 dokumentum van, és a Rules minden dokumentumhoz egy get()-tel ellenőriz valamit, akkor egy „100 doc listázás" valójában 200 olvasás.
Költség-csökkentés
Custom claims-szel sok esetben elkerülhető a get(). Ha a tenant-tagság stabilan ritkán változik, akkor a tenantId-t és a role-t tedd a JWT-be — ezt a Rules ingyen olvassa, mert az auth tokenben utazik. Cross-doc lookup-ra csak akkor van szükség, ha a döntés tényleg dinamikusan változó adatra épül.

Cache-elés egy szabályon belül

A Firestore tudja optimalizálni: ha ugyanabban a szabály-kiértékelésben többször hivatkozol ugyanarra a path-ra, akkor csak egy olvasás történik. Ezért érdemes a lookup-ot function-ben elnevezni, hogy ne ismételd — és a kiértékelés csak egyszer történjen meg.
Mit tanulsz
  • security-rulesHaladó

08 — Function-ök

Function-ök — kompozíció és olvashatóság

A Rules-ban definiálhatsz saját függvényeket, amik a kódot olvashatóbbá és újrafelhasználhatóvá teszik. Egy 200 soros Rules fájl, amiben minden szabály ugyanazt a 3 ellenőrzést duplikálja, már megérett a refaktorra.
firestore.rules — refactoredplaintext
rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {

    // --- Helper functions ---
    function isSignedIn() {
      return request.auth != null;
    }

    function isOwner(userId) {
      return isSignedIn() && request.auth.uid == userId;
    }

    function hasRole(role) {
      return isSignedIn() && request.auth.token.role == role;
    }

    function isMember(tid) {
      return isSignedIn() && request.auth.token.tenantId == tid;
    }

    function unchanged(field) {
      return request.resource.data[field] == resource.data[field];
    }

    // --- Rules ---
    match /tenants/{tid}/orders/{oid} {
      allow read:   if isMember(tid);
      allow create: if isMember(tid)
                 && request.resource.data.userId == request.auth.uid;
      allow update: if isMember(tid)
                 && unchanged('userId')
                 && unchanged('createdAt');
      allow delete: if hasRole('admin');
    }
  }
}
A függvények paramétereket vehetnek (mint az isOwner(userId)) és más függvényeket hívhatnak — így rétegezhetőek a szabályok.
Korlátok
A függvények csak return utasítást tartalmazhatnak, és nem hívhatják önmagukat (nincs rekurzió). Maximum 10 függvényhívás engedélyezett egy szabály-kiértékelésben — ha bonyolultabb logika kell, az már Cloud Function-be való.
Mit tanulsz
  • testingKözéphaladó
  • emulatorKözéphaladó

09 — Tesztelés

Tesztelés emulátorral

A Security Rules pont olyan kód, mint bármi más — tesztelni kell. Az emulátor a Firebase CLI része, helyben futtatható ingyen, és Jest-tel kombinálva ugyanúgy lehet TDD módra dolgozni vele, mint bármilyen üzleti logikán.

A test setup

orders.rules.test.tstypescript
import { initializeTestEnvironment, assertSucceeds, assertFails } from '@firebase/rules-unit-testing';
import { setDoc, doc, getDoc } from 'firebase/firestore';
import fs from 'node:fs';

let testEnv: Awaited<ReturnType<typeof initializeTestEnvironment>>;

beforeAll(async () => {
  testEnv = await initializeTestEnvironment({
    projectId: 'demo-project',
    firestore: { rules: fs.readFileSync('firestore.rules', 'utf8') },
  });
});

afterAll(() => testEnv.cleanup());
beforeEach(() => testEnv.clearFirestore());

Egy konkrét teszt

orders.rules.test.ts (continued)typescript
describe('orders/{oid}', () => {
  it('only the owner can read', async () => {
    // Seed: order belonging to usr_alice
    await testEnv.withSecurityRulesDisabled(async (ctx) => {
      await setDoc(doc(ctx.firestore(), 'orders/ord_001'), {
        userId: 'usr_alice', total: 12990,
      });
    });

    // Alice can read
    const alice = testEnv.authenticatedContext('usr_alice').firestore();
    await assertSucceeds(getDoc(doc(alice, 'orders/ord_001')));

    // Bob cannot
    const bob = testEnv.authenticatedContext('usr_bob').firestore();
    await assertFails(getDoc(doc(bob, 'orders/ord_001')));

    // Anonymous cannot
    const guest = testEnv.unauthenticatedContext().firestore();
    await assertFails(getDoc(doc(guest, 'orders/ord_001')));
  });
});
A withSecurityRulesDisabled a kezdeti adatok feltöltésére jó — a teszt környezetbe gyorsan és Rules nélkül beíródik a kezdeti állapot. Aztán a tényleges állítások a Rules-ON kontextusban futnak.
Tipp
Minden új match blokkhoz írj legalább 3 tesztet: jó eset (jogos kérés, succeeds), jogosulatlan (rossz user, fails), és nem hitelesített (nincs bejelentkezve, fails). Ha van változatlan-mező-ellenőrzés, akkor egy negyedik teszt is kell: manipuláció (a tulajdonos módosítja az immutable mezőt, fails).
Mit tanulsz
  • security-rulesHaladó

10 — Pattern könyvtár

Hat visszatérő mintázat

A legtöbb projektben ugyanazok a hozzáférési minták ismétlődnek. Itt összegyűjtöttem a hatot, ami szinte minden Firebase projektben felbukkan — érdemes ezeket egyszer megírni egy közös helper-fájlban, és újrahasznosítani.
Pattern 1

Owner-only access

Mikor: a dokumentumot csak a létrehozója (vagy egy konkrét user) láthatja és módosíthatja.

A standard megoldás: a dokumentumon van egy userId vagy ownerId mező, és ezt az auth uid-vel egyeztetjük.

owner-onlyplaintext
match /notes/{noteId} {
  allow read, update, delete: if isOwner(resource.data.userId);
  allow create: if isOwner(request.resource.data.userId);
}
Pattern 2

Role-based access

Mikor: különböző szerepkörök (admin, editor, viewer) eltérő jogokat kapnak.

A szerepkör custom claim-ként él a JWT-ben, így a Rules ingyen olvassa.

role-basedplaintext
match /articles/{articleId} {
  allow read:   if true;                       // public
  allow create: if hasRole('editor') || hasRole('admin');
  allow update: if hasRole('editor') || hasRole('admin');
  allow delete: if hasRole('admin');
}
Pattern 3

Tenant isolation

Mikor: multi-tenant SaaS, ahol minden tenant adatát szigorúan el kell szigetelni a többitől.

A tenantId a JWT-ben él, és a path is tartalmazza — kettős védelem.

tenant-isolationplaintext
match /tenants/{tid}/{document=**} {
  allow read:  if isMember(tid);
  allow write: if isMember(tid);
}

// Tenant-bound member list needs its own rule
match /tenants/{tid}/members/{uid} {
  allow read:  if isMember(tid);
  allow write: if isMember(tid) && hasRole('admin');
}
Pattern 4

Soft delete

Mikor: a dokumentumokat nem fizikailag törlöd, csak megjelölöd deletedAt mezővel — és csak a nem törölt elemeket szabad olvasni.

soft-deleteplaintext
match /posts/{postId} {
  allow read: if resource.data.deletedAt == null
           || hasRole('admin');    // admin sees everything
}
Pattern 5

Immutable createdAt + updatedAt

Mikor: a createdAt sosem változhat, az updatedAt mindig a szerveridőre kell álljon.

timestampsplaintext
match /items/{itemId} {
  allow create: if request.resource.data.createdAt == request.time
             && request.resource.data.updatedAt == request.time;

  allow update: if unchanged('createdAt')
             && request.resource.data.updatedAt == request.time;
}
Pattern 6

Public-read, owner-write

Mikor: egy publikus profil — bárki láthatja, de csak a tulajdonos szerkesztheti.

public-readplaintext
match /profiles/{uid} {
  allow read:  if true;
  allow write: if isOwner(uid);
}
Mit tanulsz
  • security-rulesHaladó

11 — Anti-pattern-ek

Hat klasszikus hiba

A Rules-ban viszonylag könnyű olyan kódot írni, ami a fejlesztés alatt működik, de később kiderül, hogy biztonsági lyuk. Itt vannak a leggyakoribb buktatók.

1) A „nyitott" Rules — élesben

anti-1plaintext
match /{document=**} {
  allow read, write: if true;     // EVERYTHING is open!
}
A Firebase Console rendszeresen küld figyelmeztetést, ha ilyet talál — vegyük komolyan. A „test mode" projektben az első 30 nap után magától is bezárul.

2) A request.resource és resource keverése

anti-2plaintext
// WRONG: on update this checks the old userId, but the client may send a new one
allow update: if resource.data.userId == request.auth.uid;

// RIGHT: check that the old userId matches AND the new one didn't change
allow update: if resource.data.userId == request.auth.uid
           && unchanged('userId');

3) A list szabály elfelejtése

Sokan csak get/create/update/delete szabályt írnak, és a list kimarad — pedig a read a get + list. Ha csak get-et engedélyezel, akkor a kliens nem fog tudni listázni, ami nem feltétlenül baj — de tudd, hogy így csinálod.

4) Cross-doc lookup, ami túl gyakran fut

anti-4plaintext
// Every read = +1 read — a 100-doc list means +100 reads!
allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid))
             .data.subscription == 'pro';

// RIGHT: put subscription into a custom claim — Rules read it for free
allow read: if request.auth.token.subscription == 'pro';

5) Túlságosan bonyolult feltételek

Ha egy allow sora 10 sor hosszú, akkor ott valószínűleg üzleti logika van, ami nem ide való. A túl bonyolult ellenőrzések a Cloud Function-ben élnek, amit a kliens hív, és ami az Admin SDK-val ír — a Rules csak az általános „ki és milyen formában" kérdésre válaszol, az „ezt a tranzakciót szabad-e most" kérdés a backend dolga.

6) Elhanyagolt Rules-tesztelés

Ha a Rules nincs tesztelve, nem tudod, mit véd és mit nem. Egy Rules-változás véletlenül megnyithat egy kollekciót, és senki nem veszi észre, amíg valaki ki nem szivárogtat valamit. A 9. szekció szerinti emulátoros teszteknek a CI-ben kötelező futnia, mint bármilyen másik unit tesztnek.

A Security Rules nem akkor jó, ha működik a fejlesztés alatt. Akkor jó, ha tesztelve, dokumentálva és időnként újragondolva van.

Mit tanulsz
  • security-rulesHaladó

12 — Konklúzió

Mi marad a Rules-ban — és mi nem?

A Security Rules egy szűk, célzott eszköz: hozzáférés-szabályozás és alapvető adatvalidáció. Ami nem fér bele, az Cloud Function-be megy. A jó Rules-fájl rövid, átlátható, és ezt a határt tiszteletben tartja.

Amit a Rules-ba érdemes tenni

  • Ki olvashatja és írhatja a dokumentumot (auth check, role check, owner check).
  • Az írandó adat alapvető formája (típus, hossz, regex, enum értékek).
  • Változatlan mezők védelme (createdAt, userId, tenantId).
  • Tenant- és user-szigetelés (path alapján és claim alapján).
  • Soft-delete állapot ellenőrzés.

Amit a Rules-ba ne tegyél

  • Bonyolult üzleti validáció (pl. „a rendelés értéke a hitelkereten belül van"). Ez Cloud Function.
  • Külső API hívás. Nem lehetséges, és nem is illik bele.
  • Tranzakciós, több dokumentumot átfogó feltételek (pl. „akkor lehet törölni, ha a kapcsolódó subcollection üres" — ezt egyszerűbb és biztonságosabb backenden ellenőrizni).
  • Audit log, történeti rekordok írása. Ez Cloud Function trigger.
  • Fizetés-ellenőrzés, kvóta-számolás. Ez backend.

A jó Rules-fájl ismérvei

Egy jól megírt Rules-fájl maximum 200-300 sor, helper függvényekkel a tetején, alatta a path-ok hierarchikusan rendezve. Minden szabályhoz tartozik 3-4 emulátoros teszt. A CI minden push-on lefuttatja a teszteket. Élesben az App Check is be van kapcsolva, ami megfogja azokat a kéréseket, amik nem az eredeti appból érkeznek.

A következő cikkben a Cloud Functions architektúrákat vesszük mélységbe: hogyan írj olyan szerveroldali kódot, ami a Rules-on túl is megfogja a hibás kéréseket, és nem fut bele a klasszikus serverless csapdákba.
Vissza az elejére