Firebase Storage Security Rules

Storage Security Rules control who can upload, download, update metadata, and delete files in your Cloud Storage bucket. Without proper rules, files are either completely open to the public or completely inaccessible. Rules let you grant precise access based on who the user is, what file they are accessing, and what they are trying to do.

Rules Structure

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if false; // deny everything by default
    }
  }
}

The {bucket} variable matches your storage bucket name. The {allPaths=**} wildcard matches all file paths recursively. You replace these broad rules with specific path-based rules.

Key Variables in Storage Rules

  • request.auth — the authenticated user (null if not logged in)
  • request.auth.uid — the user's unique ID
  • resource.size — size of the existing file in bytes
  • request.resource.size — size of the incoming file in bytes
  • resource.contentType — MIME type of the existing file
  • request.resource.contentType — MIME type of the incoming file

Allowing Only Authenticated Users

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

Users Can Only Access Their Own Files

Use the user's UID in the file path and match it in the rule:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /profile-photos/{userId}/{fileName} {
      // Anyone logged in can read profile photos
      allow read: if request.auth != null;
      // Only the owner can upload or delete their own photo
      allow write: if request.auth.uid == userId;
    }
  }
}

Restricting File Types

Allow uploads only for specific file types by checking the content type:

match /images/{userId}/{fileName} {
  allow write: if request.auth.uid == userId
    && request.resource.contentType.matches("image/.*");
}

match /documents/{userId}/{fileName} {
  allow write: if request.auth.uid == userId
    && (request.resource.contentType == "application/pdf"
      || request.resource.contentType == "text/plain");
}

Restricting File Size

Prevent large uploads that would eat your bandwidth quota:

match /uploads/{userId}/{fileName} {
  allow write: if request.auth.uid == userId
    // Limit to 5 MB
    && request.resource.size < 5 * 1024 * 1024
    && request.resource.contentType.matches("image/.*");
}

Public Read, Authenticated Write

This pattern works well for app assets that everyone can view but only admins can upload:

match /public/{fileName} {
  allow read: if true;
  allow write: if request.auth.token.admin == true;
}

Combining Multiple Conditions

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {

    // Profile photos: anyone logged in can read, owner can write up to 2MB images
    match /profile-photos/{userId}/{fileName} {
      allow read: if request.auth != null;
      allow write: if request.auth.uid == userId
        && request.resource.size < 2 * 1024 * 1024
        && request.resource.contentType.matches("image/.*");
      allow delete: if request.auth.uid == userId;
    }

    // Post attachments: public read, author write
    match /posts/{postId}/{fileName} {
      allow read: if true;
      allow write: if request.auth != null
        && request.resource.size < 10 * 1024 * 1024;
      allow delete: if request.auth != null;
    }
  }
}

Testing Rules in the Console

The Firebase Console has a Rules Playground under Storage > Rules. Simulate requests by entering a file path, selecting an operation (read or write), providing a UID, and specifying file size and content type. The playground shows ALLOW or DENY along with which rule caused the decision.

Key Takeaway

Storage rules match file paths and check conditions against the requesting user and incoming file properties. Always restrict writes to authenticated users and use the user's UID in file paths to enforce per-user access. Add content type and file size checks to prevent abuse. Test your rules in the Rules Playground before deploying to production.

Leave a Comment

Your email address will not be published. Required fields are marked *