- Notifications
You must be signed in to change notification settings - Fork36
agency-ai-solutions/nextjs-firebase-ai-coding-template
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
A production-ready template featuring event-driven broker architecture, designed for rapid AI-assisted development. Build full-stack applications with Next.js frontend and Python Firebase Functions backend using parallel AI agents.
- 🤖AI-First Development - Optimized for multi-agent parallel development
- 📊Event-Driven Architecture - Database as single source of truth
- 📝Built-in AI Rules - PRD, ADR, and task templates for AI agents
- 🔄Real-time Updates - Firestore subscriptions for automatic UI updates
- 🔐Firebase Authentication - Email/Password & Google Sign-In
- 📊Firestore Database - Real-time NoSQL with subscription hooks
- 📁Firebase Storage - File upload and management
- 🎨Material-UI (MUI) - Modern React components
- 🔄State Management - React Context for auth
- 📝TypeScript - Full type safety
- 🚀Next.js 14 - App Router with server components
- ⚡Serverless Functions - Auto-scaling Python backend
- 🏗️Broker Architecture - Event-driven, decoupled design
- 📊DocumentBase Classes - Structured Firestore management
- 🔒Authentication Wrappers - Built-in security
- 🧪Integration Testing - Real API testing with emulators
- 📦Pydantic Models - Runtime validation
- 🎯TDD Workflow - Test-first development
- Node.js 18+
- Python 3.9+
- Firebase account (sign up atFirebase Console)
- Firebase CLI (
npm install -g firebase-tools)
- Go toFirebase Console
- Click"Create a project" or"Add project"
- Enter your project name
- Choose whether to enable Google Analytics (optional)
- Wait for the project to be created
- Go toAuthentication >Sign-in method
- EnableEmail/Password provider
- EnableGoogle provider (optional but recommended)
- Go toFirestore Database >Create database
- ChooseStart in test mode for development
- Select a location closest to your users
- Note: You'll secure it with rules before production
- Go toStorage >Get started
- Start in test mode
- Choose the same location as your Firestore database
- Go toFunctions >Get started
- Note: Requires Blaze (Pay as you go) plan
- Firebase has generous free tiers
- Required for Functions and advanced features
- Follow the setup instructions
- In your Firebase project, click⚙️ >Project settings
- Scroll to"Your apps" section
- ClickWeb icon
</> - Register your app with a nickname
- Copy the Firebase configuration object
# Clone the repositorygit clone<your-repo-url>cd<project-directory># Install Firebase CLI globallynpm install -g firebase-tools# Login to Firebasefirebase login# Configure Firebase project# Edit .firebaserc and replace with your project ID
Navigate to the frontend directory:
cd front# Install dependenciesyarn install# ornpm install# Create environment filecp .env.example .env.local
Openfront/.env.local and add your Firebase configuration:
NEXT_PUBLIC_FIREBASE_API_KEY=your_api_key_hereNEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.comNEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-idNEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-project.appspot.comNEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=123456789NEXT_PUBLIC_FIREBASE_APP_ID=1:123456789:web:abcdefNEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=G-XXXXXXXXXX
yarn dev# ornpm run devVisithttp://localhost:3000 to see your app.
cd back# Create and activate virtual environmentpython -m venv venvsource venv/bin/activate# On Windows: venv\Scripts\activate# Install dependenciespip install -r requirements.txt
- Go to Firebase Console > Project Settings > Service Accounts
- Click "Generate new private key" and download the JSON file
- Place the JSON file in the
back/directory - Create
.envfile inback/directory:
cp .env.example .env# Edit .env and add:# FIREBASE_SERVICE_ACCOUNT_PATH=./your-service-account-key.json# Add any other API keys your project needs
# Start Firebase emulators (required for testing)firebase emulators:start# In another terminal, run testscd backsource venv/bin/activate# Run all tests with emulators (recommended)python run_tests.py# Run only unit tests (fast, no emulator needed)python run_tests.py --test-type unit --no-emulator# Run only integration testspython run_tests.py --test-type integration# Manual testing with pytestpytest# Ensure emulators are running first
# Deploy functions onlyfirebase deploy --only functions# Deploy security rulesfirebase deploy --only firestore:rules,storage:rules# Deploy everythingfirebase deploy
nextjs-firebase-ai-coding-template/├── front/ # Next.js Frontend│ ├── src/│ │ ├── app/ # Next.js app router pages│ │ │ ├── layout.tsx # Root layout│ │ │ ├── page.tsx # Home page│ │ │ ├── signin/ # Sign in page│ │ │ ├── signup/ # Sign up page│ │ │ └── dashboard/ # Protected dashboard│ │ ├── auth/ # Authentication logic│ │ │ ├── authContext.ts # Auth context definition│ │ │ ├── authOperations.ts # Auth functions│ │ │ ├── AuthProvider.tsx # Auth context provider│ │ │ └── useAuth.ts # Auth hook│ │ ├── lib/ # Firebase services│ │ │ ├── firebase.ts # Firebase initialization│ │ │ ├── firestore.ts # Firestore operations│ │ │ ├── functions.ts # Cloud Functions│ │ │ └── storage.ts # Storage operations│ │ ├── theme/ # MUI theme configuration│ │ └── config.ts # App configuration│ ├── .env.example # Environment variables template│ ├── package.json│ └── FRONTEND_RULES.md # Frontend-specific AI rules├── back/ # Python Firebase Functions Backend│ ├── main.py # Firebase function exports│ ├── run_tests.py # Test runner with emulator management│ ├── requirements.txt # Python dependencies│ ├── pytest.ini # Pytest configuration│ ├── .env.example # Backend environment template│ ├── BACKEND_RULES.md # Backend-specific AI rules│ ├── ADR.md # Architecture Decision Records│ ├── src/│ │ ├── apis/ # Database interfaces and API clients│ │ │ └── Db.py # Database singleton│ │ ├── brokers/ # Firebase function handlers│ │ │ ├── callable/ # Client-callable functions│ │ │ ├── https/ # HTTP endpoints│ │ │ └── triggered/ # Event-triggered functions│ │ ├── documents/ # Firestore document classes│ │ │ ├── DocumentBase.py # Base document class│ │ │ └── [collections]/ # Collection-specific classes│ │ ├── models/ # Data models and types│ │ │ ├── firestore_types.py # Firestore document types│ │ │ ├── function_types.py # Function request/response types│ │ │ └── util_types.py # Utility types│ │ ├── services/ # Business logic services│ │ ├── util/ # Utility functions│ │ └── exceptions/ # Custom exceptions│ └── tests/│ ├── conftest.py # Pytest fixtures│ ├── integration/ # Integration tests│ └── unit/ # Unit tests├── tasks/ # AI Development Templates│ ├── PRD.md # Product Requirements Document template│ └── TASK_TEMPLATE.md # Task breakdown template├── AGENTS.md # AI agent instructions├── firebase.json # Firebase configuration├── firestore.rules # Firestore security rules├── storage.rules # Storage security rules└── README.md # This fileUpdatefirestore.rules with appropriate security rules:
rules_version='2';servicecloud.firestore{match/databases/{database}/documents{// Allow users to read/write their own documentsmatch/users/{userId}{ allowread,write:ifrequest.auth!=null&&request.auth.uid==userId;}}}
Updatestorage.rules for file security:
rules_version='2';servicefirebase.storage{match/b/{bucket}/o{match/users/{userId}/{allPaths=**}{ allowread,write:ifrequest.auth!=null&&request.auth.uid==userId;}}}
# Generate PRD from requirements# Use tasks/PRD.md template# Ask AI to interview you until it can fill the PRD# Break down into tasks# Use tasks/TASK_TEMPLATE.md# Have AI create specific, actionable tasks with dependencies
Launch multiple AI agents (Cursor, Claude Code, etc.) in parallel:
# Agent 1: Frontend auth@AGENTS.md @FRONTEND_RULES.md implement [task1.md]# Agent 2: Backend API@AGENTS.md @BACKEND_RULES.md implement [task2.md]# Agent 3: Database models@AGENTS.md @BACKEND_RULES.md implement [task3.md]# Agent 4: Integration tests@AGENTS.md implement integration testsfor [feature]
# Backend: Always write integration tests firstcd backsource venv/bin/activatepython run_tests.py# Tests with real APIs# Frontend: Test with emulatorsfirebase emulators:startcd front&& yarn dev
After significant changes, update ADR:
# Tell agent to document decisions"Document the key architectural decisions in back/ADR.md"
cd frontyarn dev# Start development serveryarn build# Build for productionyarn lint# Run linting
cd backsource venv/bin/activate# Run testspython run_tests.py# All tests with emulatorspython run_tests.py --test-type unit# Unit tests onlypython run_tests.py --test-type integration# Integration tests only
- Start Firebase emulators:
firebase emulators:start - Frontend terminal:
cd front && yarn dev - Backend terminal:
cd back && source venv/bin/activate - Make changes and test integration
import{useAuth}from"@/auth/useAuth";import{authOperations}from"@/auth/authOperations";// Using the auth hookfunctionMyComponent(){const{ user, loading, isAuthenticated}=useAuth();if(loading)return<div>Loading...</div>;if(!isAuthenticated)return<div>Pleasesignin</div>;return<div>Welcome,{user.email}!</div>;}// Auth operationsawaitauthOperations.signUp(email,password,displayName);awaitauthOperations.signIn(email,password);awaitauthOperations.signInWithGoogle();awaitauthOperations.signOut();
import{userOperations}from"@/lib/firestore";// Create user documentawaituserOperations.create(uid,{ displayName, email});// Get user by IDconstuser=awaituserOperations.getById(uid);// Update userawaituserOperations.update(uid,{displayName:"New Name"});
# src/brokers/callable/example_callable.pyfromfirebase_functionsimporthttps_fn,optionsfromsrc.apis.DbimportDbfromsrc.util.db_auth_wrapperimportdb_auth_wrapper@https_fn.on_call(cors=options.CorsOptions(cors_origins=["*"]),ingress=options.IngressSetting.ALLOW_ALL,)defexample_callable(req:https_fn.CallableRequest):uid=db_auth_wrapper(req)# Implementation
# src/documents/examples/Example.pyfromsrc.documents.DocumentBaseimportDocumentBasefromsrc.apis.DbimportDbfromsrc.models.firestore_typesimportExampleDocclassExample(DocumentBase[ExampleDoc]):pydantic_model=ExampleDocdef__init__(self,id:str,doc:Optional[dict]=None):self._db=Db.get_instance()self.collection_ref=self.db.collections["examples"]super().__init__(id,doc)@propertydefdb(self)->Db:ifself._dbisNone:self._db=Db.get_instance()returnself._db
- Push your code to GitHub
- Import your repository onVercel
- Add environment variables in Vercel dashboard
- Deploy!
cd backfirebase deploy --only functions- Update Project IDs in
back/src/apis/Db.py:
defis_prod_environment(self)->bool:returnself.project_idin ["your-prod-project-id"]defis_dev_environment(self)->bool:returnself.project_idin ["your-dev-project-id"]
- Deploy Security Rules:
# Review and customize rules firstcat firestore.rulescat storage.rules# Deploy rulesfirebase deploy --only firestore:rules,storage:rules
- Set Firebase Indexes (if needed):
- Check console for index requirements
- Click provided links to create indexes
- Integration First - Test real Firebase Functions, not mocks
- Error Cases First - Test failure scenarios before success
- Full Verification - Check both API responses and database state
- Use Emulators - Never mock Firebase services
- End-to-End - Test complete user workflows
When working with AI agents:
# Always tell AI to:1. Write integration tests with real data2. Run tests and verify they pass3. Test with actual files/APIs, not mocks4. Show you where to find generated outputsdeftest_feature_integration(self,firebase_emulator,setup):# Arrange - Prepare test datatest_data= {"field":"value"}# Act - Call real Firebase Functionresponse=requests.post(f"{firebase_emulator['base_url']}/function_name",json={"data":test_data},headers={"User-Id":setup.user_id} )# Assert - Verify responseassertresponse.status_code==200result=response.json()["result"]# Assert - Verify database statedoc=DocumentClass(result["docId"])assertdoc.existsassertdoc.data.field=="value"
- Database as Truth - Firestore is the single source of truth
- No Direct Responses - Backend saves to DB, frontend subscribes
- Real-time Updates - UI updates automatically via Firestore hooks
- Decoupled Design - Frontend and backend communicate through database
- DocumentBase Pattern - All Firestore operations through DocumentBase classes
- No Direct DB Calls - Always use the Db singleton
- One Class Per File - Maintain clear file organization
- Broker Pattern - Handlers stay thin, logic in services
- Pydantic Models - Define all types in models/
- Runtime Validation - Catch errors early
- Type as Documentation - Types serve as API contracts
- Parallel Agents - Run multiple agents simultaneously
- Test-Driven - AI must write and run tests
- Documentation - Update ADR after major decisions
- Real APIs - Never let AI mock critical services
cd frontyarn dev# Start development serveryarn build# Build for productionyarn start# Start production serveryarn lint# Run ESLintyarn type-check# Run TypeScript checks
cd backpython run_tests.py# Run all tests with emulatorspython run_tests.py --test-type unit# Unit tests onlypython run_tests.py --test-type integration# Integration testspytest --cov=src# Run with coverage report
firebase emulators:start# Start local emulatorsfirebase deploy# Deploy everythingfirebase deploy --only functions# Deploy functions onlyfirebase deploy --only hosting# Deploy frontend onlyfirebase deploy --only firestore:rules# Deploy Firestore rules
NEXT_PUBLIC_FIREBASE_API_KEY=your_api_keyNEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your_auth_domainNEXT_PUBLIC_FIREBASE_PROJECT_ID=your_project_idNEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your_storage_bucketNEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_messaging_sender_idNEXT_PUBLIC_FIREBASE_APP_ID=your_app_idNEXT_PUBLIC_FIREBASE_MEASUREMENT_ID=your_measurement_id
Backend (back/.env):
FIREBASE_SERVICE_ACCOUNT_PATH- Path to service account JSON[YOUR_API_KEYS]- Any third-party API keys needed
Frontend (front/.env.local):
- All
NEXT_PUBLIC_FIREBASE_*variables from Firebase config - Any other public environment variables
Note: Never commit.env files or service account keys to version control!
- Create Firebase project
- Enable Authentication, Firestore, Storage, Functions
- Download service account key
- Configure environment variables
- Install dependencies (front & back)
- Start emulators
- Run tests
- Launch development servers
- Create PRD with AI
- Generate tasks from PRD
- Launch parallel AI agents
For issues and questions, please open an issue on GitHub.
Built for the AI development era with Next.js, Firebase, and Python
About
Resources
Uh oh!
There was an error while loading.Please reload this page.