This documentation provides comprehensive guidance on using, extending, and maintaining your Firebase backend through Trae AI's MCP (Model Context Protocol) integration.
- Overview
- Architecture
- Setup and Configuration
- Authentication Integration
- Firestore Operations
- Storage Management
- Cloud Functions
- Security Rules
- Deployment and CI/CD
- Monitoring and Debugging
- Best Practices
- Troubleshooting
- Extending the System
The Firebase MCP integration provides a comprehensive backend solution that automates Firebase service management through Trae AI. This system includes:
- Automated Code Generation: Generate Firebase initialization, CRUD operations, and Cloud Functions
- Intelligent Deployment: Automated CI/CD pipelines with environment-specific configurations
- Security Management: Dynamic security rules with role-based access control
- Performance Optimization: Automated caching, indexing, and resource optimization
- Monitoring Integration: Real-time logging, analytics, and error tracking
┌─────────────────────────────────────────────────────────────┐
│ Trae AI MCP Layer │
├─────────────────────────────────────────────────────────────┤
│ Firebase MCP Integration │ Automated Management │
│ - Code Generation │ - Deployment Automation │
│ - Rule Management │ - Performance Monitoring │
│ - Security Validation │ - Error Handling │
├─────────────────────────────────────────────────────────────┤
│ Firebase Services │
├─────────────────┬─────────────────┬─────────────────────────┤
│ Authentication │ Firestore │ Storage │
│ - User Management │ - Database Ops │ - File Management │
│ - Social Login │ - Real-time │ - Image Processing │
│ - Role-based Auth │ - Transactions │ - CDN Integration │
├─────────────────┼─────────────────┼─────────────────────────┤
│ Cloud Functions │ Analytics │ Hosting │
│ - HTTP Triggers │ - Event Tracking│ - Static Assets │
│ - Background Jobs │ - Performance │ - PWA Support │
│ - Webhooks │ - Custom Events│ - SSL/CDN │
└─────────────────┴─────────────────┴─────────────────────────┘
project-root/
├── src/
│ ├── lib/
│ │ ├── firebase-mcp-integration.ts # Core MCP integration
│ │ ├── firestore-mcp-operations.ts # Enhanced Firestore ops
│ │ └── storage-mcp-operations.ts # Enhanced Storage ops
│ └── components/
│ └── auth/
│ └── FirebaseAuthProvider.tsx # Auth context provider
├── functions/
│ └── src/
│ ├── index.ts # Function exports
│ └── mcp-enhanced-functions.ts # MCP-enhanced functions
├── docs/
│ └── firebase-mcp-integration.md # This documentation
├── .github/
│ └── workflows/
│ └── firebase-mcp-deploy.yml # CI/CD pipeline
├── firestore-mcp-rules.rules # Enhanced Firestore rules
├── storage-mcp-rules.rules # Enhanced Storage rules
└── firebase.json # Firebase configuration
Create environment-specific configuration files:
# .env.local (Development)
FIREBASE_PROJECT_ID=your-dev-project
FIREBASE_API_KEY=your-dev-api-key
FIREBASE_AUTH_DOMAIN=your-dev-project.firebaseapp.com
FIREBASE_STORAGE_BUCKET=your-dev-project.appspot.com
# MCP Configuration
MCP_SERVER_NAME=firebase-mcp
MCP_AUTO_DEPLOY=true
MCP_ENVIRONMENT_SYNC=true
MCP_LOGGING_LEVEL=debug
# .env.production
FIREBASE_PROJECT_ID=your-prod-project
# ... production values
MCP_LOGGING_LEVEL=error# Install Firebase CLI
npm install -g firebase-tools
# Login to Firebase
firebase login
# Initialize project
firebase init
# Select services:
# ✓ Firestore
# ✓ Functions
# ✓ Storage
# ✓ Emulators// src/lib/firebase-config.ts
import { initializeFirebaseMCP } from './firebase-mcp-integration';
const firebaseConfig = {
// Your Firebase config
};
const mcpConfig = {
serverName: process.env.MCP_SERVER_NAME || 'firebase-mcp',
autoDeployment: process.env.MCP_AUTO_DEPLOY === 'true',
environmentSync: process.env.MCP_ENVIRONMENT_SYNC === 'true',
logging: {
level: process.env.MCP_LOGGING_LEVEL || 'info',
enableAnalytics: true,
enableErrorTracking: true
}
};
export const { auth, firestore, storage, functions, analytics } =
initializeFirebaseMCP(firebaseConfig, mcpConfig);// App.tsx
import { FirebaseAuthProvider } from './components/auth/FirebaseAuthProvider';
function App() {
return (
<FirebaseAuthProvider>
<YourAppComponents />
</FirebaseAuthProvider>
);
}// components/LoginForm.tsx
import { useAuth } from '../auth/FirebaseAuthProvider';
function LoginForm() {
const {
user,
loading,
signInWithEmail,
signInWithGoogle,
signOut
} = useAuth();
const handleLogin = async (email: string, password: string) => {
try {
await signInWithEmail(email, password);
} catch (error) {
console.error('Login failed:', error);
}
};
if (loading) return <div>Loading...</div>;
if (user) return <div>Welcome, {user.displayName}!</div>;
return (
<form onSubmit={(e) => {
e.preventDefault();
const formData = new FormData(e.target);
handleLogin(
formData.get('email') as string,
formData.get('password') as string
);
}}>
<input name="email" type="email" required />
<input name="password" type="password" required />
<button type="submit">Sign In</button>
<button type="button" onClick={signInWithGoogle}>
Sign In with Google
</button>
</form>
);
}// Custom user profile management
const { updateUserProfile, deleteAccount, verifyEmail } = useAuth();
// Update user profile
await updateUserProfile({
displayName: 'New Name',
photoURL: 'https://example.com/photo.jpg'
});
// Send email verification
await verifyEmail();
// Delete user account
await deleteAccount();import { firestoreMCP } from '../lib/firestore-mcp-operations';
// Create document
const user = await firestoreMCP.createDocument('users', {
name: 'John Doe',
email: 'john@example.com',
createdAt: new Date()
});
// Read document
const userData = await firestoreMCP.getDocument('users', user.id);
// Update document
await firestoreMCP.updateDocument('users', user.id, {
lastLoginAt: new Date()
});
// Delete document
await firestoreMCP.deleteDocument('users', user.id);// Complex queries with filtering and pagination
const { documents, hasMore, nextCursor } = await firestoreMCP.getDocuments(
'orders',
{
where: [
['userId', '==', currentUser.uid],
['status', 'in', ['pending', 'processing']],
['createdAt', '>=', startDate]
],
orderBy: [['createdAt', 'desc']],
limit: 20,
startAfter: cursor
}
);
// Search functionality
const searchResults = await firestoreMCP.searchDocuments(
'products',
'search query',
{
searchFields: ['name', 'description'],
limit: 10
}
);// Listen to document changes
const unsubscribe = firestoreMCP.listenToDocument(
'users',
userId,
(userData) => {
console.log('User data updated:', userData);
},
(error) => {
console.error('Subscription error:', error);
}
);
// Listen to collection changes
const unsubscribeCollection = firestoreMCP.listenToCollection(
'orders',
{ where: [['userId', '==', currentUser.uid]] },
(orders) => {
console.log('Orders updated:', orders);
}
);
// Cleanup subscriptions
unsubscribe();
unsubscribeCollection();// Batch operations
const batchOperations = [
{ type: 'create', collection: 'orders', data: orderData },
{ type: 'update', collection: 'inventory', id: productId, data: { quantity: newQuantity } },
{ type: 'delete', collection: 'cart', id: cartId }
];
await firestoreMCP.batchWrite(batchOperations);
// Transactions
const result = await firestoreMCP.runTransaction(async (transaction) => {
const productDoc = await transaction.get('products', productId);
const currentStock = productDoc.data().stock;
if (currentStock < orderQuantity) {
throw new Error('Insufficient stock');
}
transaction.update('products', productId, {
stock: currentStock - orderQuantity
});
transaction.create('orders', {
productId,
quantity: orderQuantity,
userId: currentUser.uid,
createdAt: new Date()
});
return { success: true, newStock: currentStock - orderQuantity };
});import { storageMCP } from '../lib/storage-mcp-operations';
// Simple file upload
const uploadResult = await storageMCP.uploadFile(
file,
`users/${userId}/profile.jpg`,
{
metadata: {
contentType: file.type,
customMetadata: {
uploadedBy: userId,
uploadedAt: new Date().toISOString()
}
}
}
);
// Upload with progress tracking
const uploadTask = storageMCP.uploadFileResumable(
file,
`users/${userId}/documents/${file.name}`,
{
onProgress: (progress) => {
console.log(`Upload progress: ${progress.percentage}%`);
setUploadProgress(progress.percentage);
},
onError: (error) => {
console.error('Upload error:', error);
},
onComplete: (result) => {
console.log('Upload completed:', result);
}
}
);
// Pause/resume/cancel upload
uploadTask.pause();
uploadTask.resume();
uploadTask.cancel();// Upload and process image
const processedImage = await storageMCP.uploadAndProcessImage(
imageFile,
`images/${userId}/photo.jpg`,
{
resize: { width: 800, height: 600 },
quality: 0.8,
format: 'webp',
generateThumbnail: true,
thumbnailSize: { width: 200, height: 200 }
}
);
console.log('Original URL:', processedImage.originalUrl);
console.log('Optimized URL:', processedImage.optimizedUrl);
console.log('Thumbnail URL:', processedImage.thumbnailUrl);// Get file information
const fileInfo = await storageMCP.getFileInfo('users/123/document.pdf');
console.log('File size:', fileInfo.size);
console.log('Content type:', fileInfo.contentType);
console.log('Download URL:', fileInfo.downloadUrl);
// List files in directory
const files = await storageMCP.listFiles('users/123/', {
maxResults: 50,
pageToken: nextPageToken
});
// Copy file
await storageMCP.copyFile(
'users/123/temp/document.pdf',
'users/123/documents/document.pdf'
);
// Move file
await storageMCP.moveFile(
'users/123/uploads/image.jpg',
'users/123/gallery/image.jpg'
);
// Delete file
await storageMCP.deleteFile('users/123/temp/old-file.pdf');// functions/src/api/users.ts
import { createMCPFunction } from '../mcp-enhanced-functions';
export const getUser = createMCPFunction(
{ memory: '256MB', timeout: 30 },
async (req, res) => {
const { userId } = req.params;
try {
const userData = await admin.firestore()
.collection('users')
.doc(userId)
.get();
if (!userData.exists) {
return res.status(404).json({ error: 'User not found' });
}
res.json({ user: userData.data() });
} catch (error) {
console.error('Error fetching user:', error);
res.status(500).json({ error: 'Internal server error' });
}
}
);
export const updateUser = createMCPFunction(
{ memory: '512MB', timeout: 60 },
async (req, res) => {
const { userId } = req.params;
const updateData = req.body;
// Validate request
if (!validateUserUpdateData(updateData)) {
return res.status(400).json({ error: 'Invalid data' });
}
try {
await admin.firestore()
.collection('users')
.doc(userId)
.update({
...updateData,
updatedAt: admin.firestore.FieldValue.serverTimestamp()
});
res.json({ success: true });
} catch (error) {
console.error('Error updating user:', error);
res.status(500).json({ error: 'Internal server error' });
}
}
);// functions/src/triggers/orders.ts
import { createMCPFunction } from '../mcp-enhanced-functions';
export const processNewOrder = createMCPFunction(
{ memory: '1GB', timeout: 300 },
functions.firestore.document('orders/{orderId}').onCreate(async (snap, context) => {
const orderData = snap.data();
const orderId = context.params.orderId;
try {
// Validate order data
await validateOrderData(orderData);
// Update inventory
await updateInventory(orderData.items);
// Process payment
const paymentResult = await processPayment(orderData);
// Send notifications
await sendOrderNotifications(orderId, orderData);
// Update order status
await snap.ref.update({
status: 'confirmed',
paymentId: paymentResult.id,
processedAt: admin.firestore.FieldValue.serverTimestamp()
});
console.log(`Order ${orderId} processed successfully`);
} catch (error) {
console.error(`Error processing order ${orderId}:`, error);
// Update order with error status
await snap.ref.update({
status: 'failed',
error: error.message,
failedAt: admin.firestore.FieldValue.serverTimestamp()
});
// Send error notification
await sendErrorNotification(orderId, error);
}
})
);// functions/src/scheduled/cleanup.ts
export const dailyCleanup = createMCPFunction(
{ memory: '512MB', timeout: 540 },
functions.pubsub.schedule('0 2 * * *').onRun(async (context) => {
console.log('Starting daily cleanup...');
try {
// Clean up expired sessions
await cleanupExpiredSessions();
// Remove old temporary files
await cleanupTempFiles();
// Archive old logs
await archiveOldLogs();
// Generate daily reports
await generateDailyReports();
console.log('Daily cleanup completed successfully');
} catch (error) {
console.error('Daily cleanup failed:', error);
await sendAdminNotification('Daily cleanup failed', error.message);
}
})
);The enhanced Firestore rules provide:
- Role-based Access Control: Admin, moderator, and user roles
- Data Validation: Required fields, format validation, size limits
- Privacy Controls: Public, private, and friends-only access
- Rate Limiting: Basic rate limiting for sensitive operations
- Audit Logging: Automatic logging of security events
// firestore-mcp-rules.rules
function isOwner(userId) {
return isAuthenticated() && request.auth.uid == userId;
}
function hasRole(role) {
return isAuthenticated() &&
exists(/databases/$(database)/documents/users/$(request.auth.uid)) &&
get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == role;
}
function isValidEmail(email) {
return email.matches('^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$');
}The enhanced Storage rules provide:
- File Type Validation: Restrict uploads by MIME type
- Size Limits: Different limits for different file types
- Path-based Security: User-specific and role-based access
- Metadata Validation: Required metadata for uploads
- Content Scanning: Integration with content moderation
The CI/CD pipeline includes:
-
Code Quality Checks
- Linting and formatting
- Type checking
- Security scanning
- Dependency auditing
-
Testing
- Unit tests
- Integration tests
- Security rule tests
- End-to-end tests
-
Deployment
- Environment-specific deployments
- Gradual rollouts
- Rollback capabilities
- Health checks
-
Post-deployment
- Smoke tests
- Performance monitoring
- Error tracking
- Notifications
# Deploy to development
npm run deploy:dev
# Deploy to staging
npm run deploy:staging
# Deploy to production
npm run deploy:prod
# Deploy specific services
firebase deploy --only functions
firebase deploy --only firestore:rules
firebase deploy --only storage
# Deploy with MCP rules
cp firestore-mcp-rules.rules firestore.rules
cp storage-mcp-rules.rules storage.rules
firebase deploy --only firestore:rules,storage# Set environment variables for functions
firebase functions:config:set \
app.environment="production" \
app.debug="false" \
stripe.secret_key="sk_live_..." \
sendgrid.api_key="SG..."
# Deploy configuration
firebase deploy --only functions:config// Enhanced logging with MCP integration
import { logger } from '../lib/firebase-mcp-integration';
// Structured logging
logger.info('User action', {
userId: user.uid,
action: 'profile_update',
timestamp: new Date().toISOString(),
metadata: { field: 'displayName' }
});
// Error tracking
logger.error('Payment processing failed', {
orderId,
error: error.message,
stack: error.stack,
userId: user.uid
});
// Performance monitoring
logger.performance('database_query', {
collection: 'orders',
duration: queryDuration,
resultCount: results.length
});// Monitor function performance
export const monitoredFunction = createMCPFunction(
{
memory: '256MB',
timeout: 30,
monitoring: {
enableMetrics: true,
enableTracing: true,
alertThresholds: {
errorRate: 0.05,
latency: 5000
}
}
},
async (req, res) => {
const startTime = Date.now();
try {
// Function logic here
const result = await processRequest(req);
// Log success metrics
logger.metric('function_success', {
duration: Date.now() - startTime,
endpoint: req.path
});
res.json(result);
} catch (error) {
// Log error metrics
logger.metric('function_error', {
duration: Date.now() - startTime,
endpoint: req.path,
error: error.message
});
throw error;
}
}
);// Enable debug mode in development
if (process.env.NODE_ENV === 'development') {
// Enable Firestore debug logging
firebase.firestore.setLogLevel('debug');
// Enable detailed MCP logging
mcpConfig.logging.level = 'debug';
mcpConfig.logging.enableVerbose = true;
}-
Authentication
- Always validate user authentication
- Use role-based access control
- Implement proper session management
- Enable multi-factor authentication for admin users
-
Data Validation
- Validate all input data
- Use TypeScript for type safety
- Implement server-side validation
- Sanitize user inputs
-
Security Rules
- Follow principle of least privilege
- Test rules thoroughly
- Use helper functions for complex logic
- Regular security audits
-
Database Optimization
- Use appropriate indexes
- Implement pagination
- Cache frequently accessed data
- Use batch operations when possible
-
Storage Optimization
- Compress images before upload
- Use appropriate file formats
- Implement CDN caching
- Clean up unused files
-
Function Optimization
- Use appropriate memory allocation
- Implement connection pooling
- Cache external API responses
- Use async/await properly
-
Modular Structure
- Separate concerns into modules
- Use consistent naming conventions
- Implement proper error handling
- Document complex logic
-
Type Safety
- Define interfaces for all data structures
- Use strict TypeScript configuration
- Validate runtime data
- Use discriminated unions for state management
// Issue: User not authenticated after login
// Solution: Check token refresh
const checkAuthState = () => {
auth.onAuthStateChanged((user) => {
if (user) {
// User is signed in
user.getIdToken(true).then((token) => {
// Use fresh token
console.log('Fresh token:', token);
});
} else {
// User is signed out
console.log('User signed out');
}
});
};// Issue: Permission denied errors
// Solution: Check security rules and user roles
const debugPermissions = async (collection: string, docId: string) => {
try {
const doc = await firestore.collection(collection).doc(docId).get();
console.log('Document accessible:', doc.exists);
} catch (error) {
console.error('Permission error:', error);
// Check user authentication
const user = auth.currentUser;
if (!user) {
console.log('User not authenticated');
return;
}
// Check user role
const userDoc = await firestore.collection('users').doc(user.uid).get();
console.log('User role:', userDoc.data()?.role);
}
};# Issue: Function deployment fails
# Solution: Check logs and dependencies
# View deployment logs
firebase functions:log
# Check function status
firebase functions:list
# Test function locally
firebase emulators:start --only functions
# Debug specific function
firebase functions:log --only functionName// Issue: Slow query performance
// Solution: Add appropriate indexes
const optimizeQuery = async () => {
// Before: Slow query without index
const slowQuery = firestore
.collection('orders')
.where('userId', '==', userId)
.where('status', '==', 'pending')
.orderBy('createdAt', 'desc');
// After: Add composite index in firestore.indexes.json
// {
// "collectionGroup": "orders",
// "queryScope": "COLLECTION",
// "fields": [
// { "fieldPath": "userId", "order": "ASCENDING" },
// { "fieldPath": "status", "order": "ASCENDING" },
// { "fieldPath": "createdAt", "order": "DESCENDING" }
// ]
// }
};- Define Data Model
// types/models.ts
export interface Product {
id: string;
name: string;
description: string;
price: number;
category: string;
imageUrl: string;
stock: number;
createdAt: Date;
updatedAt: Date;
}- Add Security Rules
// firestore-mcp-rules.rules
match /products/{productId} {
allow read: if true; // Public read
allow create, update: if isAdmin() || isOwner(resource.data.ownerId);
allow delete: if isAdmin();
}- Create CRUD Operations
// lib/products.ts
import { firestoreMCP } from './firestore-mcp-operations';
export const productService = {
async createProduct(data: Omit<Product, 'id' | 'createdAt' | 'updatedAt'>) {
return firestoreMCP.createDocument('products', {
...data,
createdAt: new Date(),
updatedAt: new Date()
});
},
async getProduct(id: string) {
return firestoreMCP.getDocument('products', id);
},
async updateProduct(id: string, data: Partial<Product>) {
return firestoreMCP.updateDocument('products', id, {
...data,
updatedAt: new Date()
});
},
async deleteProduct(id: string) {
return firestoreMCP.deleteDocument('products', id);
}
};- Create Function File
// functions/src/api/products.ts
import { createMCPFunction } from '../mcp-enhanced-functions';
export const getProducts = createMCPFunction(
{ memory: '256MB', timeout: 30 },
async (req, res) => {
try {
const { category, limit = 20, offset = 0 } = req.query;
let query = admin.firestore().collection('products');
if (category) {
query = query.where('category', '==', category);
}
const snapshot = await query
.orderBy('createdAt', 'desc')
.limit(Number(limit))
.offset(Number(offset))
.get();
const products = snapshot.docs.map(doc => ({
id: doc.id,
...doc.data()
}));
res.json({ products, total: snapshot.size });
} catch (error) {
console.error('Error fetching products:', error);
res.status(500).json({ error: 'Internal server error' });
}
}
);- Export Function
// functions/src/index.ts
export { getProducts } from './api/products';// lib/custom-mcp-operations.ts
import { MCPConfig } from './firebase-mcp-integration';
export class CustomMCPOperations {
constructor(private config: MCPConfig) {}
async generateReport(type: string, params: any) {
// Custom report generation logic
const reportData = await this.collectReportData(type, params);
// Log operation
this.logOperation('generate_report', { type, params });
// Trigger MCP sync if needed
if (this.config.autoDeployment) {
await this.triggerMCPSync('report_generated', reportData);
}
return reportData;
}
private async collectReportData(type: string, params: any) {
// Implementation specific to report type
switch (type) {
case 'user_analytics':
return this.generateUserAnalytics(params);
case 'sales_report':
return this.generateSalesReport(params);
default:
throw new Error(`Unknown report type: ${type}`);
}
}
private async triggerMCPSync(event: string, data: any) {
// Trigger MCP server sync
console.log(`MCP sync triggered: ${event}`, data);
}
private logOperation(operation: string, data: any) {
if (this.config.logging.enableAnalytics) {
console.log(`Custom MCP operation: ${operation}`, data);
}
}
}// lib/integrations/stripe-integration.ts
import { createMCPFunction } from '../../functions/src/mcp-enhanced-functions';
export const handleStripeWebhook = createMCPFunction(
{ memory: '512MB', timeout: 60 },
async (req, res) => {
const sig = req.headers['stripe-signature'];
const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;
try {
const event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
switch (event.type) {
case 'payment_intent.succeeded':
await handlePaymentSuccess(event.data.object);
break;
case 'customer.subscription.created':
await handleSubscriptionCreated(event.data.object);
break;
default:
console.log(`Unhandled event type: ${event.type}`);
}
res.json({ received: true });
} catch (error) {
console.error('Webhook error:', error);
res.status(400).send(`Webhook Error: ${error.message}`);
}
}
);This Firebase MCP integration provides a comprehensive, scalable, and maintainable backend solution for your web application. The system is designed to grow with your needs while maintaining security, performance, and developer productivity.
For additional support or questions:
- Check the Firebase Documentation
- Review the MCP Protocol Specification
- Consult the project's issue tracker for known issues
- Reach out to the development team for custom requirements
Remember to regularly update dependencies, monitor performance metrics, and review security configurations to ensure your application remains secure and performant.