Firebase Agent Skills

repository·main·Indexed 18 days ago

https://github.com/firebase/agent-skills

A collection of packaged instructions and scripts designed to help AI coding agents interact with Firebase. It provides installation guides for the Agent Skills CLI, Gemini CLI, Claude, Codex, Kimi Code, and manual setup for Cursor, Windsurf, and GitHub Copilot. The documentation includes details on the Firebase MCP server for managing services like Firestore, Authentication, and Cloud Functions, as well as technical guidance on migrating Firebase Functions from V1 to V2 using the Destructuring Compatibility Shim.

Tokens
98.7K
Snippets
311
Records
413
Agent score
61%

What's inside Firebase Agent Skills

  1. Overview of the firebase-crashlytics skill

    main

    The firebase-crashlytics skill is a comprehensive guide for provisioning and using Firebase Crashlytics on Android and iOS. It is designed to help users set up crash reporting, add custom debugging data, and read collected crash data.

    Compatibility Note: While this skill is best used with the Firebase CLI, it does not strictly require it. You can access the Firebase CLI via npx -y firebase-tools@latest.

  2. Overview of Firebase services available via MCP

    main

    The Firebase MCP server provides an AI assistant with capabilities to manage and interact with the following core services:

    • Authentication: User management, sign-in methods, and custom claims.
    • Firestore: NoSQL document database with real-time sync.
    • App Hosting: Full-stack app deployment with SSR.
    • Storage: File storage and serving.
    • Cloud Functions: Serverless backend code.
    • Hosting: Web app deployment to a global CDN.
    • Cloud Messaging: Push notifications (FCM).
    • Remote Config: Dynamic app configuration.
    • Crashlytics: Crash reporting and analysis.
  3. Core AI Capabilities in Firebase AI Logic

    main

    Firebase AI Logic provides several key generative AI features via client-side SDKs:

    • Text-Only Generation: Standard text prompts and responses.
    • Multimodal Inference: Analyze text combined with images, audio, video, or PDFs.
      • Tip: For files larger than 20MB, store them in Cloud Storage for Firebase and pass the URL instead of using inline data to avoid HTTP 413 errors.
    • Chat Sessions: Use startChat to maintain multi-turn conversation history automatically.
    • Streaming Responses: Use generateContentStream instead of generateContent to provide a better UX (e.g., a typing effect) by displaying partial results as they arrive.
    • Image Generation: Use the Nano Banana models to generate images (requires an upgraded Blaze pay-as-you-go plan).
    • Search Grounding: Use the built-in googleSearch tool to ground responses in Google Search.
    • Structured Output: Enforce specific JSON schemas for model responses.
    • On-Device AI (Hybrid): For web apps, the JavaScript SDK can automatically switch between on-device execution (using Gemini Nano in Chrome) and cloud-hosted execution.
  4. Use the firebase-security-rules-auditor skill

    main

    The firebase-security-rules-auditor skill is designed to audit Firebase (Firestore, Cloud Storage) security rules for vulnerabilities such as privilege escalation, role bypasses, resource exhaustion, and type safety inconsistencies.

    When to use:

    • Auditing or reviewing security rules.
    • Running red-team rule assessments.
    • Scoring rules against auditor checklists.

    When NOT to use:

    • Firebase CLI operations (login, deploy).
    • Firebase Auth, Crashlytics, Remote Config, or database queries.
  5. Understand Firebase SQL Connect (formerly Data Connect)

    main
    Firebase SQL Connect is a relational database service that uses Cloud SQL for PostgreSQL. It provides a GraphQL schema, auto-generated queries and mutations, and type-safe SDKs. It is designed for use cases requiring relational data structures, tables, and relationships within the Firebase ecosystem.
  6. Core Concepts of Firebase Authentication

    main

    Firebase Authentication provides backend services and SDKs to manage user identity.

    Users

    Every user is identified by a unique uid. Key user properties include:

    • uid: Unique identifier.
    • email: User's email address.
    • displayName: User's display name.
    • photoURL: URL to user's photo.
    • emailVerified: Boolean indicating if the email is verified.

    Identity Providers

    Firebase supports several sign-in methods:

    • Email/Password: Standard email/password auth.
    • Federated Identity Providers: Google, Facebook, Twitter, GitHub, Microsoft, Apple, etc. (Google Sign-In is the recommended default).
    • Phone Number: SMS-based auth.
    • Anonymous: Temporary accounts that can be linked to permanent ones later.
    • Custom Auth: Integration with existing external auth systems.

    Tokens

    Upon sign-in, users receive tokens used to authenticate requests to Firebase services (Firestore, Storage, etc.) or custom backends:

    • ID Token: A short-lived (1 hour) JWT used to verify identity.
    • Refresh Token: A long-lived token used to obtain new ID tokens.
  7. Query across multiple subcollections using Collection Groups

    main

    By default, queries target a single collection. If you have multiple subcollections with the same ID (e.g., every user has a messages subcollection), you can use a collection group query to search across all of them simultaneously.

    • Standard Query: Targets a specific path to find documents within one collection.
    • Collection Group Query: Uses collectionGroup() to find documents with a specific collection ID regardless of where they sit in the hierarchy.
    // Standard Query: Find all 5-star reviews for a specific landmark
    db.collection('landmarks/golden_gate_bridge/reviews').where('rating', '==', 5)
    
    // Collection Group Query: Find all 5-star reviews across ALL landmarks
    db.collectionGroup('reviews').where('rating', '==', 5)
  8. When to use Native SQL instead of GraphQL

    main

    Always default to Native GraphQL. Use Native SQL only when you need database-specific features not available in GraphQL, such as:

    • PostGIS
    • Window Functions
    • Complex Aggregations
    • Specific DML Common Table Expressions (CTEs)

    When using Native SQL, you bypass GraphQL's strong typing and interact directly with PostgreSQL. This means queries return the generic Any scalar type, and client-side SDKs (TypeScript, Swift, Kotlin, Dart) will type these results as any or equivalent. You must manually cast or validate the data shape in your client-side code.

  9. Automatic entity refresh for single-entity lookups

    main

    SQL Connect automatically refreshes queries that fetch a single entity by its primary key (e.g., movie(id: $id) or user(key: { uid: $uid })). No @refresh directive is required.

    Supported Triggering Operations:

    • _insert(data) or _insertMany(data)
    • _upsert(data) or _upsertMany(data)
    • _update(id) or _update(key)
    • _delete(id) or _delete(key)

    Important Limitations:

    • Bulk operations like _updateMany and _deleteMany do not trigger automatic refreshes.
    • List queries, nested queries with JOINs, aggregations, and native SQL do not qualify for automatic refresh and require explicit @refresh directives.

    To consume these automatic updates, use the subscribe() method on the client.

    # When subscribed to, this query auto-refreshes when movie data changes — no @refresh needed
    query GetMovie($id: UUID!) @auth(level: PUBLIC) {
      movie(id: $id) {
        id title rating description
        reviews_on_movie { rating text user { displayName } }
      }
    }
  10. Rules for Native SQL Syntax and Parameters

    main

    Native SQL operations in .gql files must follow strict parsing rules to ensure security and prevent SQL injection:

    • String Literals: The sql argument must be a hardcoded string literal block using triple quotes (e.g., sql: """SELECT...""""). It cannot be a GraphQL variable.
    • Parameters: Use strict positional parameters ($1, $2, etc.) that correspond to the order of the params array. Named parameters (like $id or :name) are forbidden.
    • Comments: Use only block comments (/* ... */). Line comments (--) are forbidden as they can truncate query clauses during compilation. If you comment out a parameter in a SQL block, you must also remove it from the params list.
    • Context Maps (_expr): Variables cannot be used inside _expr fields. These must be static strings (e.g., {_expr: "auth.uid"}).
    • DDL: Do not use Data Definition Language (DDL) in operations. Use the schema.gql file for table or column changes.
    • Query Constraints: query operations cannot contain DML and must start with SELECT, TABLE, or WITH.
  11. Work with auto-generated Key scalars

    main

    Key scalars (e.g., Movie_Key, User_Key) are auto-generated types representing primary keys. They are used to uniquely identify records and are returned by insertion mutations.

    Using a Key in a Query

    Keys can be passed as variables. The format is an object containing the primary key fields.

    # Query using a Key scalar
    query GetMovie($key: Movie_Key!) @auth(level: PUBLIC) {
      movie(key: $key) { title }
    }
    
    # Variable format for a single-field key:
    # { "key": { "id": "uuid-here" } }
    
    # Variable format for a composite key:
    # { "key": { "movieId": "...", "userId": "..." } }

    Retrieving a Key from a Mutation

    Mutations like _insert return the generated key for the new record.

    mutation CreateAndFetch($title: String!) @auth(level: USER) {
      key: movie_insert(data: { title: $title })
      # Returns: { "key": { "id": "generated-uuid" } }
    }
    query GetMovie($key: Movie_Key!) @auth(level: PUBLIC) {
      movie(key: $key) { title }
    }
  12. Implement Realtime Queries with @refresh

    main

    Firebase Data Connect supports realtime updates using the @refresh directive on queries. You can trigger refreshes based on specific mutations, conditions, or time intervals.

    Refresh Strategies:

    1. Mutation-driven: Refresh when a specific operation is executed.

      • Use onMutationExecuted: { operation: "OperationName" }.
      • Use condition to filter refreshes based on mutation variables or auth context (e.g., mutation.variables.genre == request.variables.genre).
    2. Time-based: Refresh at a fixed interval.

      • Use every: { seconds: N }.
    3. Automatic: Single-entity lookups (e.g., movie(id: $id)) refresh automatically when that specific entity is modified by a mutation, without needing an explicit @refresh directive.

    # Refresh when a specific mutation is called with matching variables
    query ListMoviesByGenre($genre: String!) @auth(level: PUBLIC)
      @refresh(onMutationExecuted: {
        operation: "AddMovieWithGenre",
        condition: "mutation.variables.genre == request.variables.genre"
      }) {
      movies(where: { genre: { eq: $genre } }) { id title }
    }
    
    # Refresh every 30 seconds
    query MovieLeaderboard
      @auth(level: PUBLIC)
      @refresh(every: { seconds: 30 }) {
      movies(orderBy: [{ rating: DESC }], limit: 10) {
        id title rating
      }
    }