Cloud Functions
The functions module integrates Firebase Cloud Functions in your project. It provides a serverless framework to run backend code in response to events triggered by HTTPS requests, background events, or scheduled jobs.
Directoryfunctions/src/
Directoryaccount/ // Account management
- …
Directorypayment/ // Payment processing
- …
Directorychat/ // Chat functionality
- …
Directorygenkit/ // AI features (optional)
- …
- index.ts // Function exports
- main.ts // Express app setup
- store.ts // Firestore helpers
Setup
From within the functions
folder:
-
Install dependencies:
Terminal window npm install -
Create a
.env
file in thefunctions
folder:Terminal window # Required for Lemon Squeezy payment moduleKEY_LEMON_SQUEEZY_API=xxx -
Modify and adapt for your needs
-
Deploy the functions:
Terminal window firebase deploy --only functions
Express Engine
ShipFlutter uses Express.js to handle HTTP functions. The setup is defined in main.ts
and it means all HTTP endpoints:
- Are prefixed with
/v1
for versioning - Accept JSON payloads automatically
- Follow the pattern:
https://REGION-PROJECT_ID.cloudfunctions.net/api/v1/PATH
import express from "express";import bodyParser from "body-parser";
const app = express();const main = express();
// All routes are prefixed with /v1main.use("/v1", app);main.use(bodyParser.json());
// Example CRUD endpoint// URL: https://REGION-PROJECT_ID.cloudfunctions.net/api/v1/helloapp.post("/hello", (req, res) => { // Handle webhook res.status(200).send("OK");});
Function Types
ShipFlutter uses several types of Cloud Functions:
// Express API endpointapp.post("/payment/create", async (req, res) => { // Handle webhook res.status(200).send("OK");});
Used for webhooks and external integrations. For example:
https://REGION-PROJECT.cloudfunctions.net/api/v1/payment/event/ls
// Secure callable functionexports.hello = onCall(async (request) => { const name = request.auth?.token?.name; return `Hello ${name}`;});
Called from the app using the Firebase SDK:
final result = await functionsService.instance.call( 'hello', parser: (data) => data as String,);
// React to document changesexports.onItemUpdate = onDocumentUpdated( "items/{id}", async (event) => { // Get before and after data const before = event.data.before.data(); const after = event.data.after.data();
// Skip if no changes if (before.status === after.status) { return null; }
// Update related data return event.data.after.ref.set({ lastUpdate: new Date(), }, { merge: true }); });
// React to user creationexports.onUserCreated = onUserCreated(async (event) => { const user = event.data;
// Create user profile await db.collection('users').doc(user.uid).set({ email: user.email, createdAt: new Date(), // Add default data });});
Testing Functions
Test your functions locally using the Firebase Emulator:
cd functionsnpm run serve
Available Modules
ShipFlutter includes several function modules:
-
Account Management (
/account
)- User data synchronization
- Account deletion
- Social auth
-
Payment Processing (
/payment
)- RevenueCat webhooks
- LemonSqueezy webhooks
- Product syncing
-
Chat Features (
/chat
)- Message handling
- Chat history
- Real-time updates
-
GenKit (
/genkit
)- AI-powered features
- Vertex AI and Gemini integration
- Custom flows
Using Functions in Flutter
The AppFunctions
class provides a type-safe way to call Cloud Functions:
// Call a function with custom payloadfinal result = await functionsService.instance.call( 'functionName', payload: {'key': 'value'}, parser: (data) => MyModel.fromJson(data),);
// Simple function callfinal greeting = await functionsService.instance.call<String>( 'hello', parser: (data) => data as String,);