Firebase Cloud Functions v2 provides a built-in logger module with severity levels: logger.info(), logger.warn(), logger.error(), and logger.debug(). Import it from firebase-functions/logger and use structured logging with JSON objects for rich metadata. View logs in the Firebase Console under Functions > Logs or in Google Cloud Logging for advanced filtering and alerting.
Error Logging in Firebase Cloud Functions
Effective error logging is critical for debugging Cloud Functions in production. This tutorial covers the Firebase Functions logger module, structured logging with JSON metadata, severity levels for categorizing log output, viewing logs in the Firebase Console and Google Cloud Logging, and setting up alerts to notify you when errors occur. You will learn patterns for logging errors in HTTP functions, Firestore triggers, and callable functions.
Prerequisites
- A Firebase project on the Blaze plan
- Firebase CLI installed and logged in
- Cloud Functions initialized in your project (firebase init functions)
- At least one deployed Cloud Function
Step-by-step guide
Import the Firebase Functions logger
Import the Firebase Functions logger
The firebase-functions package includes a built-in logger module that integrates directly with Google Cloud Logging. Import it at the top of your functions file. The logger provides four severity levels: debug, info, warn, and error. Each level appears with a different severity in Cloud Logging, making it easy to filter for errors in production. Avoid using console.log() in production functions because it lacks severity levels and structured metadata.
1import { logger } from 'firebase-functions/v2';2import { onRequest } from 'firebase-functions/v2/https';34// Use logger instead of console.log5export const myFunction = onRequest(async (req, res) => {6 logger.info('Function started', { method: req.method, path: req.path });78 try {9 // Your function logic here10 logger.info('Operation completed successfully');11 res.status(200).send('OK');12 } catch (error) {13 logger.error('Function failed', { error: String(error) });14 res.status(500).send('Internal error');15 }16});Expected result: Your function logs appear with proper severity levels in Firebase Console and Cloud Logging.
Use structured logging with metadata objects
Use structured logging with metadata objects
Pass a JSON object as the second argument to any logger method to attach structured metadata. This metadata appears as searchable fields in Cloud Logging, making it much easier to filter and investigate issues. Include relevant context like user IDs, document paths, request parameters, and error details. Structured logs are more useful than string interpolation because they support advanced queries.
1import { logger } from 'firebase-functions/v2';2import { onDocumentCreated } from 'firebase-functions/v2/firestore';34export const onUserCreated = onDocumentCreated(5 'users/{userId}',6 async (event) => {7 const userId = event.params.userId;8 const userData = event.data?.data();910 logger.info('New user created', {11 userId,12 email: userData?.email,13 provider: userData?.provider,14 timestamp: new Date().toISOString()15 });1617 try {18 // Send welcome email, create profile, etc.19 logger.info('Welcome email sent', { userId });20 } catch (error: any) {21 logger.error('Failed to process new user', {22 userId,23 errorCode: error.code,24 errorMessage: error.message,25 stack: error.stack26 });27 }28 }29);Expected result: Log entries include structured JSON metadata that can be filtered and queried in Cloud Logging.
Log errors in callable functions with context
Log errors in callable functions with context
Callable functions (onCall) receive authentication context automatically. Include the caller's UID and other auth details in error logs to trace issues to specific users. Always log errors before throwing HttpsError so the error context is captured even though the client receives a generic error message.
1import { logger } from 'firebase-functions/v2';2import { onCall, HttpsError } from 'firebase-functions/v2/https';34export const processOrder = onCall(async (request) => {5 const uid = request.auth?.uid;6 const orderData = request.data;78 logger.info('Processing order', {9 uid,10 orderId: orderData.orderId,11 amount: orderData.amount12 });1314 if (!uid) {15 logger.warn('Unauthenticated order attempt', {16 ip: request.rawRequest.ip17 });18 throw new HttpsError('unauthenticated', 'Must be signed in');19 }2021 try {22 // Process the order23 logger.info('Order processed successfully', {24 uid,25 orderId: orderData.orderId26 });27 return { success: true };28 } catch (error: any) {29 logger.error('Order processing failed', {30 uid,31 orderId: orderData.orderId,32 errorCode: error.code,33 errorMessage: error.message,34 stack: error.stack35 });36 throw new HttpsError('internal', 'Failed to process order');37 }38});Expected result: Error logs include the user UID, order details, and full error information for debugging.
View logs in the Firebase Console
View logs in the Firebase Console
Open the Firebase Console, go to Functions in the left sidebar, and click the Logs tab. You can filter by function name, severity level, and time range. Each log entry shows the severity icon, timestamp, function name, and message. Click any entry to expand it and see the structured metadata. For more advanced filtering, click the 'View in Cloud Logging' link to open Google Cloud Logging with full query support.
Expected result: You can see your function's log output filtered by severity and function name in the Firebase Console.
Set up log-based alerts in Cloud Logging
Set up log-based alerts in Cloud Logging
Create alerts in Google Cloud Logging to notify you when errors occur in production. Go to Cloud Console > Logging > Logs Explorer, create a query that matches your error logs, then click Create Alert. Configure a notification channel (email, Slack, PagerDuty) and set the alert condition. This ensures you are notified immediately when functions fail instead of discovering errors hours or days later.
1# Cloud Logging query to find all function errors2resource.type="cloud_function"3severity=ERROR4resource.labels.function_name="processOrder"56# Query to find specific error patterns7resource.type="cloud_function"8severity>=WARNING9jsonPayload.errorCode="PERMISSION_DENIED"Expected result: You receive notifications when error-level logs are written by your Cloud Functions.
Complete working example
1import { logger } from 'firebase-functions/v2';2import { onRequest, onCall, HttpsError } from 'firebase-functions/v2/https';3import { onDocumentCreated } from 'firebase-functions/v2/firestore';4import { initializeApp } from 'firebase-admin/app';5import { getFirestore } from 'firebase-admin/firestore';67initializeApp();8const db = getFirestore();910// HTTP function with structured error logging11export const api = onRequest(async (req, res) => {12 const requestId = crypto.randomUUID();13 logger.info('API request received', {14 requestId,15 method: req.method,16 path: req.path,17 userAgent: req.headers['user-agent']18 });1920 try {21 const result = await db.collection('items').get();22 logger.info('Query successful', {23 requestId,24 documentCount: result.size25 });26 res.json({ items: result.docs.map(d => d.data()) });27 } catch (error: any) {28 logger.error('API request failed', {29 requestId,30 errorCode: error.code,31 errorMessage: error.message,32 stack: error.stack33 });34 res.status(500).json({ error: 'Internal server error' });35 }36});3738// Callable function with auth context logging39export const updateProfile = onCall(async (request) => {40 const uid = request.auth?.uid;41 if (!uid) {42 logger.warn('Unauthenticated profile update attempt');43 throw new HttpsError('unauthenticated', 'Sign in required');44 }4546 try {47 await db.collection('users').doc(uid).update(request.data);48 logger.info('Profile updated', { uid });49 return { success: true };50 } catch (error: any) {51 logger.error('Profile update failed', {52 uid,53 errorMessage: error.message54 });55 throw new HttpsError('internal', 'Update failed');56 }57});5859// Firestore trigger with error logging60export const onOrderCreated = onDocumentCreated(61 'orders/{orderId}',62 async (event) => {63 const orderId = event.params.orderId;64 const order = event.data?.data();6566 logger.info('New order received', {67 orderId,68 userId: order?.userId,69 total: order?.total70 });7172 try {73 // Process order logic74 logger.info('Order processed', { orderId });75 } catch (error: any) {76 logger.error('Order processing failed', {77 orderId,78 errorCode: error.code,79 errorMessage: error.message,80 stack: error.stack81 });82 }83 }84);Common mistakes when logging Errors in Firebase Cloud Functions
Why it's a problem: Using console.log() instead of the Firebase logger in production functions
How to avoid: Replace console.log() with logger.info() and console.error() with logger.error(). The Firebase logger adds proper severity levels and structured metadata support that console methods lack.
Why it's a problem: Logging sensitive data like API keys, passwords, or full user tokens
How to avoid: Never log sensitive information. Redact or mask sensitive fields before including them in log metadata. Log user IDs and request IDs instead of full tokens.
Why it's a problem: Not including enough context in error logs to reproduce the issue
How to avoid: Always include the function name, relevant document IDs, user UID, and the full error object (code, message, stack) in error log metadata.
Why it's a problem: Forgetting to log before throwing HttpsError in callable functions
How to avoid: HttpsError sends a sanitized message to the client but does not automatically create a log entry. Always call logger.error() before throwing the error so the details are captured in Cloud Logging.
Best practices
- Use the firebase-functions/v2 logger module instead of console.log for proper severity and metadata
- Attach structured JSON metadata to every log entry for searchable, filterable logs
- Include request IDs or correlation IDs to trace a single operation across multiple log entries
- Log at the appropriate severity level: debug for development, info for normal operations, warn for recoverable issues, error for failures
- Never log sensitive data including passwords, API keys, tokens, or personally identifiable information
- Set up log-based alerts in Cloud Logging for ERROR severity to catch production issues immediately
- Log both the start and completion of important operations to measure duration and identify hangs
- Include the error stack trace in error logs to pinpoint the exact line where failures occur
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
Show me how to implement structured error logging in Firebase Cloud Functions v2 using the built-in logger module. Include examples for HTTP functions, callable functions, and Firestore triggers, with proper severity levels and JSON metadata.
Write a Firebase Cloud Functions v2 module in TypeScript that demonstrates structured logging with the firebase-functions logger for an HTTP endpoint, a callable function with auth context, and a Firestore trigger. Include error handling that logs full error details including stack traces.
Frequently asked questions
What is the difference between console.log and the Firebase logger?
The Firebase logger (imported from firebase-functions/v2) writes structured logs with severity levels (INFO, WARNING, ERROR) that integrate with Google Cloud Logging. console.log writes plain text logs without severity, making them harder to filter and alert on in production.
How long are Cloud Functions logs retained?
By default, Cloud Logging retains logs for 30 days. You can configure longer retention periods or export logs to BigQuery or Cloud Storage for permanent archival. Custom retention is available at additional cost.
Can I view logs for a specific function only?
Yes. In the Firebase Console, go to Functions > Logs and use the function name dropdown to filter. In Cloud Logging, add resource.labels.function_name="yourFunctionName" to your query.
Does logger.debug() output appear in production?
By default, DEBUG level logs are not visible in production. Set the minimum log level to DEBUG in your function configuration to enable them. Keep debug logging disabled in production to reduce noise and logging costs.
How do I set up email alerts for function errors?
Go to Google Cloud Console > Logging > Logs Explorer, write a query for severity=ERROR with your function name, click Create Alert, and configure an email notification channel. You can also use Slack, PagerDuty, or webhook notification channels.
Are there costs associated with Cloud Functions logging?
Google Cloud Logging provides 50 GB of logs ingestion free per month. Beyond that, logging costs $0.50/GB. High-volume functions with verbose logging can generate significant log volume, so use appropriate severity levels and avoid logging large payloads.
Can RapidDev help set up monitoring and alerting for Firebase Functions?
Yes. RapidDev can implement comprehensive logging, monitoring dashboards in Cloud Monitoring, and alerting pipelines for your Firebase Cloud Functions, ensuring you catch production issues before they impact users.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation