agentsclimarketplace

Firebase cloud functions

Skill DentVega/firebase-agent-skills/skills/firebase-cloud-functions

Scaffolds, runs locally, and deploys Firebase Cloud Functions (2nd gen) — HTTPS endpoints, callable functions, Firestore/Auth/Storage triggers, and scheduled jobs. Use whenever the user needs server-side logic that runs in response to an HTTP request, a database change, or a cron schedule.From its SKILL.md

Install
npx -y skills add DentVega/firebase-agent-skills --skill firebase-cloud-functions

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

6.7 KB, ~1.6k tokens by cl100k_base, as published. Nobody here has run it

Firebase Cloud Functions (2nd gen)

Minimum viable example

// functions/src/index.ts
import { onCall, HttpsError } from "firebase-functions/v2/https";

export const hello = onCall((request) => {
  if (!request.auth) throw new HttpsError("unauthenticated", "");
  return { greeting: `hi ${request.auth.uid}` };
});
npx -y firebase-tools@latest deploy --only functions:hello

A signed-in client calls it via httpsCallable("hello"). That's the entire round-trip.

Always use the v2 SDK (firebase-functions/v2) for new functions. v1 is legacy and lacks Cloud Run features like concurrency, min instances, and arbitrary regions.

1. Initialize

In a Firebase project root that already has firebase.json:

npx -y firebase-tools@latest init functions

Choose TypeScript and install dependencies. This creates functions/ with:

functions/
  src/index.ts
  package.json
  tsconfig.json

2. Function types

Scaffold a callable

For the canonical v2 callable with the auth check, invoke the scaffold:

node node_modules/firebase-agent-skills/scripts/scaffold/callable-function.mjs \
  --out functions/src/index.ts --name doThing

Use --append to add a second function to the same file without overwriting. Then fill in the TODO inside the function body.

HTTPS endpoint

For public REST endpoints. Auth must be checked manually.

import { onRequest } from "firebase-functions/v2/https";

export const hello = onRequest({ cors: true, region: "us-central1" }, (req, res) => {
  res.json({ ok: true });
});

Callable function

For client SDKs (httpsCallable). Auth is verified automatically; user is at request.auth.

import { onCall, HttpsError } from "firebase-functions/v2/https";

export const createPost = onCall(async (request) => {
  if (!request.auth) throw new HttpsError("unauthenticated", "Sign in required");
  const { title, body } = request.data as { title: string; body: string };
  if (!title) throw new HttpsError("invalid-argument", "title required");

  // ... do the work
  return { id: "new-id" };
});

Client side:

import { getFunctions, httpsCallable } from "firebase/functions";
const fn = httpsCallable(getFunctions(), "createPost");
const { data } = await fn({ title: "hi", body: "..." });

Firestore trigger

Run on writes to a path. v2 trigger paths use {wildcards}.

import { onDocumentCreated } from "firebase-functions/v2/firestore";

export const onPostCreate = onDocumentCreated("posts/{postId}", async (event) => {
  const data = event.data?.data();
  // event.params.postId
});

Scheduled function

Cron-driven. Times are interpreted in the function's timezone (UTC by default).

import { onSchedule } from "firebase-functions/v2/scheduler";

export const dailyCleanup = onSchedule("every day 02:00", async () => {
  // ...
});

3. Local development with the emulator

The emulator suite runs Functions + Firestore + Auth locally so you don't burn quota:

npx -y firebase-tools@latest emulators:start

The Functions emulator hot-reloads when functions/lib/ changes. Run TypeScript in watch mode in a second terminal:

cd functions && npm run build:watch

Connect callable functions from a web client:

import { connectFunctionsEmulator, getFunctions } from "firebase/functions";
const fns = getFunctions();
if (process.env.NODE_ENV === "development") {
  connectFunctionsEmulator(fns, "127.0.0.1", 5001);
}

4. Deploy

npx -y firebase-tools@latest deploy --only functions

Deploy a single function (faster iteration):

npx -y firebase-tools@latest deploy --only functions:createPost

First deploy on a project enables required Google Cloud APIs (Cloud Build, Artifact Registry, Cloud Run). It may take a few minutes and prompt for billing.

5. Configuration & secrets

Do not use functions.config() — it's the v1 pattern and is deprecated for v2.

For non-secret config, use environment variables in functions/.env:

STRIPE_API_VERSION=2024-04-10

Available in code as process.env.STRIPE_API_VERSION.

For secrets (API keys, signing keys), use Secret Manager:

npx -y firebase-tools@latest functions:secrets:set STRIPE_SECRET_KEY

Reference in code via the function options:

import { defineSecret } from "firebase-functions/params";

const stripeKey = defineSecret("STRIPE_SECRET_KEY");

export const charge = onCall({ secrets: [stripeKey] }, async (request) => {
  const stripe = new Stripe(stripeKey.value());
  // ...
});

The secret is only mounted into functions that declare it — explicit, auditable, no global env leak.

6. Cost & cold-start tuning

  • Set minInstances: 1 for any user-facing callable that needs to respond in <1s. Cold starts on Node 20 are typically 500-2000ms; min instances eliminate them at the cost of always-on billing (~$8/mo per instance).
  • Set concurrency (default 80) higher if the function is I/O-bound and lower if CPU-bound. Each instance serves up to concurrency requests at once.
  • Set memory to the smallest size that doesn't OOM. Bigger memory = bigger CPU allocation but proportional billing.
  • Set region to be co-located with your Firestore database and your users.
export const heavy = onRequest({
  region: "us-central1",
  memory: "1GiB",
  concurrency: 20,
  minInstances: 1,
  timeoutSeconds: 60,
}, handler);

See references/admin-sdk.md for using the Admin SDK inside functions (bypasses security rules) and references/triggers.md for Auth/Storage/Pub-Sub triggers.

7. Common mistakes

  • Not awaiting promises in triggers. Background triggers exit immediately when the handler returns; un-awaited work gets killed and you'll see partial updates.
  • Calling admin.initializeApp() inside a handler. Initialize once at module top level — re-init in every invocation is slow and leaks resources.
  • Using onCall without checking request.auth. Anyone with the project's web API key can invoke it. Always assert auth.
  • Long-running work in HTTPS functions. Functions max out at 60 minutes (HTTP: 60 min, callable: 60 min — but mobile clients time out far sooner). For long jobs, enqueue a Cloud Task or use a Pub/Sub-triggered function.

What ships with it: 2 files

5.2 KB alongside SKILL.md

references/

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.