firebase-app-platform – skill DevOps & Hạ tầng cho agent AI
Xây dựng và vận hành ứng dụng trên Firebase với Auth, Firestore, Cloud Functions và Hosting. Dùng khi xây dựng backend cho ứng dụng di động/web bằng dịch vụ được quản lý, đồng bộ dữ liệu thời gian thực hoặc API serverless.
Cài skill firebase-app-platform bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/firebase-app-platform-2e828.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /firebase-app-platform – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/firebase-app-platform-2e828.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $firebase-app-platform – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/firebase-app-platform-2e828.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /firebase-app-platform – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/firebase-app-platform-2e828.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /firebase-app-platform – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
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)
Security and deployment boundaries
Test rules with allowed/denied identities in the emulator before authorized deployment to an explicitly selected project. User-editable profile fields must never grant admin permissions; the admin example uses a server-managed custom claim. The message rules are an intentionally public-to-authenticated example, not private-channel membership enforcement. Admin SDK HTTP functions bypass Firestore rules, so authenticate/authorize there or expose only explicitly public fields. CORS is not authorization. Firestore triggers may retry/out-of-order: the counter/timestamp illustration needs event-ID deduplication and monotonic timestamp handling before production. Keep secrets in supported secret storage and verify current runtime/config migration guidance; budget alerts do not cap spend. See [rule conditions](https://firebase.google.com/docs/firestore/security/rules-conditions).
Quick Start
# Install and authenticate
npm install -g firebase-tools
firebase login
# Initialize in your project directory
firebase init
# Select: Firestore, Functions, Hosting, Emulators
# Start local emulators
firebase emulators:start
# Deploy everything
firebase deploy
# Deploy specific services
firebase deploy --only functions
firebase deploy --only hosting
firebase deploy --only firestore:rulesFirestore Database
Security Rules
// firestore.rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Users can only read/write their own data
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
// Messages: authenticated users can read, only owner can write
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: if request.auth != null
&& resource.data.userId == request.auth.uid
&& request.resource.data.userId == resource.data.userId
&& request.resource.data.body is string
&& request.resource.data.body.size() <= 5000;
allow delete: if request.auth != null
&& resource.data.userId == request.auth.uid;
}
// Admin-only collection
match /admin/{document=**} {
allow read, write: if request.auth != null
&& request.auth.token.admin == true; // custom claim set only by trusted server admin
}
// Default: deny everything
match /{document=**} {
allow read, write: if false;
}
}
}Data Operations
// lib/firestore.ts
import { getFirestore, collection, doc, setDoc, getDoc,
query, where, orderBy, limit, onSnapshot,
serverTimestamp, increment } from "firebase/firestore";
const db = getFirestore();
// Create document with auto-ID
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;
}
// Real-time listener
function subscribeToMessages(channelId: string, callback: (msgs: any[]) => void) {
const q = query(
collection(db, "channels", channelId, "messages"),
orderBy("createdAt", "desc"),
limit(50)
);
return onSnapshot(q, (snapshot) => {
const messages = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
callback(messages);
});
}
// Atomic counter
async function incrementViews(postId: string) {
await setDoc(doc(db, "posts", postId), {
views: increment(1),
}, { merge: true });
}Indexes
// firestore.indexes.json
{
"indexes": [
{
"collectionGroup": "messages",
"queryScope": "COLLECTION",
"fields": [
{ "fieldPath": "channelId", "order": "ASCENDING" },
{ "fieldPath": "createdAt", "order": "DESCENDING" }
]
}
]
}Authentication
// lib/auth.ts
import { getAuth, signInWithPopup, GoogleAuthProvider,
createUserWithEmailAndPassword, signInWithEmailAndPassword,
signOut, onAuthStateChanged } from "firebase/auth";
const auth = getAuth();
// Google sign-in
async function signInWithGoogle() {
const provider = new GoogleAuthProvider();
const result = await signInWithPopup(auth, provider);
return result.user;
}
// Email/password registration
async function register(email: string, password: string) {
const result = await createUserWithEmailAndPassword(auth, email, password);
return result.user;
}
// Auth state listener
onAuthStateChanged(auth, (user) => {
if (user) {
console.log("Signed in:", user.uid, user.email);
} else {
console.log("Signed out");
}
});Cloud Functions
// functions/src/index.ts
import { onRequest } from "firebase-functions/v2/https";
import { onDocumentCreated } from "firebase-functions/v2/firestore";
import { getFirestore, FieldValue } from "firebase-admin/firestore";
import { initializeApp } from "firebase-admin/app";
initializeApp();
const db = getFirestore();
// HTTP function (API endpoint)
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.data() }));
res.json({ posts });
});
// Firestore trigger — runs when a new message is created
export const onMessageCreated = onDocumentCreated(
"channels/{channelId}/messages/{messageId}",
async (event) => {
const data = event.data?.data();
if (!data) return;
// Update channel's last message timestamp
await db.doc(`channels/${event.params.channelId}`).update({
lastMessageAt: data.createdAt,
messageCount: FieldValue.increment(1),
});
// Send notification (example)
// Do not log message bodies; emit a redacted event identifier only.
}
);Hosting
// firebase.json
{
"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", "value": "public, max-age=31536000, immutable" }]
},
{
"source": "**",
"headers": [
{ "key": "X-Frame-Options", "value": "DENY" },
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "Strict-Transport-Security", "value": "max-age=63072000" }
]
}
]
}
}Local Emulators
# Start all emulators
firebase emulators:start
# Start specific emulators
firebase emulators:start --only auth,firestore,functions
# Export emulator data for persistence
firebase emulators:export ./emulator-data
firebase emulators:start --import=./emulator-data
# Emulator UI at http://localhost:4000// firebase.json — emulator config
{
"emulators": {
"auth": { "port": 9099 },
"firestore": { "port": 8080 },
"functions": { "port": 5001 },
"hosting": { "port": 5000 },
"ui": { "enabled": true, "port": 4000 }
}
}Environment Configuration
# Set environment variables for functions
firebase functions:config:set stripe.key="sk_live_xxx" app.name="MyApp"
# View config
firebase functions:config:get
# Use in functions (v1)
const stripeKey = functions.config().stripe.key;
# For v2 functions, use .env files
# functions/.env
STRIPE_KEY=sk_live_xxx
# functions/.env.local (for emulators)
STRIPE_KEY=sk_test_xxxMulti-Environment Setup
# Create separate projects for each environment
firebase use --add # Add staging project alias
firebase use staging # Switch to staging
firebase use production
# Deploy to specific project
firebase deploy --project my-app-staging
firebase deploy --project my-app-production
# .firebaserc
{
"projects": {
"staging": "my-app-staging",
"production": "my-app-pro… (nội dung đầy đủ có trong gói tải về)
Skill liên quan
- flutter-expert – Làm chủ phát triển Flutter với Dart 3, widget nâng cao và triển khai đa nền tảng.
- secrets-vault-manager – Dùng khi người dùng yêu cầu thiết lập hạ tầng quản lý bí mật, tích hợp HashiCorp Vault…
- gcp-audit-logs – Cấu hình GCP Cloud Audit Logs để tuân thủ. Thiết lập định tuyến log và phân tích bằng…
- gcp-cloud-functions – Triển khai serverless functions trên Google Cloud Functions. Cấu hình triggers và quản…
- gcp-cloud-run – Skill chuyên biệt để xây dựng ứng dụng serverless sẵn sàng cho production trên GCP. Bao…
- gcp-cloud-sql – Khởi tạo Cloud SQL databases. Cấu hình high availability, backups và bảo mật. Dùng khi…
- gcp-compute – Quản lý Compute Engine instances và instance templates. Cấu hình managed instance groups…
- gcp-gke – Triển khai và quản lý Google Kubernetes Engine clusters. Cấu hình node pools, networking…