### Firebase CLI Commands for Setup and Deployment Source: https://context7.com/firebase/functions-samples/llms.txt These bash commands cover installing the Firebase CLI, logging in, selecting a project, installing function dependencies, starting the emulator suite, triggering functions locally, and deploying functions. ```bash # Install the Firebase CLI globally. npm install -g firebase-tools # Authenticate and select a project. firebase login firebase use --add # follow prompts to link your Firebase project # Install function dependencies (Node.js sample). cd Node/quickstarts/uppercase-firestore/functions && npm install && cd - # Run all functions locally with the Emulator Suite (no cloud required). firebase emulators:start # → Emulator UI: http://localhost:4000 # → Functions: http://localhost:5001//us-central1/ # Trigger the addmessage HTTP function from the emulator. curl "http://localhost:5001/MY_PROJECT/us-central1/addmessage?text=helloworld" # => {"result":"Message with ID: ABC123 added."} # Deploy a single function to production. firebase deploy --only functions:addmessage # Deploy all functions. firebase deploy --only functions ``` -------------------------------- ### Install Dependencies Source: https://github.com/firebase/functions-samples/blob/main/Node/quickstarts/genkit-helloworld/README.md Run this command to install the necessary project dependencies. ```bash npm install ``` -------------------------------- ### Start Development Server for Client Source: https://github.com/firebase/functions-samples/blob/main/Node/call-vertex-remote-config-server/README.md Navigate to the client directory and run the development server to test the connection to the deployed function. ```bash cd client && npm run dev ``` -------------------------------- ### Start Firebase Emulators Source: https://github.com/firebase/functions-samples/blob/main/Node/call-vertex-remote-config-server/README.md Start the Firebase emulator suite to test your Cloud Functions and other Firebase services locally. ```bash firebase emulators:start ``` -------------------------------- ### Install NPM Dependencies and Deploy Source: https://github.com/firebase/functions-samples/blob/main/Node/quickstarts/pubsub-helloworld/README.md Install local npm dependencies for the functions and then deploy the application to Firebase. The initial deployment may take longer. ```bash cd functions && npm install; cd .. ``` ```bash firebase deploy ``` -------------------------------- ### Start Firebase Emulator Source: https://github.com/firebase/functions-samples/blob/main/Node/quickstarts/genkit-helloworld/README.md Start the Cloud Functions emulator to test your Genkit flow locally. The emulator will output the function URL. ```bash firebase emulators:start --only functions ``` -------------------------------- ### Install Firebase CLI Source: https://github.com/firebase/functions-samples/blob/main/Node/quickstarts/pubsub-helloworld/README.md Install the Firebase CLI globally using npm. If you encounter permission issues, consult the npm documentation for fixing them. ```bash npm install -g firebase-tools ``` -------------------------------- ### Install Firebase Tools Source: https://github.com/firebase/functions-samples/blob/main/Node/call-vertex-remote-config-server/README.md Install the latest version of firebase-tools globally to manage Firebase projects and deployments. ```bash npm i firebase-tools@latest ``` -------------------------------- ### Handle Button Click to Stream Forecasts Source: https://github.com/firebase/functions-samples/blob/main/Node/quickstarts/callable-functions-streaming/website/index.html This function is triggered when the button is clicked. It initializes the UI, gets the callable function, and starts streaming forecast data. ```javascript async function handleClick() { // reset result initializeUi(); // [START stream_data_client] // Get the callable by passing an initialized functions SDK. const getForecast = httpsCallable(functions, "getForecast"); // Call the function with the `.stream()` method to start streaming. const { stream, data } = await getForecast.stream({ locations: favoriteLocations }); // The `stream` async iterable returned by `.stream()` // will yield a new value every time the callable // function calls `sendChunk()`. for await (const forecastDataChunk of stream) { // update the UI every time a new chunk is received // from the callable function updateUi(forecastDataChunk); } // The `data` promise resolves when the callable // function completes. const allWeatherForecasts = await data; finalizeUi(allWeatherForecasts); // [END stream_data_client] } ``` -------------------------------- ### Install and Login to Firebase CLI Source: https://github.com/firebase/functions-samples/blob/main/Node/youtube/README.md Install the Firebase CLI globally and log in to your Firebase account. This is a prerequisite for managing Firebase projects and deploying functions. ```bash npm install --global firebase-tools firebase login ``` -------------------------------- ### Generate Custom Spans with OpenTelemetry API Source: https://github.com/firebase/functions-samples/blob/main/Node/instrument-with-opentelemetry/README.md Use the OpenTelemetry API to create custom spans for specific operations within your Cloud Function. This requires importing the OpenTelemetry API and getting a tracer instance. ```javascript const opentelemetry = require('@opentelemetry/api'); const tracer = opentelemetry.trace.getTracer(); await tracer.startActiveSpan("calculatePrice", async (span) => { totalUsd = await calculatePrice(productIds); span.end(); }); ``` -------------------------------- ### Unit Test V2 Cloud Function with Mocha and Sinon Source: https://context7.com/firebase/functions-samples/llms.txt This Mocha test uses `firebase-functions-test` and Sinon to invoke a v2 Cloud Function locally. It asserts that the logger is called once. Ensure `firebase-functions-test`, Mocha, and Sinon are installed. ```javascript // Mocha + Sinon — Node/test-functions-mocha/functions/index.test.js const { logger } = require("firebase-functions"); const test = require("firebase-functions-test"); const { assert } = require("chai"); const { spy } = require("sinon"); const { logstore } = require("./index"); const { wrap } = test(); describe("firebase-functions-test", () => { describe("#logstore", () => { it("logs when the v2 Cloud Function is invoked", () => { const logSpy = spy(logger, "log"); const wrapped = wrap(logstore); wrapped(); assert.isTrue(logSpy.calledOnce); }); }); }); // Run tests: // cd Node/test-functions-mocha/functions && npm test ``` -------------------------------- ### Navigate to Sample Directory Source: https://github.com/firebase/functions-samples/blob/main/Node/testlab-to-slack/README.md Change to the sample's directory after cloning or downloading the repository. ```shell cd 2nd-gen/testlab-to-slack ``` -------------------------------- ### Build and Deploy Function and Hosting to Emulator Source: https://github.com/firebase/functions-samples/blob/main/Node/call-vertex-remote-config-server/README.md Build the client application and deploy both the function and hosting to the Firebase emulator for integrated testing. ```bash cd client && npm run build cd .. firebase server --only functions,hosting ``` -------------------------------- ### Sample Database Structure for User Data Source: https://github.com/firebase/functions-samples/blob/main/Node/fcm-notifications/README.md Illustrates the structure for storing user notification tokens under `/users/$uid/notificationTokens`. ```json /functions-project-12345 /users /Uid-12345 displayName: "Bob Dole" /notificationTokens 1234567890: true photoURL: "https://lh3.googleusercontent.com/..." ``` -------------------------------- ### Firestore Trigger - onDocumentCreated Source: https://context7.com/firebase/functions-samples/llms.txt Fires a function when a Firestore document is created. The event carries a data snapshot and URL-style path parameters. This example also includes an HTTP function to write messages to Firestore. ```javascript // Node.js (2nd gen) — Node/quickstarts/uppercase-firestore/functions/index.js const { onRequest } = require("firebase-functions/https"); const { onDocumentCreated } = require("firebase-functions/firestore"); const { logger } = require("firebase-functions"); const { initializeApp } = require("firebase-admin/app"); const { getFirestore } = require("firebase-admin/firestore"); initializeApp(); // HTTP function writes a new message to Firestore. exports.addmessage = onRequest(async (req, res) => { const original = req.query.text; const writeResult = await getFirestore() .collection("messages") .add({ original }); res.json({ result: `Message with ID: ${writeResult.id} added.` }); }); // Firestore trigger uppercases every newly created message. exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => { const original = event.data.data().original; logger.log("Uppercasing", event.params.documentId, original); return event.data.ref.set({ uppercase: original.toUpperCase() }, { merge: true }); }); // --- Auth-context variant ------------------------------------------------ // Node/quickstarts/firestore-sync-auth/functions/index.js const { onDocumentWrittenWithAuthContext } = require("firebase-functions/firestore"); exports.verifyComment = onDocumentWrittenWithAuthContext( "comments/{commentId}", (event) => { const snapshot = event.data.after; if (!snapshot) return; const { authType, authId } = event; const verified = authType === "system" || (authType !== "unknown" && authId?.endsWith("@example.com")); return snapshot.ref.set({ created_by: authId ?? "undefined", verified }, { merge: true }); } ); ``` -------------------------------- ### Sample Database Structure for Followers Source: https://github.com/firebase/functions-samples/blob/main/Node/fcm-notifications/README.md Shows how follower relationships are stored under `/followers/$followedUid/$followerUid`. ```json /functions-project-12345 /followers /followedUid-12345 followerUid-67890: true /users /Uid-12345 displayName: "Bob Dole" /notificationTokens 1234567890: true photoURL: "https://lh3.googleusercontent.com/..." ``` -------------------------------- ### Unit Test V2 Cloud Function with Jest Source: https://context7.com/firebase/functions-samples/llms.txt This Jest test uses `firebase-functions-test` to invoke a v2 Cloud Function locally without deployment. It checks if the logger is called. Ensure `firebase-functions-test` and Jest are installed. ```javascript // Jest — Node/test-functions-jest/functions/index.test.js const { logger } = require("firebase-functions"); const test = require("firebase-functions-test"); const { logstore } = require("./index"); const { wrap } = test(); // offline mode (no project credentials needed) describe("firebase-functions-test", () => { describe("#logstore", () => { it("logs when the v2 Cloud Function is invoked", () => { const logSpy = jest.spyOn(logger, "log"); const wrapped = wrap(logstore); wrapped(); // invoke without a real event expect(logSpy).toHaveBeenCalled(); }); }); }); // Run tests: // cd Node/test-functions-jest/functions && npm test ``` -------------------------------- ### Initialize Firebase and Functions Source: https://github.com/firebase/functions-samples/blob/main/Node/quickstarts/callable-functions-streaming/website/index.html Initializes the Firebase app and functions SDK, and connects to the local emulator. Ensure Firebase is configured correctly for your project. ```javascript import { initializeApp } from "https://www.gstatic.com/firebasejs/11.2.0/firebase-app.js"; import { getFunctions, connectFunctionsEmulator } from "https://www.gstatic.com/firebasejs/11.2.0/firebase-functions.js"; const callableButton = document.getElementById("btn-call-func"); const resultElement = document.getElementById("forecasts"); callableButton.onclick = handleClick; // https://firebase.google.com/docs/hosting/reserved-urls#sdk_auto-configuration const firebaseConfig = await fetch("/\[\]/firebase/init.json").then( (response) => { return response.json(); } ); const app = initializeApp(firebaseConfig); const functions = getFunctions(app); connectFunctionsEmulator(functions, "127.0.0.1", 5001); ``` -------------------------------- ### Template for Adding Community Samples Source: https://github.com/firebase/functions-samples/blob/main/community.md Use this Markdown template to contribute your own Firebase community sample. Include a title, a brief description, and the author's GitHub handle. ```markdown ### [Emoji replacer](https://link-to-sample-source-code.com) Use Cloud Functions to replace common words with emojis! **Author:** @jhuleatt ``` -------------------------------- ### Auth Blocking Triggers in Node.js Source: https://context7.com/firebase/functions-samples/llms.txt Use these functions to run code synchronously before Firebase Auth completes account creation or sign-in. Throwing an HttpsError aborts the operation. Includes examples for blocking sign-up, sign-in, email sending, and SMS sending. ```javascript // Node.js (2nd gen) — Node/quickstarts/auth-blocking-functions/functions/index.js const { beforeUserCreated, beforeUserSignedIn, beforeEmailSent, beforeSmsSent, HttpsError, } = require("firebase-functions/identity"); const { defineString } = require("firebase-functions/params"); const admin = require("firebase-admin"); admin.initializeApp(); const db = admin.firestore(); // Block sign-up to @acme.com addresses only. exports.validateNewUser = beforeUserCreated((event) => { if (!event.data?.email?.includes("@acme.com")) throw new HttpsError("invalid-argument", "Unauthorized email"); }); // Block sign-in for accounts listed in a Firestore "banned" collection. exports.checkForBan = beforeUserSignedIn(async (event) => { const email = event.data.email || ""; const doc = await db.collection("banned").doc(email).get(); if (doc.exists) throw new HttpsError("invalid-argument", "Unauthorized email"); }); // Block outbound emails to non-acme.com addresses. exports.checkEmailDomain = beforeEmailSent((event) => { const email = event.data?.email || event.additionalUserInfo?.email; if (!email) throw new HttpsError("invalid-argument", "No email in event"); if (!email.endsWith("@acme.com")) throw new HttpsError("permission-denied", "Only acme.com users can authenticate"); }); // Restrict SMS to a configurable country prefix (default +1). const intlPrefixNumber = defineString("INTERNATIONAL_PREFIX_NUMBER", { default: "+1" }); exports.checkPhoneNumber = beforeSmsSent((event) => { const phoneNumber = event.data?.phoneNumber || event.additionalUserInfo?.phoneNumber; if (!phoneNumber) throw new HttpsError("invalid-argument", "No phone number in event"); if (!phoneNumber.startsWith(intlPrefixNumber.value())) throw new HttpsError("invalid-argument", "Unauthorized phone number"); }); ``` -------------------------------- ### Log in to Firebase Source: https://github.com/firebase/functions-samples/blob/main/Node/call-vertex-remote-config-server/README.md Authenticate with your Firebase account using the firebase-tools CLI. ```bash firebase login ``` -------------------------------- ### Access Client App Source: https://github.com/firebase/functions-samples/blob/main/Node/call-vertex-remote-config-server/README.md Open the client application in your browser to interact with the deployed Firebase function. Ensure Remote Config is enabled for Vertex AI. ```bash http://localhost:5173 ``` -------------------------------- ### UI Update Functions Source: https://github.com/firebase/functions-samples/blob/main/Node/quickstarts/callable-functions-streaming/website/index.html Helper functions to initialize the UI, update it with incoming forecast data chunks, and finalize the UI once streaming is complete. ```javascript function initializeUi() { resultElement.innerHTML = ""; callableButton.disabled = true; callableButton.innerText = "Streaming forecasts..."; } function finalizeUi() { callableButton.disabled = false; callableButton.innerText = "Get forecasts"; } function updateUi(forecastData) { const newWeatherCard = document.createElement("div"); const locationName = document.createElement("h2"); locationName.innerHTML = favoriteLocations.find( (v) => v.latitude === forecastData.latitude ).name; const forecast = document.createElement("p"); console.log(forecastData); forecast.innerHTML = forecastData.forecast.properties.periods[0].detailedForecast; newWeatherCard.append(locationName, forecast); resultElement.appendChild(newWeatherCard); } ``` -------------------------------- ### Test Time Function with cURL (PUT Request) Source: https://github.com/firebase/functions-samples/blob/main/Node/quickstarts/https-time-server/README.md Tests the function's behavior with a PUT request, which is configured to return a 403 error. Replace `` with your function's actual URL. ```bash curl -X PUT -d '{"format": "MMMM Do YYYY, h:mm:ss a"}' /date ``` -------------------------------- ### Publish a Message to a Pub/Sub Topic Source: https://github.com/firebase/functions-samples/blob/main/Node/quickstarts/pubsub-helloworld/README.md Publish a simple string message to a specified Pub/Sub topic using the gcloud CLI. Check Firebase Console logs for the 'Hello YourName' output. ```bash gcloud pubsub topics publish topic-name --message='YourName' ``` -------------------------------- ### Deploy Firebase Cloud Function Source: https://github.com/firebase/functions-samples/blob/main/Node/app-distribution-feedback-to-jira/README.md Deploy the Firebase Cloud Function to your project. This command will prompt for configuration settings and store them securely. ```bash firebase deploy ``` -------------------------------- ### Publish a Message with Attributes to a Pub/Sub Topic Source: https://github.com/firebase/functions-samples/blob/main/Node/quickstarts/pubsub-helloworld/README.md Publish a message with attributes to a specified Pub/Sub topic using the gcloud CLI. Confirm the 'Hello YourName' output in Firebase Console logs. ```bash gcloud pubsub topics publish yet-another-topic-name --attribute name=YourName ``` -------------------------------- ### Test Time Function with cURL (JSON Body) Source: https://github.com/firebase/functions-samples/blob/main/Node/quickstarts/https-time-server/README.md Tests the deployed time function by sending a POST request with a JSON body specifying the desired date format. Ensure you replace `` with your function's actual URL. ```bash curl -H 'Content-Type: application/json' \ -d '{"format": "MMMM Do YYYY, h:mm:ss a"}' \ /date ``` -------------------------------- ### Deploy Firebase Functions Source: https://github.com/firebase/functions-samples/blob/main/Node/alerts-to-discord/README.md Deploy your Firebase Cloud Functions using the Firebase CLI. Ensure your environment variables are correctly set before deployment. ```bash $ firebase deploy ``` -------------------------------- ### Deploy Cloud Function Source: https://github.com/firebase/functions-samples/blob/main/Node/instrument-with-opentelemetry/README.md Deploy your instrumented Cloud Function to Firebase using the Firebase CLI. ```bash firebase deploy --only functions ``` -------------------------------- ### Publish a JSON Message to a Pub/Sub Topic Source: https://github.com/firebase/functions-samples/blob/main/Node/quickstarts/pubsub-helloworld/README.md Publish a JSON formatted message to a specified Pub/Sub topic using the gcloud CLI. Verify the 'Hello YourName' output in Firebase Console logs. ```bash gcloud pubsub topics publish another-topic-name --message='{"name":"YourName"}' ``` -------------------------------- ### Cloud Storage Trigger: Generate Thumbnail (Node.js) Source: https://context7.com/firebase/functions-samples/llms.txt Fires when an image is uploaded to Cloud Storage, generating a 200x200 thumbnail. Requires the 'sharp' library and Firebase Admin SDK initialization. Skips if the file is already a thumbnail or not an image. ```javascript // Node.js (2nd gen) — Node/quickstarts/thumbnails/functions/index.js const { onObjectFinalized } = require("firebase-functions/storage"); const { initializeApp } = require("firebase-admin/app"); const { getStorage } = require("firebase-admin/storage"); const logger = require("firebase-functions/logger"); const path = require("path"); const sharp = require("sharp"); initializeApp(); exports.generateThumbnail = onObjectFinalized({ cpu: 2 }, async (event) => { const fileBucket = event.data.bucket; const filePath = event.data.name; const contentType = event.data.contentType; if (!contentType.startsWith("image/")) return logger.log("Not an image."); const fileName = path.basename(filePath); if (fileName.startsWith("thumb_")) return logger.log("Already a thumbnail."); const bucket = getStorage().bucket(fileBucket); const [imageBuffer] = await bucket.file(filePath).download(); const thumbnailBuffer = await sharp(imageBuffer) .resize({ width: 200, height: 200, withoutEnlargement: true }) .toBuffer(); const thumbFilePath = path.join(path.dirname(filePath), `thumb_${fileName}`); await bucket.file(thumbFilePath).save(thumbnailBuffer, { metadata: { contentType } }); return logger.log("Thumbnail uploaded!"); }); ``` -------------------------------- ### Configure Service Account User Role Source: https://github.com/firebase/functions-samples/blob/main/Node/taskqueues-backup-images/README.md This step requires manual configuration via Google Cloud IAM documentation to grant the App Engine default service account the ability to act as a user for itself. ```text Please follow Google Cloud IAM documentation to add App Engine default service account as user of App Engine default service account. ``` -------------------------------- ### Cloud Storage Trigger: Generate Thumbnail (Python) Source: https://context7.com/firebase/functions-samples/llms.txt Generates a 200x200 thumbnail for every image uploaded to Cloud Storage. Requires Pillow and Firebase Admin SDK initialization. Skips if the file is already a thumbnail or not an image. ```python # Python (2nd gen) — Python/thumbnails/functions/main.py import io, pathlib from PIL import Image from firebase_admin import initialize_app, storage from firebase_functions import storage_fn initialize_app() @storage_fn.on_object_finalized() def generatethumbnail(event: storage_fn.CloudEvent[storage_fn.StorageObjectData]): """Generates a 200x200 thumbnail for every image uploaded to Storage.""" bucket_name = event.data.bucket file_path = pathlib.PurePath(event.data.name) content_type = event.data.content_type if not content_type or not content_type.startswith("image/"): print("Not an image."); return if file_path.name.startswith("thumb_"): print("Already a thumbnail."); return bucket = storage.bucket(bucket_name) image_bytes = bucket.blob(str(file_path)).download_as_bytes() image = Image.open(io.BytesIO(image_bytes)) image.thumbnail((200, 200)) out = io.BytesIO() image.save(out, format="png") thumb_path = file_path.parent / f"thumb_{file_path.stem}.png" bucket.blob(str(thumb_path)).upload_from_string(out.getvalue(), content_type="image/png") ``` -------------------------------- ### Set Discord Webhook URL Environment Variable Source: https://github.com/firebase/functions-samples/blob/main/Node/alerts-to-discord/README.md Configure the DISCORD_WEBHOOK_URL environment variable in a .env file to specify where alerts should be sent. This is required for the function to send messages to Discord. ```bash DISCORD_WEBHOOK_URL="" ``` -------------------------------- ### Realtime Database Trigger: Uppercase Conversion (Node.js) Source: https://context7.com/firebase/functions-samples/llms.txt Responds to new data in the Realtime Database by creating an uppercase version of the data. Requires Firebase Admin SDK initialization. ```javascript // Node.js (2nd gen) — Node/quickstarts/uppercase-rtdb/functions/index.js const { onRequest } = require("firebase-functions/https"); const { onValueCreated } = require("firebase-functions/database"); const { logger } = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); // HTTP function pushes a message into RTDB. exports.addmessage = onRequest(async (req, resp) => { const original = req.query.text; const snapshot = await admin.database().ref("/messages").push({ original }); resp.redirect(303, snapshot.ref.toString()); }); // RTDB trigger creates an uppercase sibling node. exports.makeuppercase = onValueCreated( "/messages/{pushId}/original", (event) => { const original = event.data.val(); logger.log("Uppercasing", event.params.pushId, original); return event.data.ref.parent.child("uppercase").set(original.toUpperCase()); } ); ``` -------------------------------- ### Call Genkit Function Source: https://github.com/firebase/functions-samples/blob/main/Node/quickstarts/genkit-helloworld/README.md Use curl to send a POST request to your deployed Genkit function. Replace the URL with your function's actual URL. ```bash curl -X POST \ --url https://127.0.0.1:5001/{$PROJECT}/us-central1/tellJoke \ --header "Content-Type: application/json" \ --header "Accept: text/event-stream" \ --data '{"data": "Observational comedy"}' ``` -------------------------------- ### Wrap Genkit AI Flow with onCallGenkit Source: https://context7.com/firebase/functions-samples/llms.txt Exposes a Genkit AI flow as a Firebase callable function, supporting streaming and secure secret management. Requires binding Cloud Secret Manager secrets for API key access. ```javascript // Node.js (2nd gen) — Node/quickstarts/genkit-helloworld/functions/index.js const { onCallGenkit } = require("firebase-functions/https"); const { defineSecret } = require("firebase-functions/params"); const { gemini15Flash, googleAI } = require("@genkit-ai/googleai"); const { genkit, z } = require("genkit"); const apiKey = defineSecret("GOOGLE_GENAI_API_KEY"); const ai = genkit({ plugins: [googleAI()], model: gemini15Flash }); const jokeTeller = ai.defineFlow( { name: "jokeTeller", inputSchema: z.string().nullable(), outputSchema: z.string(), streamSchema: z.string() }, async (jokeType = "knock-knock", { sendChunk }) => { const { stream, response: aiResponse } = ai.generateStream(`Tell me a ${jokeType} joke.`); // Stream tokens to the client as they arrive. for await (const chunk of stream) sendChunk(chunk.text); return (await aiResponse).text; } ); // Bind the API key secret and expose the flow as a callable function. exports.tellJoke = onCallGenkit({ secrets: [apiKey] }, jokeTeller); // Client usage (JavaScript): // import { getFunctions, httpsCallable } from "firebase/functions"; // const tellJoke = httpsCallable(getFunctions(), "tellJoke"); // const result = await tellJoke("dad joke"); // console.log(result.data); // "Why don't scientists trust atoms? Because they make up everything!" ``` -------------------------------- ### Show Remote Config Changes (Node.js) Source: https://context7.com/firebase/functions-samples/llms.txt Triggers when Remote Config is updated, fetches the current and previous versions, and logs the differences using json-diff. Requires Firebase Admin SDK and Google Cloud credentials. ```javascript // Node.js (2nd gen) — Node/remote-config-diff/functions/index.js const { onConfigUpdated } = require("firebase-functions/remoteConfig"); const logger = require("firebase-functions/logger"); const admin = require("firebase-admin"); const jsonDiff = require("json-diff"); const app = admin.initializeApp(); exports.showconfigdiff = onConfigUpdated(async (event) => { try { const token = (await admin.credential.applicationDefault().getAccessToken()).access_token; const api = `https://firebaseremoteconfig.googleapis.com/v1/projects/${app.options.projectId}/remoteConfig`; const cur = event.data.versionNumber; const [currentResp, prevResp] = await Promise.all([ fetch(api, { method: "POST", body: new URLSearchParams([["versionNumber", `${cur}`]]), headers: { Authorization: `Bearer ${token}` } }), fetch(api, { method: "POST", body: new URLSearchParams([["versionNumber", `${cur - 1}`]]), headers: { Authorization: `Bearer ${token}` } }), ]); const diff = jsonDiff.diffString(await prevResp.json(), await currentResp.json()); logger.log(diff); } catch (err) { logger.error(err); } }); ``` -------------------------------- ### Genkit AI Flow — `onCallGenkit` Source: https://context7.com/firebase/functions-samples/llms.txt Wraps a Genkit AI flow as a Firebase callable function. Supports streaming partial responses to clients that opt in, and binds Cloud Secret Manager secrets for safe API key access. ```APIDOC ## Genkit AI Flow — `onCallGenkit` Wraps a Genkit AI flow as a Firebase callable function. Supports streaming partial responses to clients that opt in, and binds Cloud Secret Manager secrets for safe API key access. ```js // Node.js (2nd gen) — Node/quickstarts/genkit-helloworld/functions/index.js const { onCallGenkit } = require("firebase-functions/https"); const { defineSecret } = require("firebase-functions/params"); const { gemini15Flash, googleAI } = require("@genkit-ai/googleai"); const { genkit, z } = require("genkit"); const apiKey = defineSecret("GOOGLE_GENAI_API_KEY"); const ai = genkit({ plugins: [googleAI()], model: gemini15Flash }); const jokeTeller = ai.defineFlow( { name: "jokeTeller", inputSchema: z.string().nullable(), outputSchema: z.string(), streamSchema: z.string() }, async (jokeType = "knock-knock", { sendChunk }) => { const { stream, response: aiResponse } = ai.generateStream(`Tell me a ${jokeType} joke.`); // Stream tokens to the client as they arrive. for await (const chunk of stream) sendChunk(chunk.text); return (await aiResponse).text; } ); // Bind the API key secret and expose the flow as a callable function. exports.tellJoke = onCallGenkit({ secrets: [apiKey] }, jokeTeller); // Client usage (JavaScript): // import { getFunctions, httpsCallable } from "firebase/functions"; // const tellJoke = httpsCallable(getFunctions(), "tellJoke"); // const result = await tellJoke("dad joke"); // console.log(result.data); // "Why don't scientists trust atoms? Because they make up everything!" ``` ``` -------------------------------- ### Send Callable Request to Function Source: https://github.com/firebase/functions-samples/blob/main/Node/instrument-with-opentelemetry/README.md Send a POST request with a JSON payload to your deployed callable Cloud Function to test its functionality and trace generation. ```bash $ curl -X POST -H "content-type: application/json" https:// -d '{ "data": ... }' ``` -------------------------------- ### Callable Function — `onCall` (Streaming Forecast) Source: https://context7.com/firebase/functions-samples/llms.txt A streaming callable function that fetches weather forecasts for multiple locations. It supports streaming partial results to clients that accept it using `response.sendChunk()`. It throws an `invalid-argument` HttpsError if locations are missing. ```javascript // Node/quickstarts/callable-functions-streaming/functions/index.js exports.getForecast = onCall(async (request, response) => { if (request.data?.locations?.length < 1) throw new HttpsError("invalid-argument", "Missing locations to forecast"); const allRequests = request.data.locations.map(async ({ latitude, longitude }) => { const resp = await fetch(`https://api.weather.gov/points/${latitude},${longitude}`); const forecastUrl = (await resp.json()).properties.forecast; const forecast = await (await fetch(forecastUrl)).json(); const result = { latitude, longitude, forecast }; // Stream partial result to clients that support it. if (request.acceptsStreaming) response.sendChunk(result); return result; }); return Promise.all(allRequests); }); ``` -------------------------------- ### Pub/Sub Trigger — `onMessagePublished` Source: https://context7.com/firebase/functions-samples/llms.txt Subscribes a function to a Pub/Sub topic. The message body is Base64-encoded in `event.data.message.data`; structured JSON is available via `event.data.message.json`; custom attributes are in `event.data.message.attributes`. ```javascript // Node.js (2nd gen) — Node/quickstarts/pubsub-helloworld/functions/index.js const { onMessagePublished } = require("firebase-functions/pubsub"); const logger = require("firebase-functions/logger"); // Decode raw Base64 payload. exports.hellopubsub = onMessagePublished("topic-name", (event) => { const messageBody = event.data.message.data ? Buffer.from(event.data.message.data, "base64").toString() : null; logger.log(`Hello ${messageBody || "World"}!`); return null; }); // Parse JSON payload. exports.hellopubsubjson = onMessagePublished("another-topic-name", (event) => { let name = null; try { name = event.data.message.json.name; } catch (e) { logger.error("PubSub message was not JSON", e); } logger.log(`Hello ${name || "World"}!`); return null; }); // Read message attributes. exports.hellopubsubattributes = onMessagePublished("yet-another-topic-name", (event) => { const name = event.data.message.attributes.name; logger.log(`Hello ${name || "World"}!`); return null; }); ``` -------------------------------- ### Pub/Sub Trigger — `onMessagePublished` Source: https://context7.com/firebase/functions-samples/llms.txt Subscribes a function to a Pub/Sub topic. The message body is Base64-encoded in `event.data.message.data`; structured JSON is available via `event.data.message.json`; custom attributes are in `event.data.message.attributes`. ```APIDOC ## Pub/Sub Trigger — `onMessagePublished` Subscribes a function to a Pub/Sub topic. The message body is Base64-encoded in `event.data.message.data`; structured JSON is available via `event.data.message.json`; custom attributes are in `event.data.message.attributes`. ### Example: Decode raw Base64 payload ```javascript const { onMessagePublished } = require("firebase-functions/pubsub"); const logger = require("firebase-functions/logger"); exports.hellopubsub = onMessagePublished("topic-name", (event) => { const messageBody = event.data.message.data ? Buffer.from(event.data.message.data, "base64").toString() : null; logger.log(`Hello ${messageBody || "World"}!`); return null; }); ``` ### Example: Parse JSON payload ```javascript const { onMessagePublished } = require("firebase-functions/pubsub"); const logger = require("firebase-functions/logger"); exports.hellopubsubjson = onMessagePublished("another-topic-name", (event) => { let name = null; try { name = event.data.message.json.name; } catch (e) { logger.error("PubSub message was not JSON", e); } logger.log(`Hello ${name || "World"}!`); return null; }); ``` ### Example: Read message attributes ```javascript const { onMessagePublished } = require("firebase-functions/pubsub"); const logger = require("firebase-functions/logger"); exports.hellopubsubattributes = onMessagePublished("yet-another-topic-name", (event) => { const name = event.data.message.attributes.name; logger.log(`Hello ${name || "World"}!`); return null; }); ``` ``` -------------------------------- ### Listen for Custom Events with onCustomEventPublished Source: https://context7.com/firebase/functions-samples/llms.txt Use this function to react to custom events emitted by Firebase Extensions or Eventarc channels. It's suitable for building decoupled, event-driven integrations. ```javascript // Node.js (2nd gen) — Node/quickstarts/custom-events/functions/index.js const { onCustomEventPublished } = require("firebase-functions/eventarc"); const logger = require("firebase-functions/logger"); const { initializeApp } = require("firebase-admin/app"); const { getFirestore } = require("firebase-admin/firestore"); initializeApp(); // React to Storage Resize Images extension completing a resize operation. exports.onimageresized = onCustomEventPublished( "firebase.extensions.storage-resize-images.v1.complete", (event) => { logger.info("Image resize completed", event); // Persist resized image metadata to Firestore. return getFirestore() .collection("images") .doc(event.subject.replace("/", "_")) .set(event.data); } ); ``` -------------------------------- ### Send Firebase Alerts to Discord (Node.js) Source: https://context7.com/firebase/functions-samples/llms.txt Listens for new fatal issues in Crashlytics and performance threshold alerts, then posts messages to Discord. Requires the DISCORD_WEBHOOK_URL environment variable. ```javascript // Node.js (2nd gen) — Node/alerts-to-discord/functions/index.js const { onNewFatalIssuePublished } = require("firebase-functions/alerts/crashlytics"); const { onNewTesterIosDevicePublished } = require("firebase-functions/alerts/appDistribution"); const { onThresholdAlertPublished } = require("firebase-functions/alerts/performance"); const logger = require("firebase-functions/logger"); async function postMessageToDiscord(botName, messageBody) { const webhookUrl = process.env.DISCORD_WEBHOOK_URL; if (!webhookUrl) throw new Error("DISCORD_WEBHOOK_URL not set"); return fetch(webhookUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ content: messageBody, username: botName }), }); } // Crashlytics: new fatal issue → Discord. exports.postfatalissuetodiscord = onNewFatalIssuePublished(async (event) => { const { id, title, subtitle, appVersion } = event.data.payload.issue; const message = `🚨 New fatal issue for ${event.appId} v${appVersion}\n**${title}**\n${subtitle}\nid: `${id}``; try { const res = await postMessageToDiscord("Crashlytics Bot", message); if (!res.ok) throw new Error(`Discord returned ${res.status}`); logger.info(`Posted fatal alert ${id} to Discord`, event.data.payload); } catch (err) { logger.error(`Unable to post fatal alert ${id}`, err); } }); // Performance: threshold breach → Discord. exports.postperformancealerttodiscord = onThresholdAlertPublished(async (event) => { const p = event.data.payload; const message = `⚠️ Performance Alert: ${p.metricType}/${p.eventName}\nViolation: ${p.violationValue} ${p.violationUnit}\nInvestigate: ${p.investigateUri}`; try { const res = await postMessageToDiscord("Firebase Performance Bot", message); if (!res.ok) throw new Error(`Discord returned ${res.status}`); } catch (err) { logger.error(`Unable to post performance alert`, err); } }); ``` -------------------------------- ### Firebase Cloud Function Configuration Source: https://github.com/firebase/functions-samples/blob/main/Node/app-distribution-feedback-to-jira/README.md Configure the Firebase Cloud Function with your Jira instance details. These variables are stored in an .env file after deployment. ```bash JIRA_URI="" PROJECT_KEY="" ISSUE_TYPE_ID="" ISSUE_LABEL="