Skip to content

Firebase Security Rules & Hosting Guide: Protect Data & Deploy Apps

DodaTech Updated Jun 6, 2026 7 min read

Firebase Security Rules are a declarative access control language running on Firebase servers that determines who can read or write data before any operation.

What You’ll Learn

  • Firestore Security Rules syntax and structure
  • Authentication-based access control patterns
  • Data validation and role-based permissions
  • Firebase Hosting setup, custom domains, and CDN
  • Hosting with Cloud Functions for dynamic content

Why Security Rules and Hosting Matter

Without Security Rules, anyone who knows your Firebase project ID can read or write any data. Rules are your only defense against unauthorized access. And Firebase Hosting with its global CDN ensures your app loads fast everywhere. DodaTech’s Durga Antivirus Pro uses Security Rules to ensure users can only read their own device data and threat reports — even if someone guesses another user’s device ID, the rules block the access.

    flowchart LR
    A["Client Request"] -->|"Request Auth + Path"| B["Security Rules\n(Server-side)"]
    B -->|"allow"| C["Firestore/\nStorage"]
    B -->|"deny"| D["Error:\nPermission Denied"]
    C --> E["Firebase Hosting\n(Global CDN)"]
    style A fill:#dbeafe,stroke:#2563eb
    style B fill:#fef3c7,stroke:#d97706
    style C fill:#dcfce7,stroke:#16a34a
    style D fill:#fce7f3,stroke:#ec4899
    style E fill:#fef3c7,stroke:#d97706
  
Prerequisites: Understanding of Firebase Database and Firebase Authentication concepts.

Firestore Security Rules

Rules are written in a Firebase-specific language and evaluate every read/write request before it reaches the database.

Basic Structure

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // All documents — deny by default
    match /{document=**} {
      allow read, write: if false;
    }
    
    // Devices collection
    match /devices/{deviceId} {
      allow read, write: if request.auth != null 
        && request.auth.uid == resource.data.userId;
    }
  }
}

Rule Components

  • match — selects which documents the rule applies to
  • allow — grants permission: read, write, create, update, delete
  • if — condition that must be true for access
  • request — the incoming request (auth, path, resource data)
  • resource — the existing document data (for updates)

Authentication-Based Access

// Only authenticated users can read/write their own documents
match /users/{userId} {
  allow read, write: if request.auth != null 
    && request.auth.uid == userId;
}

You might be wondering: “Can the client see request.auth.uid?” No — request.auth is injected by Firebase server-side based on the ID token. The client cannot fake it.

Data Validation Rules

Rules can validate incoming data:

match /devices/{deviceId} {
  allow create: if request.auth != null 
    && request.auth.uid == request.resource.data.userId
    && request.resource.data.name is string
    && request.resource.data.name.size() > 0
    && request.resource.data.name.size() <= 100
    && request.resource.data.os in ['Windows', 'macOS', 'Linux', 'Android', 'iOS'];
  
  allow read: if request.auth != null 
    && request.auth.uid == resource.data.userId;
}

Role-Based Access

match /threats/{threatId} {
  // Analysts can read all threats
  allow read: if request.auth != null 
    && get(/databases/(default)/documents/users/${request.auth.uid}).data.role == 'analyst';
  
  // Only admins can delete threats
  allow delete: if request.auth != null 
    && get(/databases/(default)/documents/users/${request.auth.uid}).data.role == 'admin';
}

Performance note: Each get() call counts as a document read, even if the rule denies access. Use sparingly.

Firebase Hosting

Deploying a Static Site

# Install Firebase CLI
npm install -g firebase-tools

# Initialize hosting
firebase init hosting

# Configure:
# - Public directory: dist (or build, public)
# - Single-page app: Yes (for React/Vue)
# - Auto-build: No

# Deploy
firebase deploy --only hosting

Your site is live at https://your-project.web.app within seconds.

Custom Domain

  1. In Firebase Console: Hosting > Add custom domain
  2. Enter your domain (e.g., dashboard.durga-antivirus.com)
  3. Add the provided DNS records (A and TXT) to your DNS provider
  4. Firebase provisions an SSL certificate via Let’s Encrypt — automatic HTTPS
# Verify domain ownership
firebase hosting:channel:deploy preview --expires 7d
# Preview at: https://preview-durga-antivirus-abc123.web.app

Hosting with Cloud Functions

For server-side rendering or API endpoints alongside your static site:

firebase init functions
// functions/index.js
const functions = require('firebase-functions');
const express = require('express');
const app = express();

app.get('/api/status', (req, res) => {
  res.json({ status: 'ok', uptime: process.uptime() });
});

exports.api = functions.https.onRequest(app);
# firebase.json — rewrite to Cloud Functions
{
  "hosting": {
    "rewrites": [
      { "source": "/api/**", "function": "api" },
      { "source": "**", "destination": "/index.html" }
    ]
  }
}

Common Mistakes

1. Using if true; in Production

Default development rules (allow read, write: if true;) give everyone full access. Always replace with auth-checking rules before deploying.

2. Overusing get() in Rules

Each get() call costs a document read. Using get() in rules that execute on every request can increase Firestore bills significantly. Consider using custom claims instead.

3. Not Testing Rules

Rules that compile don’t always behave as expected. Use the Rules Playground in the Firebase Console to simulate requests before deploying.

4. Deploying Without a Hosting Preview

firebase deploy pushes to production immediately. Use firebase hosting:channel:deploy preview for a preview URL first.

5. Ignoring App Check

Security Rules check auth, but they don’t verify the request comes from your app. App Check verifies requests originate from your iOS, Android, or web app, blocking abuse from API callers.

Practice Questions

  1. What does request.auth.uid contain and who sets it?
  2. How do you restrict a user to only read their own data?
  3. What is the purpose of resource vs request.resource in rules?
  4. How does Firebase Hosting handle SSL certificates?
  5. What is App Check and why is it needed alongside Security Rules?

Answers:

  1. The authenticated user’s UID, set by Firebase server-side based on the valid ID token. Clients cannot forge it.
  2. match /users/{userId} { allow read: if request.auth.uid == userId; }
  3. resource refers to the existing document data (for update/delete). request.resource refers to the incoming data (for create/update).
  4. Firebase Hosting automatically provisions and renews SSL certificates via Let’s Encrypt — no manual certificate management.
  5. App Check verifies requests originate from your legitimate app, preventing abuse from scripted API callers who have your project credentials.

Challenge: Write Security Rules for Durga Antivirus Pro that: (1) users can read only their own devices, (2) admins can read all devices, (3) any authenticated user can read threat definitions, (4) device names are validated as strings under 100 characters, and (5) users can write to their own devices but cannot change the userId field.

FAQ

Can Security Rules affect Firestore write throughput?
: Rules execute on every request and add minimal latency (usually <10ms). Complex rules with multiple get() calls may add more overhead but rarely impact throughput.
How do I debug a permission denied error?
: Check the Firebase Console > Firestore > Rules tab for errors. Use the Rules Playground to simulate requests. Enable firebase.debug() logging in the client SDK to see detailed error messages.
What is the difference between allow write and separate create, update, delete?
: allow write covers all write operations. Separating them gives finer control: you might allow create and read but deny update and delete.
Does Firebase Hosting support server-side rendering?
: Firebase Hosting serves static content. For SSR, use Cloud Functions for Firebase with a framework like Next.js or Nuxt.js configured for server-side rendering.

Try It Yourself

Deploy a simple HTML page and test Security Rules:

# Create a project directory
mkdir firebase-hosted-app && cd firebase-hosted-app

# Initialize Firebase
npm init -y
npm install firebase-tools
npx firebase init hosting --project your-project-id

# Add content
echo '<h1>Protected App</h1><script src="/__/auth/init.js"></script>' > public/index.html

# Deploy
npx firebase deploy --only hosting

Set a Firestore rule to allow read: if request.auth != null; and observe that unauthenticated requests get denied with a 403 error in the browser console.

What’s Next

TopicDescription
Firestore Queries & IndexingQuery data efficiently with filters and indexes
Firebase OverviewReview the full Firebase platform
REST API SecurityCompare Firebase rules with REST security patterns
GraphQL IntroductionAnother approach to API design

What’s Next

Congratulations on completing this Firebase Security Hosting tutorial! Here’s where to go from here:

  • Practice daily — Consistency is more important than long study sessions
  • Build a project — Apply what you learned by building something real
  • Explore related topics — Check out other tutorials in the same category
  • Join the community — Discuss with other learners and share your progress

Remember: every expert was once a beginner. Keep coding!

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro