From a91bc12c5090084a5e1213878bf88e901a4bd0b8 Mon Sep 17 00:00:00 2001 From: Joe Hanley Date: Wed, 11 Feb 2026 14:59:52 -0800 Subject: [PATCH] Add firebase-storage-basics skill --- skills/firebase-storage-basics/SKILL.md | 24 ++++ .../references/provisioning.md | 51 ++++++++ .../references/security_rules.md | 88 ++++++++++++++ .../references/web_sdk_usage.md | 109 ++++++++++++++++++ 4 files changed, 272 insertions(+) create mode 100644 skills/firebase-storage-basics/SKILL.md create mode 100644 skills/firebase-storage-basics/references/provisioning.md create mode 100644 skills/firebase-storage-basics/references/security_rules.md create mode 100644 skills/firebase-storage-basics/references/web_sdk_usage.md diff --git a/skills/firebase-storage-basics/SKILL.md b/skills/firebase-storage-basics/SKILL.md new file mode 100644 index 00000000..f454d753 --- /dev/null +++ b/skills/firebase-storage-basics/SKILL.md @@ -0,0 +1,24 @@ +--- +name: firebase-storage-basics +description: Comprehensive guide for Firebase Storage basics including provisioning, security rules, and SDK usage. Use this skill when the user needs help setting up Cloud Storage for Firebase, writing security rules, or using the Cloud Storage for Firebase SDK in their application. +--- + +# Firebase Storage Basics + +This skill provides a complete guide for getting started with Cloud Storage for Firebase, including provisioning, securing, and integrating it into your application. + +## Provisioning + +To set up Cloud Storage in your Firebase project and local environment, see [provisioning.md](references/provisioning.md). + +**Important**: In order to use Cloud Storage, your Firebase project must be on the Blaze pricing plan. Direct the user to https://console.firebase.google.com/project/_/overview?purchaseBillingPlan=metered to upgrade their plan. + +## Security Rules + +For guidance on writing and deploying Storage Security Rules to protect your files, see [security_rules.md](references/security_rules.md). + +## SDK Usage + +To learn how to use Cloud Storage in your application code, see: + +* **Web (Modular SDK)**: [web_sdk_usage.md](references/web_sdk_usage.md) diff --git a/skills/firebase-storage-basics/references/provisioning.md b/skills/firebase-storage-basics/references/provisioning.md new file mode 100644 index 00000000..84d8ca10 --- /dev/null +++ b/skills/firebase-storage-basics/references/provisioning.md @@ -0,0 +1,51 @@ +# Provisioning Cloud Storage for Firebase + +## 1. Enable Storage in the Firebase Console + +Before you can use Cloud Storage, you need to enable it in your Firebase project: + +1. Go to the [Firebase Console](https://console.firebase.google.com/). +2. Select your project. +3. Navigate to **Build > Storage** in the left sidebar. +4. Click **Get started**. +5. Review the default security rules (you can start in **Test mode** for development, but remember to secure them later). +6. Select a location for your default Cloud Storage bucket. **Note:** This location cannot be changed later. +7. Click **Done**. + +## 2. Manual Project Configuration + +Instead of using the interactive `firebase init` command, you should manually configure your project by creating or updating the following files in your project root. This ensures a deterministic setup suitable for automation. + +### Create `storage.rules` + +Create a file named `storage.rules` in your project root. Here is a basic secure starting point that requires authentication for all access: + +```javascript +service firebase.storage { + match /b/{bucket}/o { + match /{allPaths=**} { + allow read, write: if request.auth != null; + } + } +} +``` + +### Update `firebase.json` + +Add the `storage` configuration to your `firebase.json` file. If the file doesn't exist, create it. This tells the Firebase CLI which rules file to use for deployment. + +```json +{ + "storage": { + "rules": "storage.rules" + } +} +``` + +## 3. Verify and Deploy + +To verify your configuration and deploy your Storage rules to the Firebase backend: + +```bash +firebase deploy --only storage +``` diff --git a/skills/firebase-storage-basics/references/security_rules.md b/skills/firebase-storage-basics/references/security_rules.md new file mode 100644 index 00000000..745b4a77 --- /dev/null +++ b/skills/firebase-storage-basics/references/security_rules.md @@ -0,0 +1,88 @@ +# Firebase Storage Security Rules + +Firebase Security Rules for Cloud Storage determine who has read and write access to files stored in Cloud Storage, as well as how files are structured and what metadata they contain. + +## Basic Structure + +Storage rules are defined in a `service firebase.storage` block. Match statements point to specific file paths. + +```javascript +service firebase.storage { + match /b/{bucket}/o { + match /{allPaths=**} { + allow read, write: if request.auth != null; + } + } +} +``` + +* `match /b/{bucket}/o`: This is the required entry point for all Storage rules. +* `match /{allPaths=**}`: Matches all files in the bucket. +* `allow read, write`: Grants permission. + +## Granular Access Control + +You can write rules for specific paths to control access more granularly: + +```javascript +service firebase.storage { + match /b/{bucket}/o { + // User profile images: Publicly readable, writable only by the user + match /users/{userId}/profile.jpg { + allow read: if true; + allow write: if request.auth != null && request.auth.uid == userId; + } + + // Private user files: Only accessible by the user + match /users/{userId}/private/{fileName} { + allow read, write: if request.auth != null && request.auth.uid == userId; + } + } +} +``` + +## Validating File Metadata + +You can also validate file properties like size and content type: + +```javascript +allow write: if request.resource.size < 5 * 1024 * 1024 // 5MB + && request.resource.contentType.matches('image/.*'); +``` + +## Workflow for Secure Rules + +To ensure your rules are robust, follow this workflow: + +### 1. Analyze Requirements +Identify: +* **Paths**: What files are you storing? (e.g., `/users/{uid}/avatar.png`) +* **Access**: Who can read/write? (e.g., Public read, Owner write) +* **Constraints**: Max size? Specific content types? + +### 2. Draft Rules +Start with **Default Deny** and open up permissions only as needed. + +### 3. "Devil's Advocate" Attack (Critical Step) +Attempt to break your own rules mentally or via tests: +1. **Unauthorized Access**: Can user A read user B's private file? +2. **Path Traversal**: Can I write to a path not explicitly defined? +3. **Validation Bypass**: Can I upload a 1GB file if the limit is 5MB? Can I upload an `.exe` instead of `.jpg`? +4. **Unauthenticated Access**: What happens if `request.auth` is null? + +### 4. Automated Testing +Use the Firebase Emulator and `@firebase/rules-unit-testing` to write unit tests for your rules. + +**Example Test Plan:** +* Authorized upload (should succeed) +* Unauthorized upload (should fail) +* File size limit check (should fail if too large) +* Wrong file type (should fail) +* Public read (should succeed) +* Private read (unauthorized user should fail) + +## Deploying Rules + +```bash +firebase deploy --only storage +``` diff --git a/skills/firebase-storage-basics/references/web_sdk_usage.md b/skills/firebase-storage-basics/references/web_sdk_usage.md new file mode 100644 index 00000000..36166714 --- /dev/null +++ b/skills/firebase-storage-basics/references/web_sdk_usage.md @@ -0,0 +1,109 @@ +# Cloud Storage for Firebase - Web SDK Usage + +This guide covers the basics of using Cloud Storage in a web application using the modular SDK (v9+). + +## 1. Initialize Storage + +Ensure you have initialized your Firebase app first. + +```javascript +import { initializeApp } from "firebase/app"; +import { getStorage } from "firebase/storage"; + +// If running in Firebase App Hosting, you can skip Firebase Config and instead use: +// const app = initializeApp(); + +const firebaseConfig = { + // Your Firebase app config object. Get this by running 'firebase apps:sdkconfig [options] web [appId] +}; + +const app = initializeApp(firebaseConfig); +const storage = getStorage(app); +``` + +## 2. Create a Reference + +A reference points to a file or location in your bucket. + +```javascript +import { ref } from "firebase/storage"; + +// Create a child reference +const imagesRef = ref(storage, 'images'); + +// References can be chained +const spaceRef = ref(storage, 'images/space.jpg'); +// OR +const spaceRef2 = ref(imagesRef, 'space.jpg'); +``` + +## 3. Upload a File + +Use `uploadBytes` for simple uploads or `uploadBytesResumable` for monitoring progress. + +```javascript +import { ref, uploadBytes } from "firebase/storage"; + +const storageRef = ref(storage, 'some-child'); +const file = ... // File object from input element + +uploadBytes(storageRef, file).then((snapshot) => { + console.log('Uploaded a blob or file!'); +}); +``` + +### With Metadata + +```javascript +const metadata = { + contentType: 'image/jpeg', + customMetadata: { + 'uploadedBy': 'user123' + } +}; + +uploadBytes(storageRef, file, metadata).then((snapshot) => { + console.log('Uploaded with metadata'); +}); +``` + +## 4. Download a File (Get URL) + +To display an image or create a download link, get the download URL. + +```javascript +import { ref, getDownloadURL } from "firebase/storage"; + +getDownloadURL(ref(storage, 'images/stars.jpg')) + .then((url) => { + // Insert url into an tag to "download" + const img = document.getElementById('myimg'); + img.setAttribute('src', url); + }) + .catch((error) => { + // Handle any errors + }); +``` + +## 5. Handling Errors + +Always handle errors (e.g., user canceled, permission denied). + +```javascript +.catch((error) => { + switch (error.code) { + case 'storage/object-not-found': + // File doesn't exist + break; + case 'storage/unauthorized': + // User doesn't have permission to access the object + break; + case 'storage/canceled': + // User canceled the upload + break; + case 'storage/unknown': + // Unknown error occurred + break; + } +}); +```