← FirebaseCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to Firebase
Snapshot Sep 30, 2026 · 23:02 UTC · version 1.0.0
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "extension-to-functions-codebase",
"description": "Skill for converting an installed Firebase Extension (or extension source) into a standalone Cloud Functions for Firebase codebase or publishable npm package, including V1 to V2 trigger upgrades, lifecycle hooks, and declarative security",
"included_files": [
{
"relative_path": "references/configuration-migration.md",
"size_in_bytes": 6553
},
{
"relative_path": "references/destructuring-shim.md",
"size_in_bytes": 4466
},
{
"relative_path": "references/signature-mapping.md",
"size_in_bytes": 4350
}
],
"skill_md_contents": "---\nname: extension-to-functions-codebase\ndescription: Skill for converting an installed Firebase Extension (or extension source) into a standalone Cloud Functions for Firebase codebase or publishable npm package, including V1 to V2 trigger upgrades, lifecycle hooks, and declarative security\nmetadata:\n category: Serverless\n---\n\n# Extension to Functions Codebase & npm Package Migration\n\n## Overview\n\nMigrates a Firebase Extension into either:\n\n1. **A local Cloud Functions codebase** (`functions/src/` for app integration).\n1. **A publishable npm package** (reusable open-source package exporting V2\n functions).\n\nLeverages native Cloud Functions features (declarative IAM, Parameterized\nConfig, SDK Lifecycle Hooks) and modernizes 1st Gen triggers to 2nd Gen using\nthe Destructuring Compatibility Shim.\n\n______________________________________________________________________\n\n## Target Migration Workflows\n\n- **Target A: Local Functions Codebase** (End-User App Integration)\n\n - Output: Code under `functions/src/`. Config in `.env`.\n - Deployment: `firebase deploy --only functions`.\n\n- **Target B: Publishable npm Package / Shareable Package**\n\n - Output: Reusable npm package exporting V2 functions.\n - Configuration: `package.json` specifying `exports` map,\n `engines: { \"node\": \">=22\" }`, and\n `peerDependencies: { \"firebase-functions\": \">=6.0.0\" }`.\n - Usage: Consumers install package and re-export functions in `index.ts`\n (`export * from \"<package-name>\"`).\n\n______________________________________________________________________\n\n## Core Rules & Constraints\n\n### 1. Declarative IAM & APIs (Zero-Local-Overhead)\n\nUse native SDK declarations instead of manual `gcloud` scripts or console\ninstructions:\n\n- Use `requiresRole(\"roles/...\")` for required GCP IAM permissions.\n- Use `requiresAPI(\"service.googleapis.com\", \"Description\")` for Google APIs.\n\n### 2. Global Parameter Access Restriction\n\n- **Never call `.value()` at top-level module load scope.**\n- Initialize global SDK instances inside `onInit()` or lazy getters:\n ```typescript\n import { defineString } from \"firebase-functions/params\";\n import { onInit } from \"firebase-functions/v2\";\n\n const dataset = defineString(\"DATASET_ID\");\n let client: BigQuery;\n\n onInit(() => {\n client = new BigQuery({ datasetId: dataset.value() });\n });\n ```\n\n### 3. V2 Concurrency & Cost Parity\n\nV2 enables concurrency (up to 80 requests). To preserve V1 single-concurrency\npricing, set `cpu: \"gcf_gen1\"`.\n\n______________________________________________________________________\n\n## Step-by-Step Migration Execution\n\n### Step 1: Inventory Extension Resources\n\n1. **`extension.yaml`**:\n - `params` → `defineString`, `defineInt`, `defineBoolean`, `defineSecret`.\n - `apis` → `requiresAPI(...)`.\n - `roles` → `requiresRole(...)`.\n - `lifecycleEvents` → `afterFirstDeploy` & `afterRedeploy`.\n - `resources` → Upgrade 1st Gen triggers to 2nd Gen (`onDocumentWritten`,\n `onTaskDispatched`, `onRequest`).\n1. **Files & Scripts**: Preserve devDependencies, test framework (`jest`), and\n test scripts.\n\n### Step 2: Configure `package.json`\n\n- Set `name: \"<package-name>\"`, `engines: { \"node\": \">=22\" }`.\n- Set `peerDependencies`:\n ```json\n \"peerDependencies\": {\n \"firebase-admin\": \"^11.0.0 || ^12.0.0\",\n \"firebase-functions\": \">=6.0.0\"\n }\n ```\n- Configure `exports` map targeting ESM/CommonJS and TypeScript declarations\n (`lib/index.js`, `lib/index.d.ts`).\n\n### Step 3: Upgrade Triggers from V1 to V2\n\n- Firestore: Use `onDocumentWritten` from `firebase-functions/v2/firestore`.\n- Tasks: Use `onTaskDispatched` from `firebase-functions/v2/tasks`. Remove\n `EXT_INSTANCE_ID` when enqueueing tasks.\n- HTTP: Use `onRequest` from `firebase-functions/v2/https`.\n- Apply Destructuring Compatibility Shim (`{ change, context }`,\n `{ snapshot, context }`) where legacy 1st Gen handlers expect\n `(change, context)`.\n\n### Step 4: Convert Lifecycle Events\n\nMap extension lifecycle events to SDK lifecycle hooks in `src/index.ts`:\n\n- `onInstall` → `afterFirstDeploy({ task: { function: \"initTask\" } })`\n- `onUpdate` / `onConfigure` →\n `afterRedeploy({ task: { function: \"setupTask\" } })`\n\n### Step 5: Package README & Export Instructions\n\nGenerate `README.md` containing:\n\n1. Installation instructions (`npm install`).\n1. Re-export snippet (`export * from \"<package-name>\"`).\n1. Parameterized Configuration `.env` reference table.\n1. What Changed (Extension vs Package) comparison table.\n\n_Reminder: NEVER execute `npm publish`._\n"
}SHA-256: 03999708a3d5c21382a70234bfd2383027677d0112c5d46602f37ff7734bf8e0