Cloud Functions for Firebase: Serverless Backend Code Guide
In this tutorial, you will learn about Cloud Functions for Firebase: Serverless Backend Code Guide. We cover key concepts, practical examples, and best practices to help you master this topic.
Cloud Functions for Firebase runs serverless backend code in response to Firebase events (database changes, auth events) and HTTPS requests, eliminating server management.
What You'll Learn
How to write and deploy Cloud Functions, respond to Firestore document changes, Process auth user creation events, build HTTPS APIs, and handle background tasks.
Why It Matters
Business logic that should not run on the client needs a secure server environment. DodaTech's Antivirus Pro uses Cloud Functions to analyze threat samples, send push notifications, and sync device configurations — all without managing servers.
Real-World Use
When a user uploads a suspicious file, a Cloud Function triggers on the Storage write event, scans the file with a virus detection algorithm, writes results to Firestore, and sends a notification.
flowchart LR
A["Firestore Write\nNew Scan Result"] --> B["Cloud Function\nTrigger"]
A --> C["HTTP Request\n/analyze"]
B --> D["Process Data"]
C --> D
D --> E["Write Result\nFirestore"]
D --> F["Send Push\nNotification"]
D --> G["Update User\nDashboard"]
style B fill:#dbeafe,stroke:#2563eb
style D fill:#bbf7d0,stroke:#16a34a
Function Setup
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const db = admin.firestore();
const storage = admin.storage();
Firestore Trigger
// Triggered when a new scan result is written
exports.onScanCreated = functions.firestore
.document("scans/{scanId}")
.onCreate(async (snap, context) => {
const scan = snap.data();
const scanId = context.params.scanId;
console.log("New scan created:", scanId);
console.log("Device:", scan.deviceId);
console.log("Threats found:", scan.threatCount);
// If critical threat, alert the user
if (scan.severity === "critical") {
await db.collection("alerts").add({
userId: scan.userId,
scanId: scanId,
message: "Critical threat detected on your device",
timestamp: admin.firestore.FieldValue.serverTimestamp(),
resolved: false
});
console.log("Alert created for user:", scan.userId);
}
return null;
});
Auth Trigger
// Send welcome email when a user creates an account
exports.onUserCreated = functions.auth
.user()
.onCreate(async (user) => {
console.log("New user created:", user.uid, user.email);
// Initialize user profile in Firestore
await db.collection("users").doc(user.uid).set({
email: user.email,
displayName: user.displayName || "User",
createdAt: admin.firestore.FieldValue.serverTimestamp(),
subscriptionTier: "free",
deviceCount: 0
});
console.log("User profile initialized");
return null;
});
HTTPS Function
// HTTP endpoint for threat analysis
exports.analyzeThreat = functions.https.onCall(async (data, context) => {
// Verify authentication
if (!context.auth) {
throw new functions.https.HttpsError(
"unauthenticated", "User must be signed in"
);
}
const { fileHash, fileName } = data;
if (!fileHash || !fileName) {
throw new functions.https.HttpsError(
"invalid-argument", "fileHash and fileName required"
);
}
// Simulate threat analysis (replace with real detection)
console.log("Analyzing:", fileName, "hash:", fileHash);
const threatScore = Math.random() * 100;
const isThreat = threatScore > 80;
// Store result
await db.collection("analysis").add({
userId: context.auth.uid,
fileHash,
fileName,
threatScore,
isThreat,
analyzedAt: admin.firestore.FieldValue.serverTimestamp()
});
console.log("Analysis complete. Threat:", isThreat);
return {
fileName,
isThreat,
threatScore,
message: isThreat ? "Threat detected" : "File appears safe"
};
});
Scheduled Functions
// Daily cleanup of old scan records (runs at midnight)
exports.dailyCleanup = functions.pubsub
.schedule("0 0 * * *")
.onRun(async (context) => {
const cutoff = new Date();
cutoff.setDate(cutoff.getDate() - 90); // 90 days retention
const oldScans = await db.collection("scans")
.where("timestamp", "<", cutoff)
.limit(500)
.get();
let deleted = 0;
const batch = db.batch();
oldScans.forEach((doc) => {
batch.delete(doc.ref);
deleted++;
});
if (deleted > 0) {
await batch.commit();
}
console.log("Cleanup complete. Deleted:", deleted, "old scans");
return null;
});
Common Mistakes
1. Cold Starts
Functions that haven't been invoked recently take longer to respond. Keep critical functions warm by setting minInstances on frequently used functions.
2. Not Handling Errors Properly
Unhandled promise rejections cause silent failures. Always use try/catch and return meaningful error objects for HTTPS callable functions.
3. Exceeding Timeout Limits
Functions timeout after 60 seconds (default) or up to 540 seconds (configured). Long-running tasks should use work queues or split into multiple functions.
4. Making Unnecessary Network Calls
Accessing external APIs or databases adds latency. Cache frequent lookups and minimize network dependencies in latency-sensitive functions.
5. Forgetting to Return a Promise
Non-async functions that start async operations may terminate before completion. Always return a promise from your function handler.
Practice Questions
- What is a cold start in Cloud Functions?
- How do you restrict an HTTPS callable function to authenticated users?
- What triggers are available for Cloud Functions?
- How do you schedule a function to run periodically?
Answers:
- A cold start happens when a function is invoked after being idle. The runtime initializes a new container, adding latency. Set
minInstancesto keep functions warm. - Check
context.authin the function body. If null, throw anunauthenticatederror. - Firestore (create, update, delete, write), Auth (create, delete), Storage (upload, delete), PubSub (scheduled, topic), HTTPS, and more.
- Use
functions.pubsub.schedule("cron expression").onRun()to run functions on a schedule.
Challenge: Write a Cloud Function that triggers on Firestore threat alert creation, sends a push notification via Firebase Cloud Messaging, logs the notification in a subcollection, and updates the alert status to "notified".
FAQ
Mini Project
Build a serverless threat analysis pipeline: Firestore trigger for new scans, alert creation for critical threats, scheduled daily cleanup of old scans, and an HTTPS callable function for on-demand file analysis.
What's Next
Cloud Function Triggers — explore all trigger types and event-driven patterns.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro