Skill instructions
extension-to-functions-codebase4.45 KB
View saved version →
---
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
metadata:
author: Google LLC
category: Serverless
---
# Extension to Functions Codebase & npm Package Migration
## Overview
Migrates a Firebase Extension into either:
1. **A local Cloud Functions codebase** (`functions/src/` for app integration).
1. **A publishable npm package** (reusable open-source package exporting V2
functions).
Leverages native Cloud Functions features (declarative IAM, Parameterized
Config, SDK Lifecycle Hooks) and modernizes 1st Gen triggers to 2nd Gen using
the Destructuring Compatibility Shim.
______________________________________________________________________
## Target Migration Workflows
- **Target A: Local Functions Codebase** (End-User App Integration)
- Output: Code under `functions/src/`. Config in `.env`.
- Deployment: `firebase deploy --only functions`.
- **Target B: Publishable npm Package / Shareable Package**
- Output: Reusable npm package exporting V2 functions.
- Configuration: `package.json` specifying `exports` map,
`engines: { "node": ">=22" }`, and
`peerDependencies: { "firebase-functions": ">=6.0.0" }`.
- Usage: Consumers install package and re-export functions in `index.ts`
(`export * from "<package-name>"`).
______________________________________________________________________
## Core Rules & Constraints
### 1. Declarative IAM & APIs (Zero-Local-Overhead)
Use native SDK declarations instead of manual `gcloud` scripts or console
instructions:
- Use `requiresRole("roles/...")` for required GCP IAM permissions.
- Use `requiresAPI("service.googleapis.com", "Description")` for Google APIs.
### 2. Global Parameter Access Restriction
- **Never call `.value()` at top-level module load scope.**
- Initialize global SDK instances inside `onInit()` or lazy getters:
```typescript
import { defineString } from "firebase-functions/params";
import { onInit } from "firebase-functions/v2";
const dataset = defineString("DATASET_ID");
let client: BigQuery;
onInit(() => {
client = new BigQuery({ datasetId: dataset.value() });
});
```
### 3. V2 Concurrency & Cost Parity
V2 enables concurrency (up to 80 requests). To preserve V1 single-concurrency
pricing, set `cpu: "gcf_gen1"`.
______________________________________________________________________
## Step-by-Step Migration Execution
### Step 1: Inventory Extension Resources
1. **`extension.yaml`**:
- `params` → `defineString`, `defineInt`, `defineBoolean`, `defineSecret`.
- `apis` → `requiresAPI(...)`.
- `roles` → `requiresRole(...)`.
- `lifecycleEvents` → `afterFirstDeploy` & `afterRedeploy`.
- `resources` → Upgrade 1st Gen triggers to 2nd Gen (`onDocumentWritten`,
`onTaskDispatched`, `onRequest`).
1. **Files & Scripts**: Preserve devDependencies, test framework (`jest`), and
test scripts.
### Step 2: Configure `package.json`
- Set `name: "<package-name>"`, `engines: { "node": ">=22" }`.
- Set `peerDependencies`:
```json
"peerDependencies": {
"firebase-admin": "^11.0.0 || ^12.0.0",
"firebase-functions": ">=6.0.0"
}
```
- Configure `exports` map targeting ESM/CommonJS and TypeScript declarations
(`lib/index.js`, `lib/index.d.ts`).
### Step 3: Upgrade Triggers from V1 to V2
- Firestore: Use `onDocumentWritten` from `firebase-functions/v2/firestore`.
- Tasks: Use `onTaskDispatched` from `firebase-functions/v2/tasks`. Remove
`EXT_INSTANCE_ID` when enqueueing tasks.
- HTTP: Use `onRequest` from `firebase-functions/v2/https`.
- Apply Destructuring Compatibility Shim (`{ change, context }`,
`{ snapshot, context }`) where legacy 1st Gen handlers expect
`(change, context)`.
### Step 4: Convert Lifecycle Events
Map extension lifecycle events to SDK lifecycle hooks in `src/index.ts`:
- `onInstall` → `afterFirstDeploy({ task: { function: "initTask" } })`
- `onUpdate` / `onConfigure` →
`afterRedeploy({ task: { function: "setupTask" } })`
### Step 5: Package README & Export Instructions
Generate `README.md` containing:
1. Installation instructions (`npm install`).
1. Re-export snippet (`export * from "<package-name>"`).
1. Parameterized Configuration `.env` reference table.
1. What Changed (Extension vs Package) comparison table.
_Reminder: NEVER execute `npm publish`._
Referenced files: 3 — file references are metadata, not package contents.
firebase-ai-logic-basics12.3 KB
View saved version →
---
name: firebase-ai-logic-basics
description: >-
Integrates Firebase AI Logic (formerly Vertex AI for Firebase) into mobile and web apps (Android, iOS, Web, and Flutter) to call Gemini models from client code. Use when provisioning or initializing Firebase AI Logic, or adding Gemini features to an app: text generation, multimodal input, chat, streaming, structured output, hybrid on-device inference, App Check protection, or switching models with Remote Config.
version: 1.0.1
metadata:
author: Google LLC
category: AiAndMachineLearning
---
# Firebase AI Logic Basics
## Overview
Firebase AI Logic is a product of Firebase that allows developers to add gen AI
to their mobile and web apps using client-side SDKs. The app can directly call
Gemini models via Firebase AI Logic without the developer needing to manage a
dedicated backend. Firebase AI Logic was previously known as "Vertex AI for
Firebase".
It supports the two Gemini API providers:
- **Gemini Developer API**: It has a free tier ideal for prototyping, and
pay-as-you-go for production
- **Agent Platform Gemini API** (formerly branded Vertex AI): Ideal for scale
with enterprise-grade production readiness, requires Blaze pricing plan
Use the Gemini Developer API as a default, and only Agent Platform Gemini API
(formerly branded Vertex AI) if the application requires it.
______________________________________________________________________
## Setup & initialization
### Prerequisites
- Identify the platform the user is interested in building on prior to starting:
Android, iOS, Web, or Flutter.
- If their platform is unsupported, Direct the user to Firebase Docs to learn
how to set up AI Logic for their application (share this link with the user
https://firebase.google.com/docs/ai-logic/get-started)
- The Firebase CLI commands below run through `npx` on every platform, so they
need **Node.js 20+** and npm. Use the `firebase-basics` skill to check for
them and to log in to the Firebase CLI. If Node.js is missing or older than
version 20, ask the user to install it as that skill describes. Don't install
system packages yourself, for example with `sudo apt-get`, because that
changes the user's machine without their consent.
### 1. Provision Firebase AI Logic (ALL platforms)
Use the **Firebase CLI** to provision Firebase AI Logic for the Firebase
Project:
1. Make sure that you're in a firebase directory (with a `firebase.json`).
1. Verify that you're running Firebase CLI commands against the intended
Firebase Project. When you run this command, the active project is marked
with "current":
```bash
npx -y firebase-tools@latest projects:list
```
1. Make sure there's at least one Firebase App for the target platform
registered with the current Firebase Project:
```bash
npx -y firebase-tools@latest apps:list
```
1. Provision Firebase AI Logic for the Firebase Project:
```bash
npx -y firebase-tools@latest init ailogic
```
This command will enable the Gemini Developer API in the Firebase project.
> [!WARNING] **CRITICAL: Provisioning Firebase AI Logic is Required** For all
> platforms (Android, iOS, Web, or Flutter), even if the app already uses
> Firebase, you MUST run `npx -y firebase-tools@latest init ailogic` to
> provision the service. The configuration files of `GoogleService-Info.plist`,
> `google-services.json`, and `firebase_options.dart` ONLY handle client
> configuration and do NOT enable the Firebase AI Logic service, leading to
> `PERMISSION_DENIED` errors.
If you can't run `init ailogic` yourself (for example because Node.js is missing
or the Firebase CLI isn't logged in) do NOT skip it. The app's requests to
Gemini models will fail until the Firebase AI Logic service is provisioned. Tell
the user to run this command in their project directory, and include it in your
final summary:
```bash
npx -y firebase-tools@latest init ailogic
```
### 2. Add the SDK and initialize the service in the app
Adding the SDK dependency and initializing the service are platform-specific.
Before writing code, read the reference for the target platform listed under
[Initialization Code References](#initialization-code-references).
More info in
[Firebase AI Logic Getting Started](https://firebase.google.com/docs/ai-logic/get-started.md.txt)
______________________________________________________________________
## Core Capabilities
> [!WARNING] **CRITICAL: Use current model names:** Always check the
> [Firebase AI Logic Models documentation](https://firebase.google.com/docs/ai-logic/models.md.txt)
> for the currently supported model names. Do NOT use any Gemini 1.x or Gemini
> 2.x models (such as `gemini-1.5-flash`, `gemini-1.5-pro`, `gemini-2.0-flash`,
> `gemini-2.0-pro`, `gemini-2.5-flash`, `gemini-2.5-flash-lite`, or
> `gemini-2.5-pro`), as older models are deprecated or shut down. Always use a
> currently supported Gemini 3+ model; if URL access is blocked in your
> environment, proceed directly without searching local files.
### Text-Only Generation
### Multimodal (Text + Images/Audio/Video/PDF input)
Firebase AI Logic allows Gemini models to analyze image files directly from your
app. This enables features like creating captions, answering questions about
images, detecting objects, and categorizing images. Beyond images, Gemini can
analyze other media types like audio, video, and PDFs by passing them as inline
data with their MIME type. For files larger than 20 megabytes (which can cause
HTTP 413 errors as inline data), store them in Cloud Storage for Firebase and
pass their URLs to the Gemini Developer API.
### Chat Session (Multi-turn)
Maintain history automatically using `startChat`.
### Streaming Responses
To improve the user experience by showing partial results as they arrive (like a
typing effect), use `generateContentStream` instead of `generateContent` for
faster display of results.
### Text-to-Speech (TTS) Generation
Generate spoken audio directly on client devices without a custom speech
backend. Firebase AI Logic supports speech synthesis using dedicated Gemini TTS
models:
- **Supported Models**: `gemini-3.1-flash-tts-preview`
- **Capabilities**:
- Single-speaker voice persona selection (`voiceName`) and multi-speaker
dialogues (up to 2 distinct speakers) via `SpeechConfig` /
`MultiSpeakerVoiceConfig`
- Direct audio responses by setting `responseModalities` to audio
- Streaming speech responses with `generateContentStream` for low-latency
playback
- Audio directives (`[Audio Profile: ...]`, `[Scene: ...]`,
`[Director's Note: ...]`) and emotional tags (`[whispers]`, `[laughs]`,
`[slowly]`)
- Client-side decoding and playback of 24 kHz 16-bit linear PCM (`audio/l16`)
or WAV container format (`audio/x-wav`)
See the [Text-to-Speech (TTS) Generation Guide](references/tts_generation.md)
for full implementation details, streaming patterns, and copy-paste code
snippets for iOS (Swift), Android (Kotlin), and Web.
### Generate Images with Nano Banana
> [!WARNING] **Use current Image model names:** Always check the
> [Firebase AI Logic Models documentation](https://firebase.google.com/docs/ai-logic/models.md.txt)
> for the currently supported image generation (Nano Banana) model names.
- Requires an upgraded Blaze pay-as-you-go billing plan.
### Search Grounding with the built in googleSearch tool
______________________________________________________________________
## Supported Platforms and Frameworks
Supported Platforms and Frameworks include Kotlin and Java for Android, Swift
for iOS, JavaScript for web apps, Dart for Flutter, and C Sharp for Unity.
## Advanced Features
### Structured Output (JSON)
Enforce a specific JSON schema for the response.
### On-Device AI (Hybrid)
Hybrid inference runs prompts with an on-device model when one is available and
falls back to a cloud-hosted model otherwise (or vice versa). Availability and
setup steps differ by platform, more info in the
[hybrid and on-device documentation](https://firebase.google.com/docs/ai-logic/hybrid.md.txt),
which links to each platform's guide.
______________________________________________________________________
## Security & Production
### Firebase App Check
> [!WARNING] **Critical Safety Requirement:** In order to use AI Logic safely,
> you MUST set up App Check on your app. This prevents unauthorized clients from
> using your API quota and accessing your backend resources.
See
[App Check for Firebase AI Logic](https://firebase.google.com/docs/ai-logic/app-check.md.txt)
for setup instructions. Each platform uses its own attestation provider, so
follow the instructions for the target platform.
#### App Check Debug Tokens for Local Development & CI/CD
Because App Check attestation providers (like Play Integrity or DeviceCheck)
reject emulators, simulators, or CI environments, you must use **App Check Debug
Tokens** during development and testing to bypass standard attestation.
> [!WARNING] **CRITICAL: Never Hardcode or Commit Debug Tokens** App Check debug
> tokens allow clients to bypass attestation and access backend resources
> without a genuine device. Treat them as private secrets. **Never commit debug
> tokens to version control or hardcode raw token strings in client code** (Web,
> Android, iOS, or Flutter). Always inject them through local environment
> variables, gitignored local configurations, or CI secrets. If a token is
> compromised, revoke it immediately in the Firebase Console.
##### Local Development (Auto-Generated)
1. Configure your code's App Check provider to use the debug factory. The API is
platform-specific; see the App Check section of the platform reference or the
App Check documentation linked above.
1. Run your app in the emulator/localhost.
1. Look at your runtime debugger console / Logcat logs for the generated UUID:
- *Example:* `AppCheck debug token: "123a4567-b89c-12d3-e456-789012345678"`
1. Register this token in the Firebase Console under **Security > App Check >
Apps > Manage debug tokens**.
> **💡 Tip (Prevent Debug Token Churn):** Simulator or emulator resets, fresh
> installs, and clearing browser data can make the SDK generate a new debug
> token that you must register again. To keep a stable debug token without
> hardcoding it, see the App Check section of the platform reference.
##### CI/CD Pipelines (Pre-Provisioned)
1. Generate and register a new debug token in the Firebase Console under
**Security > App Check > Apps > Manage debug tokens**.
1. Add this token string as an encrypted secret in your CI system (e.g.
`APP_CHECK_DEBUG_TOKEN`).
1. Configure your build to pass this secret as an environment variable to the
SDK during test execution.
### Firebase Remote Config
Consider that you do not need to hardcode model names (e.g., a specific model
version string). Use Firebase Remote Config to update model versions dynamically
without deploying new client code. See
[Changing model names remotely](https://firebase.google.com/docs/ai-logic/change-model-name-remotely.md.txt)
______________________________________________________________________
## Initialization Code References
- **Android (Kotlin)**
- Gemini API Provider: Gemini Developer API
- Reference: [usage_patterns_android.md](references/usage_patterns_android.md)
- **iOS (Swift)**
- Gemini API Provider: Gemini Developer API
- Reference: [ios_setup.md](references/ios_setup.md)
- **Web Modular API**
- Gemini API Provider: Gemini Developer API
- Reference: [usage_patterns_web.md](references/usage_patterns_web.md)
- **Flutter (Dart)**
- Gemini API Provider: Gemini Developer API
- Reference: [flutter_setup.md](references/flutter_setup.md)
> [!WARNING] **CRITICAL: Use current model names:** Always check the
> [Firebase AI Logic Models documentation](https://firebase.google.com/docs/ai-logic/models.md.txt)
> for the currently supported model names. Do NOT use any Gemini 1.x or Gemini
> 2.x models (such as `gemini-1.5-flash`, `gemini-2.0-flash`,
> `gemini-2.5-flash`, or `gemini-2.5-flash-lite`), as older models are
> deprecated or shut down.
## References
[Android (Kotlin) SDK usage patterns](references/usage_patterns_android.md)
[iOS SDK code examples and usage patterns](references/ios_setup.md)
[Web SDK setup, code examples, and usage patterns](references/usage_patterns_web.md)
[Flutter SDK code examples and usage patterns](references/flutter_setup.md)
[Client-side Text-to-Speech (TTS) generation](references/tts_generation.md)
Referenced files: 5 — file references are metadata, not package contents.
firebase-analytics2.58 KB
View saved version →
---
name: firebase-analytics
description: >-
Comprehensive guide for Google Analytics for Firebase (GA4F), including base
setup, SDK initialization, screen tracking, and event logging on Android and
iOS. Use this skill when setting up Google Analytics, adding the SDK, or
logging analytics events. Don't use for standalone CLI login or project/config
file downloads without Analytics (use firebase-basics), or for Crashlytics,
Remote Config, Auth, Firestore, Hosting, App Hosting, or Data Connect.
compatibility: >-
This skill is best used with the Firebase CLI, but does not require it.
Firebase CLI can be accessed through `npx -y firebase-tools@latest`.
version: 1.0.0
metadata:
author: Google LLC
category: CloudObservabilityAndMonitoring
---
# Firebase Analytics
This skill provides a complete guide for getting started with Google Analytics
for Firebase (GA4F) on Android or iOS. It covers base dependency setup,
configuration file placement, initialization, screen tracking, and real-time
event verification.
## Prerequisites
An active Firebase project
[linked to a Google Analytics property](https://support.google.com/analytics/answer/9289234).
See the `firebase-basics` skill for references on project initialization, CLI
login, and downloading app configuration files (`google-services.json` or
`GoogleService-Info.plist`).
## SDK Setup
To learn how to set up Google Analytics for Firebase in your application code
and verify events in real time with DebugView, choose your platform:
* **Android**: [android_setup.md](references/android_setup.md)
* **iOS**: [ios_setup.md](references/ios_setup.md)
## SDK Usage
Google Analytics for Firebase automatically logs some events and user
properties; you can also define custom events and properties.
* [Log events (custom or recommended)](https://firebase.google.com/docs/analytics/events)
* [Set user properties](https://firebase.google.com/docs/analytics/user-properties)
* Track screens
* **Android**:
[android_screen_views.md](references/android_screen_views.md)
* **iOS**: [ios_screen_views.md](references/ios_screen_views.md)
* [Configure data collection and consent mode](https://firebase.google.com/docs/analytics/configure-data-collection)
To learn how to customize event logging and configure advanced behaviors,
consult the documentation for your platform.
* **Android**:
[Get started with Google Analytics for Android](https://firebase.google.com/docs/analytics/android/get-started)
* **iOS**:
[Get started with Google Analytics for iOS+](https://firebase.google.com/docs/analytics/ios/get-started)
Referenced files: 4 — file references are metadata, not package contents.
firebase-app-hosting-basics3.28 KB
View saved version →
---
name: firebase-app-hosting-basics
description: >-
Deploys and manages full-stack web applications (Next.js, Angular) with Server-Side Rendering (SSR) using Firebase App Hosting. Use when deploying Next.js/Angular apps, configuring apphosting.yaml or firebase.json apphosting blocks, managing secrets, setting up GitHub CI/CD, or configuring Blaze billing requirements. Don't use for classic static web hosting, Auth, Firestore, Crashlytics, or Xcode.
metadata:
author: Google LLC
category: Serverless
---
# App Hosting Basics
## Description
This skill enables the agent to deploy and manage modern, full-stack web
applications (Next.js, Angular, etc.) using Firebase App Hosting.
**Important**: In order to use App Hosting, 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.
## Hosting vs App Hosting
**Choose Firebase Hosting if:**
- You are deploying a static site (HTML/CSS/JS).
- You are deploying a simple SPA (React, Vue, etc. without SSR).
- You want full control over the build and deploy process via CLI.
**Choose Firebase App Hosting if:**
- You are using a supported full-stack framework like Next.js or Angular.
- You need Server-Side Rendering (SSR) or ISR.
- You want an automated "git push to deploy" workflow with zero configuration.
## Deploying to App Hosting
### Deploy from Source
This is the recommended flow for most users.
1. Configure `firebase.json` with an `apphosting` block.
```json
{
"apphosting": {
"backendId": "my-app-id",
"rootDir": "/",
"ignore": [
"node_modules",
".git",
".next",
".vercel",
"firebase-debug.log",
"firebase-debug.*.log",
"functions"
]
}
}
```
1. Create or edit `apphosting.yaml`- see
[Configuration](references/configuration.md) for more information on how to
do so.
1. Create the backend if it does not exist (`apphosting:backends:list`; switch
`--primary-region`, e.g. `us-east4`, if a region hits its 10-backend quota):
```bash
npx -y firebase-tools@latest apphosting:backends:create --backend my-app-id --primary-region us-central1 --root-dir /
```
1. If the app needs safe access to sensitive keys, set and grant access after
creating the backend:
```bash
printf '%s' '<value>' | npx -y firebase-tools@latest apphosting:secrets:set <secret-name> --data-file - --force
npx -y firebase-tools@latest apphosting:secrets:grantaccess <secret-name> --backend my-app-id
```
1. Run `npx -y firebase-tools@latest deploy` when you are ready to deploy.
### Automated deployment via GitHub (CI/CD)
Alternatively, set up a backend connected to a GitHub repository for automated
"git push" deployments. For GitHub-connected backends, trigger rollouts with
`npx -y firebase-tools@latest apphosting:rollouts:create <backend-id> --git-branch <branch>`
(do not use `rollouts:create` when deploying from local source with `deploy`).
For other backend or secret flags (`backends:get`, `backends:delete`, etc.), run
`npx -y firebase-tools@latest <command> --help`.
## Emulation
See [Emulation](references/emulation.md) for more information on how to test
your app locally using the Firebase Local Emulator Suite.
Referenced files: 3 — file references are metadata, not package contents.
firebase-auth-basics4.58 KB
View saved version →
---
name: firebase-auth-basics
description: Guide for setting up and using Firebase Authentication. Use this skill when the user's app requires user sign-in, user management, or secure data access using auth rules.
compatibility: This skill is best used with the Firebase CLI, but does not require it. Firebase CLI can be accessed through `npx -y firebase-tools@latest`.
metadata:
author: Google LLC
category: Identity
---
## Prerequisites
- **Firebase Project**: Created via
`npx -y firebase-tools@latest projects:create` (see `firebase-basics`).
- **Firebase CLI**: Installed and logged in (see `firebase-basics`).
## Core Concepts
Firebase Authentication provides backend services, easy-to-use SDKs, and
ready-made UI libraries to authenticate users to your app.
### Users
A user is an entity that can sign in to your app. Each user is identified by a
unique ID (`uid`) which is guaranteed to be unique across all providers. User
properties include:
- `uid`: Unique identifier.
- `email`: User's email address (if available).
- `displayName`: User's display name (if available).
- `photoURL`: URL to user's photo (if available).
- `emailVerified`: Boolean indicating if the email is verified.
### Identity Providers
Firebase Auth supports multiple ways to sign in:
- **Email/Password**: Basic email and password authentication.
- **Federated Identity Providers**: Google, Facebook, Twitter, GitHub,
Microsoft, Apple, etc.
- **Phone Number**: SMS-based authentication.
- **Anonymous**: Temporary guest accounts that can be linked to permanent
accounts later.
- **Custom Auth**: Integrate with your existing auth system.
Google Sign In is recommended as a good and secure default provider.
### Tokens
When a user signs in, they receive an ID Token (JWT). This token is used to
identify the user when making requests to Firebase services (Realtime Database,
Cloud Storage, Firestore) or your own backend.
- **ID Token**: Short-lived (1 hour), verifies identity.
- **Refresh Token**: Long-lived, used to get new ID tokens.
## Workflow
### 1. Provisioning
#### Option 1. Enabling Authentication via CLI
Only Google Sign In, anonymous auth, and email/password auth can be enabled via
CLI. For other providers, use the Firebase Console.
Configure Firebase Authentication in `firebase.json` by adding an 'auth' block:
```
{
"auth": {
"providers": {
"anonymous": true,
"emailPassword": true,
"googleSignIn": {
"oAuthBrandDisplayName": "Your Brand Name",
"supportEmail": "support@example.com",
"authorizedRedirectUris": [
"https://my-project-id.firebaseapp.com/__/auth/handler",
"http://localhost"
]
}
}
}
}
```
> [!NOTE] If the Google Sign-In popup opens and immediately closes with the
> error `[firebase_auth/unauthorized-domain]`, it means the domain is not
> authorized. For local development, add `http://localhost` to
> `authorizedRedirectUris` in `firebase.json` (or ensure `localhost` is included
> in the **Authorized Domains** list in the Firebase Console under
> Authentication > Settings > Authorized domains). **CRITICAL**: Do NOT include
> the port number in `authorizedRedirectUris` (e.g., use `http://localhost`, NOT
> `http://localhost:9090` or `http://localhost:4000`), and do NOT include the
> protocol or port number in the Console Authorized Domains list (use
> `localhost`). Including a port number in `authorizedRedirectUris` causes
> `firebase deploy --only auth` to fail with `INVALID_AUTHORIZED_DOMAIN`.
**CRITICAL**: After configuring `firebase.json`, you MUST deploy the auth
configuration to the Firebase backend for the changes to take effect. This is
essential for auth providers like Google Sign-In, email/password, etc. to
auto-generate the necessary OAuth clients for your app platforms. Run:
```bash
npx -y firebase-tools@latest deploy --only auth
```
#### Option 2. Enabling Authentication in Console
Enable other providers in the Firebase Console.
1. Go to the
https://console.firebase.google.com/project/_/authentication/providers
1. Select your project.
1. Enable the desired Sign-in providers (e.g., Email/Password, Google).
### 2. Client Setup & Usage
**Web** See [references/client_sdk_web.md](references/client_sdk_web.md).
**Flutter** See [references/flutter_setup.md](references/flutter_setup.md).
**Android (Kotlin)** See
[references/client_sdk_android.md](references/client_sdk_android.md).
**iOS (Swift)** See [references/ios_setup.md](references/ios_setup.md).
### 3. Security Rules
Secure your data using `request.auth` in Firestore/Storage rules.
See [references/security_rules.md](references/security_rules.md).
Referenced files: 5 — file references are metadata, not package contents.
firebase-basics7.24 KB
View saved version →
---
name: firebase-basics
description: >-
Provides foundational Firebase CLI setup, CLI installation, version checks (`firebase-tools@latest --version`), CLI login (including --no-localhost), project creation, project selection (`firebase use`), and app config file downloads (`google-services.json`, `GoogleService-Info.plist`). Use ONLY for CLI login, project creation/switching, or downloading app config files. Don't use for Firebase Hosting deploy, Firestore, Auth, App Hosting, Data Connect, Crashlytics, or Remote Config.
metadata:
author: Google LLC
category: CloudInfrastructureAndServices
version: "1.0.0"
---
# Prerequisites
Complete these setup steps before proceeding:
1. **Local Environment Setup:** Verify the environment is properly set up so we
can use Firebase tools:
- Run `npx -y firebase-tools@latest --version` to check if the Firebase CLI
is installed.
- Verify if the Firebase MCP server is installed using your existing tools.
- **CRITICAL**: Before configuring any extensions or agent environments
below, you MUST read
[references/local-env-setup.md](references/local-env-setup.md).
- **DO NOT SKIP** this step: if 'firebase-basics' is the only Firebase skill
available to you, you must follow the reference for your agent environment
to set up the full suite of Firebase skills:
- **Gemini CLI**: Review
[references/setup/gemini_cli.md](references/setup/gemini_cli.md)
- **Antigravity**: Review
[references/setup/antigravity.md](references/setup/antigravity.md)
- **Android Studio**: Review
[references/setup/android_studio.md](references/setup/android_studio.md)
- **Claude Code**: Review
[references/setup/claude_code.md](references/setup/claude_code.md)
- **Cursor**: Review
[references/setup/cursor.md](references/setup/cursor.md)
- **GitHub Copilot**: Review
[references/setup/github_copilot.md](references/setup/github_copilot.md)
- **Other Agents**: Review
[references/setup/other_agents.md](references/setup/other_agents.md)
1. **Authentication:** Ensure you are logged in to Firebase so that commands
have the correct permissions. Run `npx -y firebase-tools@latest login:list`
first; if not logged in, run `npx -y firebase-tools@latest login`. For
environments without a browser (e.g., remote shells), use
`npx -y firebase-tools@latest login --no-localhost`.
- The command should output the current user.
- If you are not logged in, follow the interactive instructions from this
command to authenticate.
1. **Active Project:** Most Firebase tasks require an active project context.
> [!IMPORTANT] **For Agents:** If no Project ID was provided, you MUST pause
> and ask the developer if they prefer to:
>
> 1. **Provide an existing Firebase Project ID**, or
> 1. **Create a new Firebase project**.
- **If using an existing Project ID:**
1. Check the current project with `npx -y firebase-tools@latest use` (if
`firebase.json` is missing at the project root, create `{}` first).
1. If the command outputs `Active Project: <project-id>`, confirm with the
user if this is the intended project.
1. If not, or if no project is active, set the project provided by the
user:
```bash
npx -y firebase-tools@latest use <PROJECT_ID>
```
- **If creating a new project:** Run the following command to create it:
```bash
npx -y firebase-tools@latest projects:create <project-id> --display-name "<display-name>"
```
*Note: The `<project-id>` must be 6-30 characters, lowercase, and can
contain digits and hyphens. It must be globally unique.*
# Firebase Usage Principles
Adhere to these principles:
1. **Use npx for CLI commands:** To ensure you always use the latest version of
the Firebase CLI, always prepend commands with `npx -y firebase-tools@latest`
instead of just `firebase`. For example, use
`npx -y firebase-tools@latest --version`. NEVER suggest the naked `firebase`
command as an alternative.
1. **Prioritize official knowledge:** For any Firebase-related knowledge,
consult the `developerknowledge_search_documents` MCP tool before falling
back to Google Search or your internal knowledge base. Including "Firebase"
in your search query significantly improves relevance.
1. **Follow Agent Skills for implementation guidance:** Skills provide
opinionated workflows (CUJs), security rules, and best practices. Always
consult them to understand *how* to implement Firebase features correctly
instead of relying on general knowledge.
1. **Use Firebase MCP Server tools instead of direct API calls:** Whenever you
need to interact with remote Firebase APIs (such as fetching Crashlytics logs
or executing Data Connect queries), use the tools provided by the Firebase
MCP Server instead of attempting manual API calls.
1. **Keep Plugin / Agent Skills updated:** Since Firebase best practices evolve
quickly, regularly check for and install updates to their Firebase plugin or
Agent Skills. Similarly, if you encounter issues with outdated tools or
commands, follow the steps below based on your agent environment:
- **Antigravity**: Follow
[references/refresh/antigravity.md](references/refresh/antigravity.md)
- **Gemini CLI**: Follow
[references/refresh/gemini-cli.md](references/refresh/gemini-cli.md)
- **Claude Code**: Follow
[references/refresh/claude.md](references/refresh/claude.md)
- **Cursor**: Follow
[references/refresh/other-agents.md](references/refresh/other-agents.md)
- **Android Studio**: Follow
[references/refresh/android_studio.md](references/refresh/android_studio.md)
- **Others**: Follow
[references/refresh/other-agents.md](references/refresh/other-agents.md)
1. **Automate Config File Retrieval:** When setting up iOS or Android apps, do
NOT direct users to the Firebase Console to download `google-services.json`
or `GoogleService-Info.plist`. Instead, use the Firebase CLI to fetch the
config programmatically:
- For Android:
`npx -y firebase-tools@latest apps:sdkconfig ANDROID <APP_ID> --project <PROJECT_ID>`
- For iOS:
`npx -y firebase-tools@latest apps:sdkconfig IOS <APP_ID> --project <PROJECT_ID>`
Save the output to the appropriate location (e.g.,
`app/google-services.json` for Android, or a path to be linked by
`xcode-project-setup` for iOS).
# References
- **Initialize Firebase:** See
[references/firebase-service-init.md](references/firebase-service-init.md)
when you need to initialize new Firebase services using the CLI.
- **Exploring Commands:** See
[references/firebase-cli-guide.md](references/firebase-cli-guide.md) to
discover and understand CLI functionality.
- **SDK Setup:** For detailed guides on adding Firebase to your app:
- **Web**: See [references/web_setup.md](references/web_setup.md)
- **Android**: See [references/android_setup.md](references/android_setup.md)
- **iOS**: See [references/ios_setup.md](references/ios_setup.md)
# Common Issues
- **Login Issues:** If the browser fails to open during the login step, use
`npx -y firebase-tools@latest login --no-localhost` instead.
- **Genkit:** If using Genkit, install the skills:
```bash
npx skills add genkit-ai/skills
```
Referenced files: 19 — file references are metadata, not package contents.
firebase-crashlytics1.71 KB
View saved version →
---
name: firebase-crashlytics
description: Comprehensive guide for Firebase Crashlytics, including provisioning and SDK usage. Use this skill when the user needs help setting up Crashlytics, adding crash reporting, or using the Crashlytics SDK in their application.
compatibility: This skill is best used with the Firebase CLI, but does not require it. Firebase CLI can be accessed through `npx -y firebase-tools@latest`.
metadata:
author: Google LLC
category: CloudObservabilityAndMonitoring
---
# Crashlytics
This skill provides a complete guide for getting started with Crashlytics on
Android or iOS. Crash data collected from client applications can be read using
the MCP server in the Firebase CLI.
## Prerequisites
Provisioning Crashlytics requires both a Firebase project and a Firebase app,
either Android or iOS. To read the data collected by Crashlytics, install the
MCP server in the Firebase CLI. See the `firebase-basics` skill for references.
## SDK Setup
To learn how to setup Crashlytics in your application code, choose your
platform:
- **Android**: [android_setup.md](references/android_setup.md)
- **iOS**: [ios_setup.md](references/ios_setup.md)
## SDK Usage
The SDK provides a number of features to make crash reports more actionable.
- Add custom keys
- Add custom logs
- Set user identifiers
- Report non-fatal exceptions
To learn how to customize crash reports and add additional debugging data,
consult the documentation for your platform.
- **Android**:
[Customize Crash Reports for Android](https://firebase.google.com/docs/crashlytics/android/customize-crash-reports.md)
- **iOS**:
[Customize Crash Reports for Apple Platforms](https://firebase.google.com/docs/crashlytics/ios/customize-crash-reports.md)
Referenced files: 2 — file references are metadata, not package contents.
firebase-data-connect9.3 KB
View saved version →
---
name: firebase-data-connect
description: Builds and deploys Firebase SQL Connect (aka Firebase Data Connect) backends with PostgreSQL securely. Use when designing schemas with tables and relations, writing authorized queries and mutations, configuring real-time data updates, or generating type-safe SDKs. Use when you need a relational database with Firebase, or when the user mentions SQL Connect or Data Connect.
metadata:
author: Google LLC
category: Databases
---
# Firebase SQL Connect
Firebase SQL Connect is a relational database service using Cloud SQL for
PostgreSQL with GraphQL schema, auto-generated queries/mutations, and type-safe
SDKs.
> [!NOTE] **Product Rename**: Firebase Data Connect was renamed to **Firebase
> SQL Connect**. All instructions, references, and examples in this skill
> repository referring to "Data Connect" or "Firebase Data Connect" apply to
> "SQL Connect" and "Firebase SQL Connect" as well.
## Project Structure
```text
dataconnect/
├── dataconnect.yaml # Service configuration
├── seed_data.gql # LOCAL ONLY — prototype/test data
├── schema/
│ └── schema.gql # Data model (types with @table)
└── connector/
├── connector.yaml # Connector config + SDK generation
├── queries.gql # Queries
└── mutations.gql # Mutations
```
## Key Tools for Validation
Rely on these two mechanisms to ensure project correctness:
1. **Review GraphQL Schema**: Both user-defined and generated extensions (in
`.dataconnect/schema/main/`).
1. **Validate Operations**: Run
`npx -y firebase-tools@latest dataconnect:compile` against the schema.
## Operation Strategies: GraphQL vs. Native SQL
Always default to **Native GraphQL**. **Native SQL lacks type safety** and
bypasses schema-enforced structures. Only use **Native SQL** when the user
explicitly requests it or when the task requires advanced database features.
| Strategy | When to use | Implementation |
| ---------------------------- | ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| **Native GraphQL** (Default) | Almost all use cases. Standard CRUD, basic filtering/sorting, simple relational joins. Requires full type safety. | Auto-generated fields (`movie_insert`, `movies`). Strong typing and schema enforcement. |
| **Native SQL** (Advanced) | PostgreSQL extensions (e.g., PostGIS), window functions (`RANK()`), complex aggregations, or highly tuned sub-queries. | Raw SQL string literals via `_select`, `_execute`, etc. Requires strict positional parameters (`$1`). No type safety. |
## Development Workflow
Follow this strict workflow to build your application. You **must** read the
linked reference files for each step to understand the syntax and available
features.
### 1. Define Data Model (`schema/schema.gql`)
Define your GraphQL types, tables, and relationships (which map to a Postgres
schema).
> **Read [reference/schema.md](reference/schema.md)** for:
>
> - `@table`, `@col`, `@default`
> - Relationships (`@ref`, one-to-many, many-to-many)
> - Data types (UUID, Vector, JSON, etc.)
### 2. Define Authorized Operations (`connector/queries.gql`, `connector/mutations.gql`)
Write the queries and mutations your client will use, including authorization
logic. SQL Connect is secure by default.
> **Read [reference/operations.md](reference/operations.md)** for:
>
> - **Queries**: Filtering (`where`), Ordering (`orderBy`), Pagination
> (`limit`/`offset`).
> - **Mutations**: Create (`_insert`), Update (`_update`), Delete (`_delete`).
> - **Upserts**: Use `_upsert` to "insert or update" records (CRITICAL for user
> profiles).
> - **Transactions**: Use `@transaction` for multi-step atomic operations. Use
> `_expr: "response.<prevStep>"` to pass data between steps.
>
> **Read [reference/security.md](reference/security.md)** for authorization:
>
> - `@auth(level: ...)` for PUBLIC, USER, or NO_ACCESS.
> - `@check` and `@redact` for row-level security and validation.
>
> **Read [reference/realtime.md](reference/realtime.md)** for real-time
> subscriptions:
>
> - `@refresh` directive for time-based polling and event-driven updates.
> - CEL conditions to scope refresh triggers precisely.
>
> **Read [reference/native_sql.md](reference/native_sql.md)** for Native SQL
> operations:
>
> - Embedding raw SQL with `_select`, `_selectFirst`, `_execute`
> - Strict rules for positional parameters (`$1`, `$2`), quoting, and CTEs
> - Advanced PostgreSQL features (PostGIS, Window Functions)
### 3. Use type-safe SDK in your apps
Generate type-safe code for your client platform.
Configure SDK generation in `connector.yaml`:
```yaml
connectorId: my-connector
generate:
javascriptSdk:
outputDir: "../web-app/src/lib/dataconnect"
package: "@movie-app/dataconnect"
kotlinSdk:
outputDir: "../android-app/app/src/main/kotlin/com/example/dataconnect"
package: "com.example.dataconnect"
swiftSdk:
outputDir: "../ios-app/DataConnect"
package: "DataConnectGenerated"
```
Generate SDKs:
```bash
npx -y firebase-tools@latest dataconnect:sdk:generate
```
For platform-specific instructions on how to use the generated SDKs, read:
- **Web (TypeScript)**: [reference/sdk_web.md](reference/sdk_web.md)
- **Android (Kotlin)**: [reference/sdk_android.md](reference/sdk_android.md)
- **iOS (Swift)**: [reference/sdk_ios.md](reference/sdk_ios.md)
- **Admin (Node.js)**:
[reference/sdk_admin_node.md](reference/sdk_admin_node.md)
- **Flutter (Dart)**: [reference/sdk_flutter.md](reference/sdk_flutter.md)
______________________________________________________________________
## Feature Capability Map
If you need to implement a specific feature, consult the mapped reference file:
| Feature | Reference File | Key Concepts |
| :------------------------------ | :----------------------------------------------------------- | :------------------------------------------------- |
| **Data Modeling** | [reference/schema.md](reference/schema.md) | `@table`, `@unique`, `@index`, Relations |
| **Vector Search** | [reference/search.md](reference/search.md) | `Vector`, `@col(dataType: "vector")`, embeddings |
| **Full-Text Search** | [reference/search.md](reference/search.md) | `@searchable`, `movies_search` |
| **Upserting Data** | [reference/operations.md](reference/operations.md) | `_upsert` mutations |
| **Complex Filters** | [reference/operations.md](reference/operations.md) | `_or`, `_and`, `_not`, `eq`, `contains` |
| **Transactions** | [reference/operations.md](reference/operations.md) | `@transaction`, `response` binding |
| **Environment Config** | [reference/config.md](reference/config.md) | `dataconnect.yaml`, `connector.yaml` |
| **Realtime Subscriptions** | [reference/realtime.md](reference/realtime.md) | `@refresh`, `subscribe()`, auto-refresh |
| **Cloud Functions Integration** | [reference/cloud_functions.md](reference/cloud_functions.md) | `onMutationExecuted`, triggering events |
| **Data Seeding & Migrations** | [reference/data_seeding.md](reference/data_seeding.md) | `seed_data.gql`, `_insertMany`, Admin SDK bulk |
| **Starter Templates** | [templates.md](templates.md) | CRUD, user-owned resources, many-to-many, SDK init |
______________________________________________________________________
## Deployment & CLI
> **Read [reference/config.md](reference/config.md)** for deep dive on
> configuration.
Follow these patterns based on your current task:
### How to initialize SQL Connect in a Firebase project
1. Understand the app idea. Ask clarification questions if unclear.
1. Run `npx -y firebase-tools@latest init dataconnect`.
1. Validate that the app template and generated SDK are setup.
### How to build apps using SQL Connect locally
1. Start the emulator:
`npx -y firebase-tools@latest emulators:start --only dataconnect`.
1. Write schema and operations.
1. Seed local test data into `seed_data.gql`. Read
[reference/data_seeding.md](reference/data_seeding.md#1-local-prototyping-data-seeding).
1. Run `npx -y firebase-tools@latest dataconnect:compile` or
`npx -y firebase-tools@latest dataconnect:sdk:generate` to validate them.
1. Use the operations in your app and build it.
### How to deploy SQL Connect to Cloud SQL
1. Run `npx -y firebase-tools@latest deploy --only dataconnect`.
## Examples
For complete, working code examples of schemas and operations, see
**[examples.md](examples.md)**.
For ready-to-use starter templates (CRUD, user-owned resources, many-to-many,
YAML configs, SDK init), see **[templates.md](templates.md)**.
Referenced files: 16 — file references are metadata, not package contents.
firebase-firestore4.68 KB
View saved version →
---
name: firebase-firestore
description: >-
Sets up, manages, queries, and configures Cloud Firestore databases (Standard/Enterprise edition), including data modeling, security rules, indexes, and SDK integrations (Web, Python, iOS, Android, Flutter). Use when creating/listing Firestore databases, defining data models/indexes, writing SDK queries, or integrating Firestore SDKs. For authoring or modifying Firestore Security Rules (firestore.rules), delegate to the firestore-rules-author subagent if subagent delegation is available, or use firestore-rules-creation otherwise. Don't use for Firebase Hosting, Data Connect, Auth, Storage/GCS, Crashlytics, Functions, or BigQuery.
compatibility: This skill is best used with the Firebase CLI, but does not require it. Firebase CLI can be accessed through `npx -y firebase-tools@latest`.
metadata:
author: Google LLC
category: Databases
---
# Cloud Firestore Database and Operations
> [!IMPORTANT] **Security Rules Authoring (`firestore.rules`)** Whenever your
> task requires creating, authoring, or modifying `firestore.rules`:
>
> - **If subagent delegation AND the `firestore-rules-author` subagent are
> available**: delegate authoring `firestore.rules` to the
> `firestore-rules-author` subagent rather than writing `firestore.rules`
> directly in the main agent.
> - **If subagent delegation is unavailable** (e.g., subagents not enabled in
> the IDE) **OR `firestore-rules-author` is not installed**: read and follow
> the `firestore-rules-creation` skill to write `firestore.rules` directly.
Before setting up dependencies, writing data models, or configuring security
rules, you MUST always identify the Firestore instance edition.
## 1. Instance Selection and Edition Detection
Run the following command to list current Firestore databases:
```bash
npx -y firebase-tools@latest firestore:databases:list
```
### A. Instance Found
1. For each database found, inspect its edition and details:
```bash
npx -y firebase-tools@latest firestore:databases:get <database-id>
```
1. Ask the user which database instance they wish to target or if they would
prefer to create a new instance.
1. Once the target instance is established:
- If the **`edition`** is `STANDARD`, follow the guides under
`references/standard/`.
- If the **`edition`** is `ENTERPRISE` or native mode, follow the guides
under `references/enterprise/`.
### B. No Instance Found (or New Requested)
If no databases exist or the user requests a new one, default to provisioning an
**Enterprise** edition database and ask the user what location to use. Run
`npx -y firebase-tools@latest firestore:locations` to get the list of options.
Suggest colocating with other resources if applicable.
Once the location is determined, create the database:
```bash
npx -y firebase-tools@latest firestore:databases:create <database-id> --edition="enterprise" --location="<selected-location>"
```
Proceed with using the guides under `references/enterprise/`.
______________________________________________________________________
## 2. Specialized Guides
Based on the identified or created instance edition, open and read the
corresponding reference guides:
### Standard Edition (`references/standard/`)
- **Provisioning**: Read [provisioning.md](references/standard/provisioning.md)
- **Security Rules**: See the `firestore-rules-creation` skill
- **SDK Usage**: Read [web_sdk_usage.md](references/standard/web_sdk_usage.md),
[android_sdk_usage.md](references/standard/android_sdk_usage.md),
[ios_setup.md](references/standard/ios_setup.md), or
[flutter_setup.md](references/standard/flutter_setup.md)
- **Indexes**: Read [indexes.md](references/standard/indexes.md)
### Enterprise Edition / Native Mode (`references/enterprise/`)
- **Provisioning**: Read
[provisioning.md](references/enterprise/provisioning.md)
- **Data Model**: Read [data_model.md](references/enterprise/data_model.md)
- **Security Rules**: See the `firestore-rules-creation` skill
- **SDK Usage**:
> [!CRITICAL] **Mandatory Reference Reading** Before writing or modifying any
> application code for Firestore Enterprise Edition, you **MUST** read at
> least one of the relevant reference documents below for the target
> platform/language to understand specific architectural requirements and
> pipeline initialization patterns.
Read [web_sdk_usage.md](references/enterprise/web_sdk_usage.md),
[python_sdk_usage.md](references/enterprise/python_sdk_usage.md),
[android_sdk_usage.md](references/enterprise/android_sdk_usage.md),
[ios_setup.md](references/enterprise/ios_setup.md), or
[flutter_setup.md](references/enterprise/flutter_setup.md)
- **Indexes**: Read [indexes.md](references/enterprise/indexes.md)
Referenced files: 14 — file references are metadata, not package contents.
firebase-hosting-basics2.36 KB
View saved version →
---
name: firebase-hosting-basics
description: >-
Deploys and configures classic Firebase Hosting for static websites, single-page apps (SPAs), and microservices. Use when deploying static sites/SPAs, setting up custom domains, configuring firebase.json hosting settings (redirects, rewrites, headers, multi-site), or managing preview channels. Don't use for Firebase App Hosting (Next.js/SSR), Auth, Firestore queries/rules, Data Connect, or Crashlytics.
metadata:
author: Google LLC
category: Serverless
---
# hosting-basics
This skill provides instructions and references for working with Firebase
Hosting, a fast and secure hosting service for your web app, static and dynamic
content, and microservices.
## Overview
Firebase Hosting provides production-grade web content hosting for developers.
With a single command, you can deploy web apps and serve both static and dynamic
content to a global CDN (content delivery network).
**Key Features:**
- **Fast Content Delivery:** Files are cached on SSDs at CDN edges around the
world.
- **Secure by Default:** Zero-configuration SSL is built-in.
- **Preview Channels:** View and test changes on temporary preview URLs before
deploying live.
- **GitHub Integration:** Automate previews and deploys with GitHub Actions.
- **Dynamic Content:** Serve dynamic content and microservices using Cloud
Functions or Cloud Run.
## Hosting vs App Hosting
**Choose Firebase Hosting if:**
- You are deploying a static site (HTML/CSS/JS).
- You are deploying a simple SPA (React, Vue, etc. without SSR).
- You want full control over the build and deploy process via CLI.
**Choose Firebase App Hosting if:**
- You are using a supported full-stack framework like Next.js or Angular.
- You need Server-Side Rendering (SSR) or ISR.
- You want an automated "git push to deploy" workflow with zero configuration.
## Instructions
### 1. Configuration (`firebase.json`)
For details on configuring Hosting behavior, including public directories,
redirects, rewrites, and headers, see
[configuration.md](references/configuration.md).
### 2. Deploying
For instructions on deploying your site, using preview channels, and managing
releases, see [deploying.md](references/deploying.md).
### 3. Emulation
To test your app locally:
```bash
npx -y firebase-tools@latest emulators:start --only hosting
```
This serves your app at `http://localhost:5000` by default.
Referenced files: 2 — file references are metadata, not package contents.
firebase-remote-config-basics4.77 KB
View saved version →
---
name: firebase-remote-config-basics
description: >-
Manages Firebase Remote Config templates, feature flags, loading strategies, and SDKs (Android, iOS). Use when downloading/deploying remoteconfig JSON templates, managing version history/feature flags, setting in-app defaults, fetchAndActivate(), real-time listeners, or SDK setup. Don't use for Firebase Hosting, Auth, Firestore, Data Connect, Crashlytics, or App Hosting.
compatibility: This skill is best used with the Firebase CLI, but does not require it. Firebase CLI can be accessed through `npx -y firebase-tools@latest`.
metadata:
author: Google LLC
category: ApplicationDevelopment
---
# Remote Config
This skill provides a complete guide for getting started with Remote Config on
Android or iOS. Remote Config allows you to change the behavior and appearance
of your app without publishing an app update by maintaining a cloud-based
configuration template.
## Prerequisites
Provisioning Remote Config requires both a Firebase project and a Firebase app,
either Android or iOS. To manage the Remote Config template and conditions via
the command line, use the Firebase CLI. See the `firebase-basics` skill for
references on project initialization.
## Troubleshooting Execution
### Handling npx 403 Forbidden Errors
If `npx -y firebase-tools@latest` fails due to registry permissions (403 error):
1. **Inform the user**: "I am unable to fetch the latest Firebase tools via npx
due to a registry error."
1. **Fallback**: Attempt to use the local `firebase` command directly if the
user confirms it is installed globally (`npm install -g firebase-tools`).
### Handling Project Context Issues
If a command fails because "no active project is selected":
1. **Check login**: Run `npx -y firebase-tools@latest login:list`.
1. **Prompt for ID**: If logged in but no project is active, ask the user:
"Please provide your Firebase Project ID to proceed."
1. **Use Flag**: Append `--project <PROJECT_ID>` to every subsequent command.
## SDK Setup
To learn how to set up Remote Config in your application code, choose your
platform:
- **Android**: [android_setup.md](references/android_setup.md)
- **iOS**: [ios_setup.md](references/ios_setup.md)
## Best Practices and Template Management
Follow these guidelines and use the associated CLI tools to ensure efficient and
safe use of Remote Config.
### Fetching Strategies
To optimize app performance and user experience, follow these recommended
patterns (see
[Loading Strategies](https://firebase.google.com/docs/remote-config/loading)):
- **Load new values for next startup**: The most effective pattern is to
activate previously fetched values immediately on startup and fetch new values
in the background to be used next time. This minimizes user wait time.
- **Real-time Updates**: Use the SDK's real-time listener to update the app
instantly without a refresh when server-side configuration changes.
### Template Management via CLI
Use the following commands to manage your Remote Config template and version
history through the terminal:
- **Get current template**: Save the remote template to a local JSON file for
auditing or modification.
```bash
npx -y firebase-tools@latest remoteconfig:get -o remote_config.json
```
- **Autonomous Editing & Discovery** : Modify the local `remote_config.json`
directly. Determine the correct signal (e.g., device.country or percent) and
update the "conditions" array and "parameters" map accordingly.
- **MANDATORY: User Review and Verification** : STOP and ask the user to verify
your changes before proceeding to deployment.
- Action: Inform the user: "I have prepared the changes in remote_config.json.
Please review the file for accuracy. Once you are satisfied, tell me to
'deploy' to make the changes live."
- **Deployment Orchestration** : To push changes, you must ensure the
environment is configured for deployment.
- Config Mapping: If a firebase.json file is missing, create one to map the
local JSON to the Remote Config service:
```json
{ "remoteconfig": { "template": "remote_config.json" } }
```
- Deploy: Execute the partial deployment command
```bash
npx -y firebase-tools@latest deploy --only remoteconfig
```
- **Verification**: After deployment, verify the update by listing the version
history.
```bash
npx -y firebase-tools@latest remoteconfig:versions:list
```
The SDK provides a number of features to make your application dynamic and
responsive to user segments.
- **Set In-App Defaults**: Define baseline values to ensure the app functions
offline or before the first fetch.
- **Fetch and Activate**: Retrieve values from the Firebase backend and apply
them to the local UI/Logic.
- **Template Management**: Use the Firebase CLI to version-control, get, and
deploy your config JSON files.
Referenced files: 2 — file references are metadata, not package contents.
firebase-security-rules-auditor3.82 KB
View saved version →
---
name: firebase-security-rules-auditor
description: >-
Audits Firebase (Firestore, Cloud Storage) security rules for vulnerabilities, privilege escalation, role bypasses, create vs update inconsistencies, resource exhaustion, type safety, size limits, and hasOnly ownership checks. Use when auditing/reviewing rules, running red-team rule assessments, or scoring against auditor checklists. Don't use for Firebase CLI (login, deploy), Auth, Crashlytics, Remote Config, or database queries.
metadata:
author: Google LLC
category: CloudSecurity
---
# Overview
This skill acts as an auditor for Firebase Security Rules, evaluating them
against a rigorous set of criteria to ensure they are secure, robust, and
correctly implemented.
# Scoring Criteria
## Assessment: Security Validator (Red Team Edition)
You are a Senior Security Auditor and Penetration Tester specializing in
Firestore. Your goal is to find "the hole in the wall." Do not assume a rule is
secure because it looks complex; instead, actively try to find a sequence of
operations to bypass it.
### Mandatory Audit Checklist:
1. **The Update Bypass:** Compare 'create' and 'update' rules. Can a user create
a valid document and then 'update' it into an invalid or malicious state
(e.g., changing their role, bypassing size limits, or corrupting data types)?
1. **Authority Source:** Does the security rely on user-provided data
(request.resource.data) for sensitive fields like 'role', 'isAdmin', or
'ownerId'? Carefully consider the source for that authority.
1. **Business Logic vs. Rules:** Does the rule set actually support the app's
purpose? (e.g., In a collaboration app, can collaborators actually read the
data? If not, the rules are "broken" or will force insecure workarounds).
1. **Storage Abuse:** Are there string length or array size limits? If not,
label it as a "Resource Exhaustion/DoS" risk.
1. **Type Safety:** Are fields checked with 'is string', 'is int', or 'is
timestamp'?
1. **Field-Level vs. Identity-Level Security:** Be careful with rules that use
`hasOnly()` or `diff()`. While these restrict *which* fields can be updated,
they do NOT restrict *who* can update them unless an ownership check (e.g.,
`resource.data.uid == request.auth.uid`) is also present. If a rule allows
any authenticated user to update fields on another user's document without a
corresponding ownership check, it is a data integrity vulnerability.
### Admin Bootstrapping & Privileges:
The admin bootstrapping process is limited in this app. If the rules use a
single hardcoded admin email (e.g., checking request.auth.token.email ==
'admin@example.com'), this should NOT count against the score as long as:
- email_verified is also checked (request.auth.token.email_verified == true).
- It is implemented in a way that does not allow additional admins to add
themselves or leave an escalation risk open.
### Scoring Criteria (1-5):
- **1 (Critical):** Unauthorized data access (leaks), privilege escalation, or
total validation bypass.
- **2 (Major):** Broken business logic, self-assigned roles, bypass of controls.
- **3 (Moderate):** PII exposure (e.g., public emails), Inconsistent validation
(create vs update) on critical fields
- **4 (Minor):** Problems that result in self-data corruption like update
bypasses that only impact the user's own data, lack of size limits, missing
minor type checks or over-permissive read access on non-sensitive fields.
- **5 (Secure):** Comprehensive validation, strict ownership, and role-based
access via secure ACLs.
Return your assessment in JSON format using the following structure:
```json
{
"score": 1,
"summary": "overall assessment",
"findings": [
{
"check": "checklist item",
"severity": "critical|major|moderate|minor",
"issue": "description",
"recommendation": "fix"
}
]
}
```
firestore-rules-creation27.4 KB
View saved version →
---
name: firestore-rules-creation
description: >-
Designs, authors, refactors, and hardens production-grade Cloud Firestore Security Rules (firestore.rules). IMPORTANT: If subagent delegation AND the firestore-rules-author subagent are available in your environment, delegate authoring firestore.rules to the firestore-rules-author subagent. If subagent delegation is unavailable (e.g. not enabled in the IDE), firestore-rules-author is not installed, or you are running inside firestore-rules-author, follow this skill directly.
metadata:
author: Google LLC
category: Databases
---
# Firestore Security Rules Creation
> [!IMPORTANT] **Subagent Delegation vs. Direct Authoring**
>
> - **If subagent delegation AND the `firestore-rules-author` subagent are
> available** in your active environment: **DO NOT** author `firestore.rules`
> directly in the main agent. Invoke the `firestore-rules-author` subagent and
> delegate the analysis and creation of `firestore.rules` to it.
> - **If subagent delegation is unavailable** (e.g., in IDE environments where
> subagent tools are not enabled) **OR the `firestore-rules-author` subagent
> is not installed**, **OR if you are already executing inside
> `firestore-rules-author`**: proceed with the workflow below to author
> `firestore.rules` directly.
You are an expert Firebase Security Rules engineer with deep knowledge of
Firestore security best practices. Your task is to generate comprehensive,
secure Firebase Security rules for the user's project. To minimize the risk of
security incidents and avoid misleading the user about the security of their
application, you must be extremely humble about the rules you generate. Always
present the rules you've written as a prototype that needs review.
After generating the rules, you MUST explicitly communicate to the user exactly
like this: "I've set up prototype Security Rules to keep the data in Firestore
safe. They are designed to be secure for <explain reasons here>. However, you
should review and verify them before broadly sharing your app. If you'd like, I
can help you harden these rules."
### Workflow
Follow this structured workflow strictly:
#### Phase-1: Codebase Analysis
1. **Scan the entire codebase** to identify:
- Programming language(s) used (for understanding context only)
- All Firestore collection and document paths
- **All Firestore Queries:** Identify every `where()`, `orderBy()`, and
`limit()` clause. The security rules **MUST** allow these specific queries.
- Data models and schemas (interfaces, classes, types)
- Data types for each field (strings, numbers, booleans, timestamps, URLs,
emails, etc.)
- Required vs. optional fields
- Field constraints (min/max length, format patterns, allowed values)
- CRUD operations (create, read, update, delete)
- Authentication patterns (Firebase Auth, custom tokens, anonymous)
- Access patterns and business logic rules
1. **Synthesize your findings** concisely (in memory; do not create extra
untracked scratch files in the workspace) and refer to them when generating
the security rules.
#### Phase-2: Security Rules Generation
**CRITICAL**: Follow the following principles **every time you modify the
security rules file**
Generate Firebase Security Rules following these principles:
- **Default deny:** Start with denying all access, then explicitly allow only
what's needed
- **Least privilege:** Grant minimum permissions required
- **Validate data:** Check data types, allowed fields, and constraints on both
creates and updates.
- **MANDATORY:** You **MUST** use the **Validator Function Pattern** described
in the "Critical Directives" section below. This involves defining a
specific validation function (e.g., `isValidUser`) and calling it in
**BOTH** `create` and `update` rules.
- **MANDATORY:** For **ALL** creates **AND ALL** updates, ensure that after
the operation, the required fields are still available and that the data is
valid.
- **Authentication checks:** Verify user identity before granting access
- **Authorization logic:** Implement role-based or ownership-based access
control
- **UID Protection:** Prevent users from changing ownership of data
- **Initially restricted:** Never make any collection or data publicly readable,
always require authentication for any access to data unless the user makes an
*explicit* request for unauthenticated data.
This means the first firestore.rules file you generate must never have any
"allow read: true" statements.
**Structure Requirements:**
1. **Document assumed data models at the beginning of the rules file:**
```javascript
// ===============================================================
// Assumed Data Model
// ===============================================================
//
// This security rules file assumes the following data structures:
//
// Collection: [name]
// Document ID: [pattern]
// Fields:
// - field1: type (required/optional, constraints) - description
// - field2: type (required/optional, constraints) - description
// [List all fields with types, constraints, and whether immutable]
//
// [Repeat for all collections]
//
// ===============================================================
```
1. **Include comprehensive helper functions to avoid repetition:**
```javascript
// ===============================================================
// Helper Functions
// ===============================================================
//
// Check if the user is authenticated
function isAuthenticated() {
return request.auth != null;
}
//
// Check if user owns the resource (for user-owned documents)
function isOwner(userId) {
return isAuthenticated() && request.auth.uid == userId;
}
//
// Check if user is owner based on document's uid field
function isDocOwner() {
return isAuthenticated() && request.auth.uid == resource.data.uid;
}
//
// Verify UID hasn't been tampered with on create
function uidUnchanged() {
return !('uid' in request.resource.data) ||
request.resource.data.uid == request.auth.uid;
}
//
// Ensure uid field is not modified on update
function uidNotModified() {
return !('uid' in request.resource.data) ||
request.resource.data.uid == resource.data.uid;
}
//
// Validate required fields exist
function hasRequiredFields(fields) {
return request.resource.data.keys().hasAll(fields);
}
//
// Validate string length
function validStringLength(field, minLen, maxLen) {
return request.resource.data[field] is string &&
request.resource.data[field].size() >= minLen &&
request.resource.data[field].size() <= maxLen;
}
//
// Validate URL format (must start with https:// or http://)
function isValidUrl(url) {
return url is string &&
(url.matches("^https://.*") || url.matches("^http://.*"));
}
//
// Validate email format
function isValidEmail(email) {
return email is string &&
email.matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");
}
//
// Validate ISO 8601 date string format (YYYY-MM-DDTHH:MM:SS)
// CRITICAL: This validates format ONLY, not logical date values (e.g., month 13).
// Use the 'timestamp' type for documents where logical date validation is required.
function isValidDateString(dateStr) {
return dateStr is string &&
dateStr.matches("^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}.*Z?$");
}
//
// Validate that a string path is correctly scoped to the user's ID
function isScopedPath(path) {
return path is string && path.matches("^users/" + request.auth.uid + "/.*");
}
//
// Validate that a value is positive
function isPositive(field) {
return request.resource.data[field] is number && request.resource.data[field] > 0;
}
//
// Validate that a list is a list and enforces size limits
function isValidList(list, maxSize) {
return list is list && list.size() <= maxSize;
}
//
// Validate optional string (if present, must be string and within length)
function isValidOptionalString(field, minLen, maxLen) {
return !(field in request.resource.data) ||
(request.resource.data[field] is string &&
request.resource.data[field].size() >= minLen &&
request.resource.data[field].size() <= maxLen);
}
//
// Validate that a map contains only allowed keys
function isValidMap(mapData, allowedKeys) {
return mapData is map && mapData.keys().hasOnly(allowedKeys);
}
//
// Validate that the document contains only the allowed fields
function hasOnlyAllowedFields(fields) {
return request.resource.data.keys().hasOnly(fields);
}
//
// Validate that the document hasn't changed in the fields that are not allowed to be changed
function areImmutableFieldsUnchanged(fields) {
return !request.resource.data.diff(resource.data).affectedKeys().hasAny(fields);
}
//
// Validate that a timestamp is recent (within the last 5 minutes)
function isRecent(time) {
return time is timestamp &&
time > request.time - duration.value(5, 'm') &&
time <= request.time;
}
//
// [Add more helper functions as needed for the data validation like the example below]
//
// ===============================================================
//
// Domain Validators (CRITICAL: Use these in both create and update)
//
// function isValidUser(data) {
// // Only allow admin to create admin roles
// return hasOnlyAllowedFields(['name', 'email', 'age', 'role']) &&
// data.name is string && data.name.size() > 0 && data.name.size() < 50 &&
// data.email is string && isValidEmail(data.email) &&
// data.age is number && data.age >= 18 &&
// data.role in ['admin', 'user', 'guest'];
// }
```
#### Mandatory: User Data Separation (The "No Mixed Content" Rule)
- Firestore security rules apply to the entire document. You cannot allow users
to read the displayName field while hiding the email field in the same
document.
- If a collection (e.g., users) contains ANY PII (email, phone, address, private
settings), you MUST strictly limit read access to the document owner only
(allow read: if isOwner(userId);).
- If the application requires public profiles (e.g., showing user names/avatars
on posts):
- 1. Denormalization (Preferred): Copy the user's public info (name, photoURL)
directly onto the resources they create (e.g., store authorName and
authorPhoto inside the posts document).
- 2. Split Collections: Create a separate users_public collection that
contains only non-sensitive data, and keep the sensitive data in a
locked-down users_private collection.
- NEVER write a rule that allows read access to a document containing PII for
anyone other than the owner.
#### **CRITICAL** RBAC Guidelines
This is one of the most important set of instructions to follow. Failing to
follow these rules will result in catastrophic security vulnerabilities.
- **NEVER** allow users to create their own privileged roles. That means that no
user should be able to create an item in a database with their role set to a
role similar to "admin" unless they are already a bootstrapped admin.
- **NEVER** allow users to update their own roles or permissions.
- **NEVER** allow users to grant themselves access to other users' data.
- **NEVER** allow users to bypass the role hierarchy.
- **ALWAYS** validate that the user is authorized to perform the requested
action.
- **ALWAYS** validate that the user is not attempting to escalate their
privileges.
- **ALWAYS** validate that the user is not attempting to access data they do not
have permission to access.
Here's a **bad** example of what **NOT** to do:
```javascript
match /users/{userId} {
// BAD: Allows users to create their own roles because a user can create a new user document with a role of 'admin' and the isAdmin() function will return true
allow create: if (isOwner(userId) && isValidUser(request.resource.data)) || isAdmin();
// BAD: Allows users to update their own roles because a user can update their own user document with a role of 'admin' and the isAdmin() function will return true
allow update: if (isOwner(userId) && isValidUser(request.resource.data)) || isAdmin();
}
```
Here's a **good** example of what **TO** do:
```javascript
match /users/{userId} {
// GOOD: Does NOT allow users to create their own roles unless they are an admin or the user is updating their own role to a less privileged role
allow create: if isAuthenticated() && isValidUser(request.resource.data) && ((isOwner(userId) && request.resource.data.role == 'client') || isAdmin());
// GOOD: Does NOT allow users to update their own roles unless they are an admin
allow update: if isAuthenticated() && isValidUser(request.resource.data) && ((isOwner(userId) && request.resource.data.role == resource.data.role) || isAdmin());
}
```
#### Critical Directives for Secure Generation
- **PREFER USING READ OVER LIST OR GET** `list` and `get` can add complexity to
security rules. Prefer using `read` over them.
- **Date and Timestamp Validation:**
- **Prefer Timestamps:** ALWAYS prefer the `timestamp` type for date fields.
Firestore automatically ensures they are logically valid dates.
- **String Date Risks:** If using strings for dates (e.g., ISO 8601), a regex
check like `isValidDateString` only validates **format**, not **logic** (it
would accept Feb 31st).
- **Regex Escaping:** When using regex for digits, you **MUST** use double
backslashes (e.g., `\\\\d`) in the rules string. Using a single backslash
(`\\d`) is a common bug that causes validation to fail.
- **Immutable Fields:** Fields like `createdAt`, `authorUID`, or any other field
that should not change after creation must be explicitly protected in `update`
rules. (e.g., `request.resource.data.createdAt == resource.data.createdAt`).
**CRITICAL**: When allowing non-owners to update specific fields (like
incrementing a counter), you **MUST** explicitly verify that all other fields
(e.g., `authorName`, `tags`, `body`) remain unchanged to prevent unauthorized
metadata modification. For sensitive fields, ensure that the logged in user is
also the owner of the document.
- **Identity Integrity:** When storing denormalized user identity (e.g.
`authorName`, `authorPhoto`), you **MUST** validate this data.
- **Prefer Auth Token:** If possible, check if
`request.resource.data.authorName == request.auth.token.name`.
- **Strict Validation:** If the auth token is unavailable, you **MUST**
strictly validate the type (string) and length (e.g. < 50 chars) to prevent
spoofing with massive or malicious payloads.
- **Client-Side Fetching:** The most secure pattern is to store ONLY
`authorUid` and fetch the profile client-side. If you denormalize, you
accept the risk of stale or spoofed data unless you validate it.
- **Enforce Strict Schema (No Extraneous Fields):** Documents must not contain
any fields other than those explicitly defined in the data model. This
prevents users from adding arbitrary data.
- **NEVER allow PII EXPOSURE LEAKS:** Never allow PII (Personally Identifiable
Information) to be exposed in the data model. This includes email addresses,
phone numbers, and any other information that could be used to identify a
user. For example, even if a user is logged-in, they should not have access to
read another user's information.
- **No Blanket User Read Access:** You are strictly FORBIDDEN from generating
`allow read: if isAuthenticated();` for the users collection if that
collection is defined to contain email addresses or other private data.
- **CRITICAL: Double-Check Blanket `isAuthenticated` fields:** Ensure that paths
that are protected with only `isAuthenticated()` do not need any additional
checks based on role or any other condition.
- **The "Ownership-Only Update" Trap:** A common critical vulnerability is
allowing updates based solely on ownership (e.g.,
`allow update: if isOwner(resource.data.uid);`). This allows the owner to
corrupt the data schema, delete required fields, or inject malicious payloads.
You **MUST** always combine ownership checks with data validation (e.g.,
`allow update: if isOwner(...) && isValidEntity(...);`) **AND** validate that
self-escalation is not possible.
- **Deep Array Inspection:** It is insufficient to check if a field `is list`.
You **MUST** validate the contents of the array (e.g., ensuring all elements
are strings of a valid UID length) to prevent data corruption or schema
pollution. For example, a `tags` array must verify that every item is a string
AND that each string is within a reasonable length (e.g., < 20 chars).
- **Permission-Field Lockdown:** Fields that control access (e.g., `editors`,
`viewers`, `roles`, `role`, `ownerId`) **MUST** be immutable for non-owner
editors. In `update` rules, use `areImmutableFieldsUnchanged()` for these
fields unless the `request.auth.uid` matches the document's original
owner/creator. This prevents "Permission Escalation" where a collaborator
could grant themselves higher privileges or remove the owner.
### Advanced Validation for Business Logic
Secure rules must enforce the application's business logic. This includes
validating field values against a list of allowed options and controlling how
and when fields can change.
#### 1. Enforce Enum Values
If a field should only contain specific values (e.g., a status), validate
against a list.
**Example:**
```javascript
// A 'task' document's status can only be one of three values
function isValidStatus() {
let validStatuses = ['pending', 'in-progress', 'completed'];
return request.resource.data.status in validStatuses;
}
allow create: if isValidStatus() && ...
```
#### 2. Validate State Transitions
For `update` operations, you **MUST** validate that a field is changing from a
valid previous state to a valid new state. This prevents users from bypassing
workflows (e.g., marking a task as 'completed' from 'archived').
**Example:**
```javascript
// A task can only be marked 'completed' if it was 'in-progress'
function validStatusTransition() {
let previousStatus = resource.data.status;
let newStatus = request.resource.data.status;
return (previousStatus == 'in-progress' && newStatus == 'completed') ||
(previousStatus == 'pending' && newStatus == 'in-progress');
}
allow update: if validStatusTransition() && ...
```
#### 3. Strict Path and Relationship Scoping
For any field that references another resource (like an image path or a parent
document ID), you **MUST** ensure it is correctly scoped to the user or valid
within the context.
**Example:**
```javascript
// Ensure image path is within the user's own storage folder
allow create: if isScopedPath(request.resource.data.imageBucket) && ...
```
#### 4. Secure Counter Updates
When allowing users to update a counter (like `voteCount` or `answerCount`), you
**MUST** ensure: 1. **Atomic Increments:** The field is only changing by exactly
+1 or -1. 2. **Isolation:** **NO OTHER FIELDS** are being modified. This is
critical to prevent attackers from hijacking the `authorName` or `content` while
"voting". 3. **Action Verification:** You **MUST** prevent users from
artificially inflating counts. When incrementing a counter, verify that the user
has not already performed the action (e.g., by checking for the existence of a
'like' document) and is not looping updates. * **CRITICAL:** Relying solely on
`!exists(likeDoc)` is insufficient because a malicious user can skip creating
the document and loop the increment. * **SOLUTION:** Use `getAfter()` to verify
that the corresponding tracking document *will exist* after the batch completes.
**Example:**
```javascript
function isValidCounterUpdate(docId) {
// Allow update only if 'voteCount' is the ONLY field changing
return request.resource.data.diff(resource.data).affectedKeys().hasOnly(['voteCount']) &&
// And the change is exactly +1 or -1
math.abs(request.resource.data.voteCount - resource.data.voteCount) == 1 &&
// Verify consistency:
(
// Increment: Vote must NOT exist before, but MUST exist after
(request.resource.data.voteCount > resource.data.voteCount &&
!exists(/databases/$(database)/documents/votes/$(request.auth.uid + '_' + docId)) &&
getAfter(/databases/$(database)/documents/votes/$(request.auth.uid + '_' + docId)) != null) ||
// Decrement: Vote MUST exist before, but must NOT exist after
(request.resource.data.voteCount < resource.data.voteCount &&
exists(/databases/$(database)/documents/votes/$(request.auth.uid + '_' + docId)) &&
getAfter(/databases/$(database)/documents/votes/$(request.auth.uid + '_' + docId)) == null)
);
}
allow update: if isValidCounterUpdate(docId) && ...
```
#### 5. **CRITICAL** Ensure Application Validity
While updating the firestore rules, also ensure that the application still works
after firestore rules updates.
1. **For each collection, implement explicit data validation:**
- Type Checking: 'field is string', 'field is number', 'field is bool', 'field
is timestamp'
- Required fields validation using 'hasRequiredFields()'
- **Enforce Size Limits:** For **EVERY** string, list, and map field, you
**MUST** enforce realistic size limits (e.g., `text.size() < 1000`,
`tags.size() < 20`). **Failure to limit a single string field (like `caption`
or `bio`) allows 1MB attacks, which is a CRITICAL vulnerability.**
- URL validation using 'isValidUrl()' for URL fields
- Email validation using 'isValidEmail()' for email fields
- **Immutable field protection** (authorId, createdAt, etc. should not change on
update)
- **UID protection** using 'uidUnchanged()' on creates and 'uidNotModified()' on
updates should be accompanied with `isDocOwner()`
- **Temporal accuracy** using `isRecent()` for timestamps.
- **Range validation** using `isPositive()` or similar for numbers.
- **Path scoping** using `isScopedPath()` for storage paths.
Structure your rules clearly with comments explaining each rule's purpose.
#### Phase-3: Devil's Advocate Attack
**Critical step:** Systematically attempt to break your own rules using the
following attack vectors. You MUST document the outcome of each attempt.
1. **Public List Exploit:** Can I run a collection query without authentication
and retrieve documents that should be private (e.g., where
`visible == false`)?
1. **Unauthorized Read/Write:** Can I `get`, `create`, `update`, or `delete` a
document that I do not own or have permissions for?
1. **The "Update Bypass":** Can I `create` a valid document and then `update` it
with a 1MB string or invalid fields? (Tests if validation logic is missing
from `update`).
1. **Ownership Hijacking (Create):** Can I create a document and set the
`authorUID` or `ownerId` to another user's ID?
1. **Ownership Hijacking (Update):** Can I `update` an existing document to
change its `authorUID` or `ownerId`?
1. **Immutable Field Modification:** Can I change a `createdAt` or other
immutable timestamp or property on an `update`?
1. **Data Corruption (Type Juggling):** Can I write a `number` to a field that
should be a `string`, or a `string` to a `timestamp`?
1. **Validation Bypass (Create vs. Update):** Can I `create` a valid document
and then `update` it into an invalid state (e.g., remove a required field,
write a string that's too long)?
1. **Resource Exhaustion / DoS:** Can I write an enormous string (e.g., 1MB) to
any field that accepts a string or a massive array to a list field? Every
string field (e.g., `bio`, `url`, `name`) MUST have a `.size()` check. If any
are missing, it's a "Resource Exhaustion/DoS" risk.
1. **Required Field Omission:** Can I `create` or `update` a document while
omitting fields that are marked as required in the data model?
1. **Privilege Escalation:** Can I create an account and assign myself an admin
role by writing `isAdmin: true` to my user profile document? (Tests reliance
on document data vs. custom claims).
1. **Schema Pollution:** Can I `create` or `update` a document and add an
arbitrary, undefined field like `extraData: 'malicious_code'`? (Tests for
strict schema enforcement).
1. **Invalid State Transition:** Can I update a document's `status` field from
`'pending'` directly to `'completed'`, bypassing the required `'in-progress'`
state? (Tests business logic enforcement).
1. **Path Traversal / Scoping Attack:** Can I set a path field (like
`imageBucket` or `profilePic`) to a value that points to another user's data
or a restricted area? (Tests for regex path scoping).
1. **Timestamp Manipulation:** Can I set a `createdAt` field to the past or
future to bypass sorting or logic? (Tests for `request.time` validation).
1. **Negative Value / Overflow:** Can I set a numeric field (like `price` or
`quantity`) to a negative number or an extremely large one? (Tests for range
validation).
1. **The "Mixed Content" Leak:** Create a second user. Can User B read User A's
users document? If "Yes" (because you wanted public profiles), does that
document also contain User A's email or private keys? If both are true, the
rules are insecure.
1. **Counter/Action Replay:** If there is a counter (like `likesCount`), can I
increment it without creating the corresponding tracking document (e.g.,
inside `likes/{userId}`)? Can I increment it twice? (Tests for `getAfter()`
consistency checks).
1. **Orphaned Subcollection Access:** Can I read/write to a subcollection (e.g.,
`users/123/posts/456`) if the parent document (`users/123`) does not exist?
(Tests for parent existence checks).
1. **Query Mismatch:** Do the rules actually allow the queries the app performs?
(e.g., if the app filters by `status == 'published'`, do the rules allow
`list` only when `resource.data.status == 'published'`?)
1. **Validator Pattern Check:** Do **ALL** `update` rules (including owner-only
ones) call the `isValidX()` function? If an `allow update` rule only checks
`isOwner()`, it is a CRITICAL vulnerability.
Evaluate each attack attempt mentally (do not create separate untracked
attack-log files). If ANY attack succeeds:
- Fix the security hole
- Regenerate the rules
- **Repeat Phase-3** until no attacks succeed
#### Phase-4: Syntactic Validation
Once devil's advocate testing passes, repeat until rules pass validation.
**After all phases are complete, create or update the `firestore.rules` file.**
### Critical Constraints
1. **Never skip the devil's advocate phase** - this is your primary security
validation
1. **MUST include helper functions** for common operations ('isAuthenticated',
'isOwner', 'uidUnchanged', 'uidNotModified') AND domain validators
('isValidUser', etc.)
1. **MUST document assumed data models** at the beginning of the rules file
1. **Always validate the rules syntax** using 'firebase deploy --only
firestore:rules --dry-run' or a similar tool before outputting the final
file.
1. **Provide complete, runnable code** - no placeholders or TODOs
1. **Document all assumptions** about data structure or access patterns
1. **Always run the devil's advocate attack** after any modification of the
rules.
1. **Determine whether the rules need to be updated** after permission denied
errors occur.
1. **Do not make overly confident guarantees of the security of rules that you
have generated**. It is very difficult to exhaustively guarantee that there
are no vulnerabilities in a rules set, and it is vital to not mislead users
into thinking that their rules are perfect. After an initial rules
generation, you should describe the rules you've written as a solid
prototype, and tell users that before they launch their app to a large
audience, they should work with you to harden and validate the rules file. Be
clear that users should carefully review rules to ensure security.
xcode-project-setup5.99 KB
View saved version →
---
name: xcode-project-setup
description: Safely modifies Xcode projects (.pbxproj) to add Swift Packages and link files. Use this skill whenever an iOS project needs dependencies installed (e.g. Firebase, Alamofire).
compatibility: Requires Swift to be installed locally and macOS environment.
metadata:
author: Google LLC
category: ApplicationDevelopment
---
# Xcode Project Setup
## ⛔️ CRITICAL RULES & ENVIRONMENT CHECKS
Before performing any Xcode setup or file manipulation, you **MUST** adhere to
the following rules. A hefty fee will be applied if you violate them.
### 1. The Anti-Ruby Mandate
You are **strictly forbidden** from using Ruby, Rails, or any Ruby gems
(including the `xcodeproj` gem). Under no circumstances may you write or execute
Ruby scripts.
### 2. Modern Xcode Folder Synchronization
Modern Xcode projects support folder synchronization. When adding new source
code (`.swift`) or resource files, simply write them to the correct directory on
disk. They will be automatically included in the Xcode project. **Never manually
modify the `.pbxproj` file to add files.**
### 3. Allowed Scripting Languages
If you absolutely must write a script to manipulate the project environment
(e.g., configuring SPM packages beyond what the provided `xcode_spm_setup`
script does), you **must use Swift**. Only as an absolute last resort, if Swift
is completely unviable, may you use Node.js or TypeScript.
### 4. Toolchain Verification
Because this skill relies entirely on a native Swift script, you must verify the
environment:
- Run `swift --version` before proceeding.
- If the Swift command is not found, you must stop and recommend the user
install the Swift toolchain (e.g., via `xcode-select --install` on macOS), or
ask if you can attempt to install it for them. Do not attempt to proceed
without Swift.
### 5. Mandatory Linker Flags for Static Frameworks (Firebase)
When setting up SPM dependencies that heavily rely on internal Objective-C
categories and `+load` methods (such as the Firebase iOS SDK suite), the Apple
linker will aggressively strip these methods out if they are linked statically.
This causes fatal runtime crashes (e.g.,
`FirebaseAuth/Auth.swift:167: Fatal error: Unexpectedly found nil`).
**The provided `xcode_spm_setup` Swift script automatically injects the `-ObjC`
flag to `OTHER_LDFLAGS` when adding Firebase products.** However, you should
still verify it is present in the build settings if you encounter issues.
- Failing to include this flag when adding Firebase dependencies is a critical
error.
______________________________________________________________________
## Empty Directory Workflow
If you are asked to build an iOS app or configure Xcode dependencies but **no
`.xcodeproj` or `.xcworkspace` exists**, you MUST ask the user to create the
project first:
**"No Xcode project found in this directory. Please create an empty Xcode
project manually and let me know when you are ready to proceed."**
Wait for the user to confirm they have created the `.xcodeproj` via Xcode, then
proceed with the Standard Xcode Workflow below.
______________________________________________________________________
## Standard Xcode Workflow
Do not use raw text parsing, `sed`, or Ruby scripts to modify `.pbxproj` files
directly.
Instead, execute the Swift configuration package bundled with this skill
(`scripts/xcode_spm_setup`) to securely install SPM packages and link optional
config files (like `GoogleService-Info.plist`).
### **CRITICAL: Always Use Latest SDK Version**
To ensure access to the latest features and security fixes, always use the most
recent version of the Firebase iOS SDK. Check for the latest release version at
[https://github.com/firebase/firebase-ios-sdk/releases](https://github.com/firebase/firebase-ios-sdk/releases).
- Use the most recent version number (e.g., `11.x.y`) in your commands instead
of hardcoded placeholders.
### Understanding the Script's Actions
When adding a Swift Package to an Xcode project, two distinct steps must occur:
1. Adding the package repository dependency (e.g.,
`https://github.com/Alamofire/Alamofire`).
1. Selecting the target (e.g., `MyApp`), navigating to **General > Frameworks,
Libraries, and Embedded Content**, and hitting the `+` button to explicitly
link the specific product modules (e.g., `Alamofire`).
**The provided `xcode_spm_setup` Swift script automatically handles BOTH of
these steps for you.** By passing the list of modules as arguments, it safely
injects the package dependency and automatically wires those modules to the main
target's Frameworks build phase. You do not need to do any manual linking.
## Usage
1. **Locate the package path:** Find the absolute path to this skill's
`scripts/xcode_spm_setup` directory on disk.
1. **Execute:** Run the native `swift run` command using the signature below:
```bash
swift run --package-path <PATH_TO_SKILL>/scripts/xcode_spm_setup xcode_spm_setup <ProjectPath.xcodeproj> <RepoURL> <VersionRequirement> [--plist <Optional/Path/To/Config.plist>] <Product1> [Product2 ...]
```
### Example 1: Generic Package (e.g., Alamofire)
Adding Alamofire to a standard Xcode project. Notice there is no `--plist` flag.
```bash
swift run --package-path /Users/foo/.agents/skills/xcode-project-setup/scripts/xcode_spm_setup xcode_spm_setup MyApp.xcodeproj https://github.com/Alamofire/Alamofire 5.8.1 Alamofire
```
### Example 2: Firebase (Requires Plist)
Adding Firebase and linking the `GoogleService-Info.plist` to the resources
build phase automatically. *Note: Replace `11.0.0` with the actual latest
version from
[the releases page](https://github.com/firebase/firebase-ios-sdk/releases).*
```bash
swift run --package-path /Users/foo/.agents/skills/xcode-project-setup/scripts/xcode_spm_setup xcode_spm_setup MyApp.xcodeproj https://github.com/firebase/firebase-ios-sdk 11.0.0 --plist MyApp/GoogleService-Info.plist FirebaseCore FirebaseAuth FirebaseFirestore
```
*Note: The script is idempotent. It will automatically skip linking files or
packages that are already present in the project.*
Referenced files: 4 — file references are metadata, not package contents.