Modern digital ID generation for Google Developer Groups (GDG), built with Next.js, TypeScript, Tailwind, Firebase, and Google Cloud.
- About
- Features
- Tech Stack
- Getting Started
- Environment Variables
- Project Structure
- API Routes
- Security & Anti‑Spam
- Development Workflow
- Troubleshooting
- Important Links
The GDG ID Platform lets members search for their profile (via email), render a branded digital ID card on the client (HTML canvas), and download it as PNG or PDF. Admins can review contact form submissions and manage platform content through protected routes.
Highlights:
- Smart email search against a Google Sheet
- Beautiful GDG-themed ID card rendering (Canvas)
- One‑click download as PNG or PDF
- Admin endpoints protected with Firebase Admin Auth and rate limits
- Responsive, mobile‑first UI with Tailwind CSS
Member-facing:
- Email-based lookup with instant feedback (SearchForm)
- Digital ID preview (Canvas-based) with member details
- Download ID as PNG or PDF (jsPDF)
Admin/Platform:
- Contact form backed by Firestore + email notification to admins
- Admin-only APIs (messages listing, mark done/not-done, delete)
- Role-based access (Firebase Admin) and request rate limiting
DX:
- TypeScript-first codebase with strict types
- Organized app router structure and modular libs
Organized by category. All badges link to the official docs.
Prerequisites:
- Node.js 18+
- npm (or yarn/pnpm)
Install and run:
git clone https://github.com/SauceCode01/gdg-id-platform.git
cd gdg-id-platform
npm install
npm run devVisit http://localhost:3000
Create a .env.local in the project root with the following keys. Only include real secrets locally or in your deployment platform settings.
Firebase (client):
NEXT_PUBLIC_APIKEY=
NEXT_PUBLIC_AUTHDOMAIN=
NEXT_PUBLIC_PROJECTID=
NEXT_PUBLIC_STORAGEBUCKET=
NEXT_PUBLIC_MESSAGINGSENDERID=
NEXT_PUBLIC_APPID=
NEXT_PUBLIC_MEASUREMENTID=
Firebase Admin (server):
FIREBASE_PROJECT_ID=
FIREBASE_CLIENT_EMAIL=
FIREBASE_PRIVATE_KEY= # escape newlines as \n
Google APIs (Gmail for contact notifications):
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REFRESH_TOKEN=
ADMIN_EMAIL=
Google Sheet (for members lookup):
NEXT_PUBLIC_SHEET_ID=
public/
cards/, contributors/, sites/ … # static assets
src/
app/
api/ # API routes (Next.js App Router)
members/route.ts # GET member by email (Google Sheet)
messages/route.ts # POST contact, GET messages (admin)
users/[uid]/route.ts # Admin fetch user by UID
ids/ # ID generation page (canvas)
contacts/, faqs/, about/, admin/ # site pages
components/ # UI components (Button, SearchForm, etc.)
lib/
firebase/ # client + admin SDK setup
gcp/ # gmail API auth
server/ # rate limiter, server utils
providers/, stores/, types/ # app context, state, types
Public / Member:
GET /api/members?email=you@example.com→ looks up a member row from Google Sheets
Contact / Messages:
POST /api/messages→ create a message (rate-limited), sends email to adminGET /api/messages→ list messages (admin only)PUT /api/messages/[id]/done→ mark as done (admin)PUT /api/messages/[id]/notDone→ mark as not done (admin)DELETE /api/messages/[id]/delete→ delete (admin)
Users (Admin):
GET /api/users/[uid]→ fetch a user’s data by UID (admin)
All admin endpoints require a valid authenticated admin context (see lib/server/serverUtils.ts).
- Request throttling with
rate-limiter-flexible(per-IP limits) - Firebase Admin Auth checks on admin endpoints
- Server-side validation on API routes
- Recommended extras (optional):
- reCAPTCHA on public forms
- Honeypot field on contact form
- Start from the latest
devbranch
git checkout dev
git pull origin dev- Create a feature branch from dev
git checkout -b tix-123- Commit with the ticket number
git add .
git commit -m "#123 Short, clear message"- Rebase/pull latest dev, resolve conflicts, and push
git pull origin dev
git push origin tix-123- Open a PR into
dev, document changes, include issue number in the title
- Firebase Admin auth errors → verify
FIREBASE_*env vars and private key formatting (\nnewlines) - Gmail send failures → check
GOOGLE_*creds andADMIN_EMAIL - Members search returns 500 → confirm
NEXT_PUBLIC_SHEET_IDand that the sheet is publicly readable (or adjust access) - Canvas export empty → ensure images under
public/cardsare reachable and member data is loaded
- Project Docs (SharePoint): https://docs.google.com/document/d/1l0axPJebnxow9CICbYZriG0nRyFmppqw_EEhaPnGD4o/edit?tab=t.0
- Figma Design: https://www.figma.com/design/4JbaxIFjz3y6CQTddMWfUd/GDG--26?node-id=482-599
- Issues: https://github.com/SauceCode01/gdg-id-platform/issues
Made with ❤️ by the GDG team.