| name | firebase-app-platform |
| description | Build and operate apps on Firebase using Auth, Firestore, Cloud Functions, and Hosting. Use when building mobile/web backends with managed services, real-time data sync, or serverless APIs. |
| license | MIT |
| metadata | {"author":"devops-skills","version":"1.0"} |
Firebase App Platform
Ship mobile and web backends with Firebase managed services.
When to Use This Skill
Use this skill when:
- Building mobile or web apps with real-time data sync
- Need authentication with minimal backend code
- Prototyping quickly with managed infrastructure
- Building serverless APIs with Cloud Functions
- Hosting static sites or SPAs with CDN
Prerequisites
- Node.js 18+
- Firebase CLI (
npm install -g firebase-tools)
- Google Cloud account (Firebase is part of GCP)
- A Firebase project (create at console.firebase.google.com)
Quick Start
npm install -g firebase-tools
firebase login
firebase init
firebase emulators:start
firebase deploy
firebase deploy --only functions
firebase deploy --only hosting
firebase deploy --only firestore:rules
Firestore Database
Security Rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
match /channels/{channelId}/messages/{messageId} {
allow read: if request.auth != null;
allow create: if request.auth != null
&& request.resource.data.userId == request.auth.uid
&& request.resource.data.body is string
&& request.resource.data.body.size() <= 5000;
allow update, delete: if request.auth != null
&& resource.data.userId == request.auth.uid;
}
match /admin/{document=**} {
allow read, write: if request.auth != null
&& get($(database)/documents/users/$(request..)).. == ;
}
match /{=**} {
allow read, : ;
}
}
}
Data Operations
import { getFirestore, collection, doc, setDoc, getDoc,
query, where, orderBy, limit, onSnapshot,
serverTimestamp, increment } from "firebase/firestore";
const db = getFirestore();
async function createMessage(channelId: string, body: string, userId: string) {
const ref = doc(collection(db, "channels", channelId, "messages"));
await setDoc(ref, {
body,
userId,
createdAt: serverTimestamp(),
});
return ref.id;
}
function subscribeToMessages(channelId: string, callback: (msgs: any[]) => void) {
const q = query(
collection(db, "channels", channelId, "messages"),
orderBy("createdAt", "desc"),
limit(50)
);
return onSnapshot(q, {
messages = snapshot..( ({ : doc., ...doc.() }));
(messages);
});
}
() {
((db, , postId), {
: (),
}, { : });
}
Indexes
{
"indexes": [
{
"collectionGroup": "messages",
"queryScope": "COLLECTION",
"fields": [
{ "fieldPath": "channelId", "order": "ASCENDING" },
{ "fieldPath": "createdAt", "order": "DESCENDING" }
]
}
]
}
Authentication
import { getAuth, signInWithPopup, GoogleAuthProvider,
createUserWithEmailAndPassword, signInWithEmailAndPassword,
signOut, onAuthStateChanged } from "firebase/auth";
const auth = getAuth();
async function signInWithGoogle() {
const provider = new GoogleAuthProvider();
const result = await signInWithPopup(auth, provider);
return result.user;
}
async function register(email: string, password: string) {
const result = await createUserWithEmailAndPassword(auth, email, password);
return result.user;
}
onAuthStateChanged(auth, (user) => {
if (user) {
console.log("Signed in:", user.uid, user.email);
} else {
console.log("Signed out");
}
});
Cloud Functions
import { onRequest } from "firebase-functions/v2/https";
import { onDocumentCreated } from "firebase-functions/v2/firestore";
import { getFirestore } from "firebase-admin/firestore";
import { initializeApp } from "firebase-admin/app";
initializeApp();
const db = getFirestore();
export const api = onRequest({ cors: true, region: "us-central1" }, async (req, res) => {
if (req.method !== "GET") {
res.status(405).send("Method not allowed");
return;
}
const snapshot = await db.collection("posts").orderBy("createdAt", "desc").limit(10).get();
const posts = snapshot.docs.map(doc => ({ id: doc.id, ...doc.() }));
res.({ posts });
});
onMessageCreated = (
,
(event) => {
data = event.?.();
(!data) ;
db.().({
: data.,
: .(),
});
.();
}
);
Hosting
{
"hosting": {
"public": "dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{ "source": "/api/**", "function": "api" },
{ "source": "**", "destination": "/index.html" }
],
"headers": [
{
"source": "**/*.@(js|css|svg|png|jpg|webp|woff2)",
"headers": [{ "key": "Cache-Control"
Local Emulators
firebase emulators:start
firebase emulators:start --only auth,firestore,functions
firebase emulators:export ./emulator-data
firebase emulators:start --import=./emulator-data
{
"emulators": {
"auth": { "port": 9099 },
"firestore": { "port": 8080 },
"functions": { "port": 5001 },
"hosting": { "port": 5000 },
"ui": { "enabled": true, "port": 4000 }
}
}
Environment Configuration
firebase functions:config:set stripe.key="sk_live_xxx" app.name="MyApp"
firebase functions:config:get
const stripeKey = functions.config().stripe.key;
STRIPE_KEY=sk_live_xxx
STRIPE_KEY=sk_test_xxx
Multi-Environment Setup
firebase use --add
firebase use staging
firebase use production
firebase deploy --project my-app-staging
firebase deploy --project my-app-production
{
"projects": {
"staging": "my-app-staging",
"production": "my-app-production"
}
}
CLI Reference
firebase projects:list
firebase deploy
firebase deploy --only functions
firebase deploy --only hosting
firebase deploy --only firestore
firebase functions:log
firebase hosting:channel:create pr-123
firebase hosting:channel:delete pr-123
Security Best Practices
- Write strict Firestore security rules before any other code
- Separate environments by Firebase project (staging/production)
- Enable budget alerts and quota monitoring in GCP console
- Move privileged logic into Cloud Functions (never trust the client)
- Use App Check to prevent API abuse from non-app clients
- Enable Firestore audit logging for compliance
- Review OAuth consent screen settings
Troubleshooting
| Issue | Solution |
|---|
| Permission denied | Check Firestore rules, verify auth state |
| Function cold starts | Use min instances (minInstances: 1), optimize imports |
| Emulator won't start | Check port conflicts, run firebase emulators:start --debug |
| Deploy fails | Run firebase deploy --debug, check service account permissions |
| Rules test failing | Use firebase emulators:exec to run rules unit tests |
Related Skills