iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Security Rules

Security rules enforce who can read / write what — per collection, per document, per field. Without them, anyone with your project ID can hammer your DB. With them, you have row-level security for free.

Real Firestore + Storage rules

EXAMPLE
// firestore.rules — Cloud Firestore
rules_version = '2';
service cloud.firestore {
    match /databases/{database}/documents {

        // Helper functions
        function isSignedIn()         { return request.auth != null; }
        function isSelf(uid)          { return isSignedIn() && request.auth.uid == uid; }
        function hasRole(role) {
            return isSignedIn() && request.auth.token.role == role;
        }

        // Profile: a user can read everyone's; only owners can write their own.
        match /users/{uid} {
            allow read: if isSignedIn();
            allow write: if isSelf(uid)
                && request.resource.data.email == resource.data.email   // can't change email this way
                && request.resource.data.role  == resource.data.role;
        }

        // Posts: public read; only the author can update/delete.
        match /posts/{postId} {
            allow read:   if true;
            allow create: if isSignedIn() &&
                request.resource.data.authorId == request.auth.uid &&
                request.resource.data.title is string &&
                request.resource.data.title.size() <= 120;
            allow update, delete: if isSignedIn() &&
                resource.data.authorId == request.auth.uid;
        }

        // Admin-only collection
        match /admin/{document=**} {
            allow read, write: if hasRole('admin');
        }

        // Default DENY — match the rest, reject
        match /{document=**} {
            allow read, write: if false;
        }
    }
}

// storage.rules — Cloud Storage
rules_version = '2';
service firebase.storage {
    match /b/{bucket}/o {
        // Per-user uploads — only owner can write; world can read
        match /uploads/{uid}/{file=**} {
            allow read:  if true;
            allow write: if request.auth != null && request.auth.uid == uid &&
                request.resource.size < 5 * 1024 * 1024 &&
                request.resource.contentType.matches('image/.*');
        }
    }
}

Why it matters

Always end with allow read, write: if false;. Without it, ANY new collection you add later defaults to open — rules are deny-only matchers, not allow-only.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
rules_version = '2';
service cloud.firestore {
    match /databases/{db}/documents {
        match /posts/{id} {
            allow read: if true;
            allow write: if request.auth != null
                && request.auth.uid == resource.data.authorId;
        }
    }
}
Try it Yourself »

Exercise

Reference the auth context in rules.

allow read: if request. != null;

Test yourself

Q1. Security rules run…
Q2. You always have access to the auth token via…
Q3. Default rules in production should be…

Discussion

Loading…