Migrating from Firebase Functions to Conduit Link
A step-by-step guide to replacing Firebase Functions proxy endpoints with Conduit Link for better performance and lower costs.
Conduit Link Team
Technical Content Writers
Migrating from Firebase Functions to Conduit Link
If you're using Firebase Functions as API proxies to hide your third-party API keys, you're not alone. It's a common pattern, but it comes with significant drawbacks: cold starts, vendor lock-in, complex deployment, and rising costs. Let's explore how to migrate to Conduit Link for a better solution.
Why Developers Use Firebase Functions for API Proxies
Firebase Functions seem like a natural choice for API proxying:
- Already using Firebase for other services
- Serverless architecture promises simplicity
- Built-in authentication with Firebase Auth
- Pay-per-use pricing model
However, the reality often falls short of expectations.
The Hidden Costs of Firebase Functions
1. Cold Start Latency
Firebase Functions suffer from notorious cold starts:
// Your users experience this delay
// First request: 2-5 seconds (cold start)
// Subsequent requests: 200-300ms
exports.proxyOpenAI = functions.https.onRequest(async (req, res) => {
// Cold start happens here
const response = await fetch('https://api.openai.com/v1/completions', {
headers: { 'Authorization': Bearer ${process.env.OPENAI_KEY}
},
// ...
});
});
2. Complex Local Development
Testing Firebase Functions locally requires emulators and setup:
Install emulators
firebase init emulatorsStart emulators (uses significant resources)
firebase emulators:startYour simple API proxy now needs all this infrastructure
3. Deployment Complexity
Every small change requires a full deployment:
Change one line of code?
Wait 2-3 minutes for deployment
firebase deploy --only functionsMeanwhile, your users might experience downtime
4. Escalating Costs
What starts cheap quickly becomes expensive:
Conduit Link: A Purpose-Built Alternative
Conduit Link is designed specifically for API proxying, eliminating the overhead of general-purpose serverless functions.
Performance Comparison
| Metric | Firebase Functions | Conduit Link | |--------|-------------------|--------------| | Cold Start | 2-5 seconds | None (always warm) | | Average Latency | 200-300ms | 20-50ms | | Setup Time | 30-60 minutes | 2 minutes | | Deployment | 2-3 minutes | Instant | | Local Testing | Complex emulators | Direct API calls |
Migration Guide: Step by Step
Step 1: Audit Your Firebase Functions
First, identify which functions are used for API proxying:
// Example: Firebase Function for OpenAI
exports.chatGPT = functions.https.onRequest(async (req, res) => {
// CORS handling
res.set('Access-Control-Allow-Origin', '*'); if (req.method === 'OPTIONS') {
res.set('Access-Control-Allow-Methods', 'POST');
res.set('Access-Control-Allow-Headers', 'Content-Type');
res.status(204).send('');
return;
}
try {
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': Bearer ${functions.config().openai.key}
,
'Content-Type': 'application/json'
},
body: JSON.stringify(req.body)
});
const data = await response.json();
res.json(data);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
Step 2: Create Equivalent Conduit Links
For each Firebase Function, create a Conduit Link:
https://api.openai.com/v1
- API Key: Your OpenAI key (encrypted and secure)
Step 3: Update Your Frontend Code
The migration requires minimal code changes:
// Before: Firebase Function
const response = await fetch('https://us-central1-your-project.cloudfunctions.net/chatGPT', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: messages
})
});// After: Conduit Link
const response = await fetch('https://proxy.conduit.link/YOUR-LINK-ID/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Access-Token': 'your-access-token' // Required for authentication
},
body: JSON.stringify({
model: 'gpt-3.5-turbo',
messages: messages
})
});
Step 4: Implement Authentication (If Needed)
If you're using Firebase Auth, you can integrate it with Conduit Link:
// Generate a custom JWT for Conduit Link
const generateConduitToken = async (user) => {
const firebaseToken = await user.getIdToken(); // Your backend validates Firebase token and issues Conduit JWT
const response = await fetch('/api/auth/conduit-token', {
headers: { 'Authorization': Bearer ${firebaseToken}
}
});
return response.json();
};
// Use the token with Conduit Link
const { token } = await generateConduitToken(currentUser);
const response = await fetch('https://proxy.conduit.link/YOUR-LINK-ID/api/data', {
headers: {
'Authorization': Bearer ${token}
}
});
Step 5: Migrate Rate Limiting
Convert Firebase Function rate limiting to Conduit Link configuration:
// Before: Manual rate limiting in Firebase
const rateLimit = new Map();exports.apiProxy = functions.https.onRequest(async (req, res) => {
const ip = req.ip;
const requests = rateLimit.get(ip) || 0;
if (requests > 100) {
res.status(429).send('Rate limit exceeded');
return;
}
rateLimit.set(ip, requests + 1);
// ... rest of function
});
// After: Configure in Conduit Link Dashboard
// - 100 requests per minute per IP
// - 1000 requests per hour per authenticated user
// - Custom limits based on JWT claims
Step 6: Update Error Handling
Conduit Link provides consistent error responses:
// Improved error handling
async function callAPI(endpoint, data) {
try {
const response = await fetch(https://proxy.conduit.link/YOUR-LINK-ID${endpoint}
, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
}); if (!response.ok) {
const error = await response.json();
switch (response.status) {
case 429:
// Rate limit exceeded
console.error('Rate limit:', error.reset_time);
break;
case 401:
// Invalid authentication
await refreshToken();
break;
case 403:
// Forbidden (check allowed paths)
console.error('Access denied:', error.message);
break;
}
}
return response.json();
} catch (error) {
// Network or parsing error
console.error('Request failed:', error);
}
}
Advanced Migration Scenarios
Migrating Complex Request Transformations
If your Firebase Functions modify requests:
// Before: Firebase Function with transformation
exports.translateAPI = functions.https.onRequest(async (req, res) => {
// Transform request
const modifiedBody = {
...req.body,
source_lang: 'auto',
target_lang: req.body.lang || 'en',
api_key: functions.config().translate.key
}; const response = await fetch('https://api.translate.com/v2/translate', {
method: 'POST',
body: JSON.stringify(modifiedBody)
});
});
// After: Use Conduit Link request templates
// Configure in dashboard:
// - Request template to add default fields
// - Header injection for API keys
// - Response transformation if needed
Handling WebSocket Connections
For real-time APIs:
// Conduit Link supports WebSocket proxying
const ws = new WebSocket('wss://proxy.conduit.link/YOUR-LINK-ID/ws');ws.on('open', () => {
ws.send(JSON.stringify({
type: 'auth',
token: yourJWT
}));
});
ws.on('message', (data) => {
// Handle real-time data
});
Batch Request Migration
Convert Firebase batch processing:
// Before: Custom batch handling in Firebase
exports.batchProcess = functions.https.onRequest(async (req, res) => {
const results = await Promise.all(
req.body.items.map(item => processItem(item))
);
res.json(results);
});// After: Use Conduit Link with concurrent requests
const batchProcess = async (items) => {
const promises = items.map(item =>
fetch('https://proxy.conduit.link/YOUR-LINK-ID/process', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(item)
})
);
return Promise.all(promises);
};
Post-Migration Optimization
1. Monitor Performance
Use Conduit Link's analytics to track:
2. Optimize Caching
Configure intelligent caching:
// Add cache headers for appropriate endpoints
const response = await fetch('https://proxy.conduit.link/YOUR-LINK-ID/api/metadata', {
headers: {
'Cache-Control': 'max-age=3600' // Cache for 1 hour
}
});
3. Implement Gradual Migration
For large applications, migrate incrementally:
// Feature flag for gradual rollout
const useConduitLink = await getFeatureFlag('use_conduit_link');const apiUrl = useConduitLink
? 'https://proxy.conduit.link/YOUR-LINK-ID'
: 'https://us-central1-your-project.cloudfunctions.net';
Cost Comparison
Firebase Functions (Monthly)
Conduit Link (Monthly)
Migration Checklist
Common Gotchas and Solutions
CORS Configuration
Ensure your Conduit Link CORS settings match your Firebase Function:
// Check current CORS headers in Firebase
// Replicate in Conduit Link dashboard
Environment-Specific URLs
Use environment variables for easy switching:
const API_BASE = process.env.REACT_APP_API_BASE;
// Development: Firebase Functions
// Production: Conduit Link
Request Size Limits
Conduit Link supports larger payloads than Firebase Functions:
Conclusion
Migrating from Firebase Functions to Conduit Link typically takes less than an hour and provides immediate benefits:
Ready to migrate? Start your free trial →
Need help with migration? Contact our support team for personalized assistance.
Ready to Secure Your APIs?
Join thousands of developers who trust Conduit Link to protect their API keys and build secure applications.