Agent skill

Firebase

by alinaqi in alinaqi/maggy

Firebase Firestore, Auth, Storage, real-time listeners, security rules

MITAuto-check passedDatabases

Install Firebase

skills CLI
$ npx skills add alinaqi/maggy --skill firebase -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install alinaqi/maggy firebase --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/alinaqi/maggy.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/firebase .claude/skills/firebase && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
firebase
GitHub stars
707
Token cost
~4.6k tokens
SKILL.md length
232 words
Files
1
Skills in repo
71
Repo updated
First seen
Licence
MIT

At a glance

Firebase Firestore, Auth, Storage, real-time listeners, security rules

  • Databases work in your project
  • SKILL.md covers Core Principle, Firebase Stack, Project Setup and Firestore Data Modeling, plus 6 more sections
  • Calls firebase and npm; needs NEXT_PUBLIC_FIREBASE_API_KEY

What it does

Firebase is an agent skill from alinaqi/maggy. Firebase Firestore, Auth, Storage, real-time listeners, security rules

Its SKILL.md is about 4.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Databases. It works with Firebase and Cloud Firestore. The repository describes itself as: What started as an opinionated Claude Code setup kit is now an autonomous AI engineering command center. The licence is MIT.

When your agent uses it

  • Databases work in your project

Example prompts

  • “/firebase”

Requirements

  • Node.js
  • A credential in NEXT_PUBLIC_FIREBASE_API_KEY

What it can do on your machine

Read from SKILL.md and the folder at commit 72a456e. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • firebase
    • npm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • firebase.google.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • NEXT_PUBLIC_FIREBASE_API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Firebase loads about 4.6k tokens when it runs. Until then it costs about 20 tokens; SKILL.md has 232 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~20
When it runs · the whole SKILL.md, loaded when a task matches
~4.6k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from alinaqi/maggy at commit 72a456e, republished under its MIT licence (© alinaqi). 232 words, ~4,583 tokens.

Download SKILL.mdSave it as .claude/skills/firebase/SKILL.md (or your agent's skills folder).
name
firebase
description
Firebase Firestore, Auth, Storage, real-time listeners, security rules
when-to-use
When working with Firebase services
user-invocable
false
paths
**/firebase*, firestore.rules, storage.rules, firebase.json
effort
medium

Firebase Skill

Firebase/Firestore patterns for web and mobile applications with real-time data, offline support, and security rules.

Sources: Firebase Docs | Firestore Best Practices | Security Rules


Core Principle

Denormalize with purpose, secure with rules, scale horizontally.

Firestore is a document database - embrace denormalization for read efficiency. Security rules are your server-side validation. Design for your access patterns.


Firebase Stack

ServicePurpose
FirestoreNoSQL document database with real-time sync
AuthenticationUser auth, OAuth, anonymous sessions
StorageFile uploads with security rules
FunctionsServerless backend (Node.js)
HostingStatic site + CDN
ExtensionsPre-built solutions (Stripe, Algolia, etc.)

Project Setup

Install Firebase CLI
bash
# Install globally
npm install -g firebase-tools

# Login
firebase login

# Initialize in project
firebase init
Initialize with Emulators
bash
firebase init emulators

# Start local development
firebase emulators:start
Project Structure
project/
├── firebase.json           # Firebase config
├── firestore.rules         # Security rules
├── firestore.indexes.json  # Composite indexes
├── storage.rules           # Storage security rules
└── functions/              # Cloud Functions
    ├── src/
    ├── package.json
    └── tsconfig.json

Firestore Data Modeling

Document Structure
typescript
// Good: Flat documents with all needed data
interface Post {
  id: string;
  title: string;
  content: string;
  authorId: string;
  authorName: string;      // Denormalized for display
  authorAvatar: string;    // Denormalized
  tags: string[];
  likeCount: number;       // Aggregated counter
  createdAt: Timestamp;
  updatedAt: Timestamp;
}

// Collection: posts/{postId}
When to Use Subcollections
typescript
// Use subcollections for:
// 1. Unbounded lists (comments, messages)
// 2. Data with different access patterns
// 3. Data that grows independently

// posts/{postId}/comments/{commentId}
interface Comment {
  id: string;
  text: string;
  authorId: string;
  authorName: string;
  createdAt: Timestamp;
}
Data Model Patterns
typescript
// Pattern 1: Embedded data (bounded, always needed)
interface User {
  id: string;
  email: string;
  profile: {
    displayName: string;
    bio: string;
    avatar: string;
  };
  settings: {
    notifications: boolean;
    theme: 'light' | 'dark';
  };
}

// Pattern 2: Reference with denormalization
interface Order {
  id: string;
  userId: string;
  userEmail: string;  // Denormalized for display
  items: OrderItem[]; // Embedded (bounded)
  total: number;
  status: 'pending' | 'paid' | 'shipped';
}

// Pattern 3: Aggregation documents
// Keep counters in parent document
interface Channel {
  id: string;
  name: string;
  memberCount: number;  // Updated via Cloud Function
  messageCount: number;
}

TypeScript SDK (Modular v9+)

Initialize Firebase
typescript
// lib/firebase.ts
import { initializeApp, getApps } from 'firebase/app';
import { getFirestore, connectFirestoreEmulator } from 'firebase/firestore';
import { getAuth, connectAuthEmulator } from 'firebase/auth';
import { getStorage, connectStorageEmulator } from 'firebase/storage';

const firebaseConfig = {
  apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
  authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
  projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
  storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID
};

// Initialize only once
const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0];

export const db = getFirestore(app);
export const auth = getAuth(app);
export const storage = getStorage(app);

// Connect to emulators in development
if (process.env.NODE_ENV === 'development') {
  connectFirestoreEmulator(db, 'localhost', 8080);
  connectAuthEmulator(auth, 'http://localhost:9099');
  connectStorageEmulator(storage, 'localhost', 9199);
}
CRUD Operations
typescript
import {
  collection,
  doc,
  getDoc,
  getDocs,
  addDoc,
  setDoc,
  updateDoc,
  deleteDoc,
  query,
  where,
  orderBy,
  limit,
  startAfter,
  serverTimestamp,
  Timestamp
} from 'firebase/firestore';
import { db } from './firebase';

// Create
async function createPost(data: Omit<Post, 'id' | 'createdAt' | 'updatedAt'>) {
  const docRef = await addDoc(collection(db, 'posts'), {
    ...data,
    createdAt: serverTimestamp(),
    updatedAt: serverTimestamp()
  });
  return docRef.id;
}

// Read single document
async function getPost(postId: string): Promise<Post | null> {
  const docSnap = await getDoc(doc(db, 'posts', postId));
  if (!docSnap.exists()) return null;
  return { id: docSnap.id, ...docSnap.data() } as Post;
}

// Query with filters
async function getPostsByAuthor(authorId: string, pageSize = 10) {
  const q = query(
    collection(db, 'posts'),
    where('authorId', '==', authorId),
    orderBy('createdAt', 'desc'),
    limit(pageSize)
  );
  const snapshot = await getDocs(q);
  return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() } as Post));
}

// Pagination
async function getNextPage(lastDoc: Post, pageSize = 10) {
  const q = query(
    collection(db, 'posts'),
    orderBy('createdAt', 'desc'),
    startAfter(lastDoc.createdAt),
    limit(pageSize)
  );
  const snapshot = await getDocs(q);
  return snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() } as Post));
}

// Update
async function updatePost(postId: string, data: Partial<Post>) {
  await updateDoc(doc(db, 'posts', postId), {
    ...data,
    updatedAt: serverTimestamp()
  });
}

// Delete
async function deletePost(postId: string) {
  await deleteDoc(doc(db, 'posts', postId));
}
Real-time Listeners
typescript
import { onSnapshot, QuerySnapshot, DocumentSnapshot } from 'firebase/firestore';

// Listen to single document
function subscribeToPost(
  postId: string,
  onData: (post: Post | null) => void,
  onError: (error: Error) => void
) {
  return onSnapshot(
    doc(db, 'posts', postId),
    (snapshot: DocumentSnapshot) => {
      if (!snapshot.exists()) {
        onData(null);
        return;
      }
      onData({ id: snapshot.id, ...snapshot.data() } as Post);
    },
    onError
  );
}

// Listen to collection with query
function subscribeToPosts(
  authorId: string,
  onData: (posts: Post[]) => void,
  onError: (error: Error) => void
) {
  const q = query(
    collection(db, 'posts'),
    where('authorId', '==', authorId),
    orderBy('createdAt', 'desc')
  );

  return onSnapshot(
    q,
    (snapshot: QuerySnapshot) => {
      const posts = snapshot.docs.map(doc => ({
        id: doc.id,
        ...doc.data()
      } as Post));
      onData(posts);
    },
    onError
  );
}

// React hook example
function usePost(postId: string) {
  const [post, setPost] = useState<Post | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    const unsubscribe = subscribeToPost(
      postId,
      (data) => {
        setPost(data);
        setLoading(false);
      },
      (err) => {
        setError(err);
        setLoading(false);
      }
    );
    return unsubscribe;
  }, [postId]);

  return { post, loading, error };
}
Offline Persistence (Web)
typescript
import { enableIndexedDbPersistence, enableMultiTabIndexedDbPersistence } from 'firebase/firestore';

// Enable offline persistence (call once at startup)
async function enableOffline() {
  try {
    // Single tab
    await enableIndexedDbPersistence(db);

    // OR multi-tab (recommended)
    await enableMultiTabIndexedDbPersistence(db);
  } catch (err: any) {
    if (err.code === 'failed-precondition') {
      // Multiple tabs open, only works in one
      console.warn('Persistence only available in one tab');
    } else if (err.code === 'unimplemented') {
      // Browser doesn't support
      console.warn('Persistence not supported');
    }
  }
}

// Check if data is from cache
onSnapshot(docRef, (snapshot) => {
  const source = snapshot.metadata.fromCache ? 'cache' : 'server';
  console.log(`Data from ${source}`);

  if (snapshot.metadata.hasPendingWrites) {
    console.log('Local changes pending sync');
  }
});

Security Rules

Basic Rules Structure
javascript
// firestore.rules
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

    // Helper functions
    function isAuthenticated() {
      return request.auth != null;
    }

    function isOwner(userId) {
      return request.auth.uid == userId;
    }

    function isAdmin() {
      return request.auth.token.admin == true;
    }

    // Posts collection
    match /posts/{postId} {
      // Anyone can read published posts
      allow read: if resource.data.status == 'published';

      // Only authenticated users can create
      allow create: if isAuthenticated()
        && request.resource.data.authorId == request.auth.uid
        && request.resource.data.keys().hasAll(['title', 'content', 'authorId']);

      // Only author can update
      allow update: if isOwner(resource.data.authorId)
        && request.resource.data.authorId == resource.data.authorId; // Can't change author

      // Only author or admin can delete
      allow delete: if isOwner(resource.data.authorId) || isAdmin();

      // Comments subcollection
      match /comments/{commentId} {
        allow read: if true;
        allow create: if isAuthenticated();
        allow update, delete: if isOwner(resource.data.authorId);
      }
    }

    // User profiles
    match /users/{userId} {
      allow read: if true;
      allow create: if isAuthenticated() && isOwner(userId);
      allow update: if isOwner(userId);
      allow delete: if false; // Never allow delete
    }

    // Private user data
    match /users/{userId}/private/{document=**} {
      allow read, write: if isOwner(userId);
    }
  }
}
Data Validation in Rules
javascript
match /posts/{postId} {
  function isValidPost() {
    let data = request.resource.data;
    return data.title is string
      && data.title.size() >= 3
      && data.title.size() <= 100
      && data.content is string
      && data.content.size() <= 50000
      && data.tags is list
      && data.tags.size() <= 5;
  }

  allow create: if isAuthenticated() && isValidPost();
  allow update: if isOwner(resource.data.authorId) && isValidPost();
}
Test Rules Locally
bash
# Install emulators
firebase emulators:start

# Run rules tests
npm test
typescript
// tests/firestore.rules.test.ts
import { assertFails, assertSucceeds, initializeTestEnvironment } from '@firebase/rules-unit-testing';

describe('Firestore Rules', () => {
  let testEnv: RulesTestEnvironment;

  beforeAll(async () => {
    testEnv = await initializeTestEnvironment({
      projectId: 'test-project',
      firestore: { rules: fs.readFileSync('firestore.rules', 'utf8') }
    });
  });

  test('unauthenticated users cannot write', async () => {
    const unauthedDb = testEnv.unauthenticatedContext().firestore();
    await assertFails(
      setDoc(doc(unauthedDb, 'posts/test'), { title: 'Test' })
    );
  });

  test('users can only update own posts', async () => {
    const aliceDb = testEnv.authenticatedContext('alice').firestore();
    const bobDb = testEnv.authenticatedContext('bob').firestore();

    // Create as Alice
    await assertSucceeds(
      setDoc(doc(aliceDb, 'posts/test'), { title: 'Test', authorId: 'alice' })
    );

    // Bob cannot update
    await assertFails(
      updateDoc(doc(bobDb, 'posts/test'), { title: 'Hacked' })
    );
  });
});

Authentication

Email/Password Auth
typescript
import {
  createUserWithEmailAndPassword,
  signInWithEmailAndPassword,
  signOut,
  onAuthStateChanged,
  User
} from 'firebase/auth';
import { auth } from './firebase';

// Sign up
async function signUp(email: string, password: string) {
  const credential = await createUserWithEmailAndPassword(auth, email, password);
  return credential.user;
}

// Sign in
async function signIn(email: string, password: string) {
  const credential = await signInWithEmailAndPassword(auth, email, password);
  return credential.user;
}

// Sign out
async function logout() {
  await signOut(auth);
}

// Auth state listener
function onAuthChange(callback: (user: User | null) => void) {
  return onAuthStateChanged(auth, callback);
}
OAuth Providers
typescript
import {
  GoogleAuthProvider,
  signInWithPopup,
  signInWithRedirect
} from 'firebase/auth';

const googleProvider = new GoogleAuthProvider();

async function signInWithGoogle() {
  try {
    const result = await signInWithPopup(auth, googleProvider);
    return result.user;
  } catch (error) {
    // Handle errors
    throw error;
  }
}

Cloud Functions

Basic HTTP Function
typescript
// functions/src/index.ts
import { onRequest } from 'firebase-functions/v2/https';
import { onDocumentCreated } from 'firebase-functions/v2/firestore';
import { initializeApp } from 'firebase-admin/app';
import { getFirestore } from 'firebase-admin/firestore';

initializeApp();
const db = getFirestore();

// HTTP endpoint
export const helloWorld = onRequest((request, response) => {
  response.json({ message: 'Hello from Firebase!' });
});

// Firestore trigger
export const onPostCreated = onDocumentCreated('posts/{postId}', async (event) => {
  const snapshot = event.data;
  if (!snapshot) return;

  const post = snapshot.data();

  // Update author's post count
  await db.doc(`users/${post.authorId}`).update({
    postCount: FieldValue.increment(1)
  });
});
Callable Functions
typescript
// Backend
import { onCall, HttpsError } from 'firebase-functions/v2/https';

export const createPost = onCall(async (request) => {
  // Auth check
  if (!request.auth) {
    throw new HttpsError('unauthenticated', 'Must be logged in');
  }

  const { title, content } = request.data;

  // Validation
  if (!title || title.length < 3) {
    throw new HttpsError('invalid-argument', 'Title must be at least 3 characters');
  }

  // Create post
  const postRef = await db.collection('posts').add({
    title,
    content,
    authorId: request.auth.uid,
    createdAt: FieldValue.serverTimestamp()
  });

  return { postId: postRef.id };
});

// Frontend
import { getFunctions, httpsCallable } from 'firebase/functions';

const functions = getFunctions();
const createPostFn = httpsCallable(functions, 'createPost');

async function createPost(title: string, content: string) {
  const result = await createPostFn({ title, content });
  return result.data as { postId: string };
}

Batch Operations & Transactions

Batch Writes
typescript
import { writeBatch, doc } from 'firebase/firestore';

async function batchUpdate(updates: { id: string; data: any }[]) {
  const batch = writeBatch(db);

  updates.forEach(({ id, data }) => {
    batch.update(doc(db, 'posts', id), data);
  });

  await batch.commit(); // Atomic
}
Transactions
typescript
import { runTransaction, doc, increment } from 'firebase/firestore';

async function likePost(postId: string, userId: string) {
  await runTransaction(db, async (transaction) => {
    const postRef = doc(db, 'posts', postId);
    const likeRef = doc(db, 'posts', postId, 'likes', userId);

    const postSnap = await transaction.get(postRef);
    if (!postSnap.exists()) throw new Error('Post not found');

    const likeSnap = await transaction.get(likeRef);
    if (likeSnap.exists()) throw new Error('Already liked');

    transaction.set(likeRef, { createdAt: serverTimestamp() });
    transaction.update(postRef, { likeCount: increment(1) });
  });
}

Indexes

Composite Indexes
json
// firestore.indexes.json
{
  "indexes": [
    {
      "collectionGroup": "posts",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "authorId", "order": "ASCENDING" },
        { "fieldPath": "createdAt", "order": "DESCENDING" }
      ]
    },
    {
      "collectionGroup": "posts",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "tags", "arrayConfig": "CONTAINS" },
        { "fieldPath": "createdAt", "order": "DESCENDING" }
      ]
    }
  ]
}
bash
# Deploy indexes
firebase deploy --only firestore:indexes

CLI Quick Reference

bash
# Project setup
firebase login                       # Authenticate
firebase init                        # Initialize project
firebase projects:list               # List projects

# Emulators
firebase emulators:start             # Start all emulators
firebase emulators:start --only firestore,auth  # Specific emulators

# Deploy
firebase deploy                      # Deploy everything
firebase deploy --only firestore     # Deploy rules + indexes
firebase deploy --only functions     # Deploy functions
firebase deploy --only hosting       # Deploy hosting

# Functions
cd functions && npm run build        # Build TypeScript
firebase functions:log               # View logs

Anti-Patterns

  • No security rules - Always write rules, never use test mode in production
  • Deep nesting - Keep documents flat, max 2-3 levels
  • Large documents - Max 1MB, split if larger
  • Unbounded arrays - Use subcollections for lists that grow
  • No offline handling - Enable persistence for mobile/PWA
  • Reading all fields - Use field masks or Firestore Lite
  • Ignoring indexes - Check console for missing index errors
  • No emulator testing - Always test rules before deploy

© alinaqi, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/firebase of alinaqi/maggy.

Open the folder on GitHubat commit 72a456e

Compare with similar skills

Firebase next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Firebase compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Firebase this skillalinaqi/maggy707—~4.6kAutomated safety check: PassMIT
Firebaseaiskillstore/marketplace4303 repos~4.7kAutomated safety check: PassNone
Firebaseericrisco/rsc-harness167—~3.3kAutomated safety check: PassMIT
FirebasebenjaminasterA/antigravity-awesome-skills3681 repos~399Automated safety check: PassMIT
Firebase App Platformsickn33/agentic-awesome-skills47k2 repos~2.6kAutomated safety check: NotesMIT
Firebasedavila7/claude-code-templates32k2 repos~445Automated safety check: PassMIT

Similar skills

  • Firebase

    aiskillstore/marketplace

    Firebase gives you a complete backend in minutes - auth, database, storage, functions, hosting.

    430 GitHub starsUsed in 3 repos~4.7k tokens
    Backend & APIsAuto-check passed
  • Firebase

    ericrisco/rsc-harness

    A skill your agent uses when building on Firebase — Firestore data modeling, Security Rules, Auth and custom claims, Cloud Functions, Storage, modular Web/Admin SDK imports — including symptoms like…

    167 GitHub stars~3.3k tokensUpdated yesterday
    DatabasesAuto-check passed
  • Firebase

    benjaminasterA/antigravity-awesome-skills

    Firebase gives you a complete backend in minutes - auth, database, storage, functions, hosting.

    368 GitHub starsUsed in 1 repo~399 tokens
    DatabasesAuto-check passed
  • Firebase App Platform

    sickn33/agentic-awesome-skills

    Build and operate apps on Firebase using Auth, Firestore, Cloud Functions, and Hosting.

    47k GitHub starsUsed in 2 repos~2.6k tokens
    Backend & APIsAuto-check: notes
  • Firebase

    davila7/claude-code-templates

    Firebase gives you a complete backend in minutes - auth, database, storage, functions, hosting.

    32k GitHub starsUsed in 2 repos~445 tokens
    Backend & APIsAuto-check passed
  • Firebase Vertex AI

    jeremylongshore/tons-of-skills-marketplace

    Execute firebase platform expert with Vertex AI Gemini integration for Authentication, Firestore, Storage, Functions, Hosting, and AI-powered features.

    2.8k GitHub stars~831 tokensUpdated today
    Backend & APIsAuto-check passed

More from alinaqi/maggy

All 71 skills in this repo
  • AI Models

    alinaqi/maggy

    Latest AI models reference - Claude, OpenAI, Gemini, Eleven Labs, Replicate

    707 GitHub starsUsed in 1 repo~4.1k tokens
    Auto-check passed
  • Azure Cosmosdb

    alinaqi/maggy

    Azure Cosmos DB partition keys, consistency levels, change feed, SDK patterns

    707 GitHub starsUsed in 1 repo~4.5k tokens
    Auto-check passed
  • LLM Patterns

    alinaqi/maggy

    AI-first application patterns, LLM testing, prompt management

    707 GitHub starsUsed in 1 repo~2.1k tokens
    Auto-check passed
  • Woocommerce

    alinaqi/maggy

    WooCommerce REST API - products, orders, customers, webhooks

    707 GitHub starsUsed in 1 repo~4.4k tokens
    Auto-check: notes
  • Aeo Optimization

    alinaqi/maggy

    AI Engine Optimization - semantic triples, page templates, content clusters for AI citations

    707 GitHub stars~3.7k tokensUpdated 14 days ago
    Auto-check passed
  • Agent Teams

    alinaqi/maggy

    Claude Code Agent Teams - default team-based development with strict TDD pipeline enforcement

    707 GitHub stars~5k tokensUpdated 14 days ago
    Auto-check: notes

Questions about Firebase

What does Firebase do?

Firebase Firestore, Auth, Storage, real-time listeners, security rules. Firebase is an agent skill from alinaqi/maggy.

When should I use Firebase?

Firebase fits situations like: databases work in your project.

How do I install Firebase in Claude Code?

Run `npx skills add alinaqi/maggy --skill firebase -a claude-code`. Or copy the skill folder (skills/firebase in alinaqi/maggy) into .claude/skills/firebase in your project. Claude Code loads it when a task matches its description.

How do I install Firebase in Codex?

Run `npx skills add alinaqi/maggy --skill firebase -a codex`. Or copy the skill folder (skills/firebase in alinaqi/maggy) into .agents/skills/firebase in your project. Codex loads it when a task matches its description.

Can I use Firebase in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add alinaqi/maggy --skill firebase -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/firebase, .gemini/skills/firebase, .github/skills/firebase and .opencode/skills/firebase in your project.

What does Firebase need to run?

Going by SKILL.md and its folder, Firebase needs the command-line tools its instructions call (firebase and npm) and credentials named NEXT_PUBLIC_FIREBASE_API_KEY. Our summary lists: Node.js; A credential in NEXT_PUBLIC_FIREBASE_API_KEY.

Does Firebase access the network?

SKILL.md names 1 domain. As links in the text: firebase.google.com. This is read from the text; nothing was executed.

Is Firebase safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Firebase use?

Firebase is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Firebase use?

About 4.6k tokens (SKILL.md is roughly 18k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Firebase?

Skills that share tags, products or a category with Firebase: Firebase (aiskillstore/marketplace, 430 stars), Firebase (ericrisco/rsc-harness, 167 stars), Firebase (benjaminasterA/antigravity-awesome-skills, 368 stars) and Firebase App Platform (sickn33/agentic-awesome-skills, 47k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Firebase?

alinaqi (a GitHub user) maintains it in alinaqi/maggy, which has 707 GitHub stars. The repository holds 71 skills in this directory. The repository was last updated on September 24, 2026.

Source: alinaqi/maggy on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.