Chattroom
Overview
Chattroom is a lightweight, single-page messaging experience built with Create React App, React 19, and Firebase. It provides Google-based authentication, a responsive chat interface, and real-time synchronization through Cloud Firestore. The codebase intentionally keeps business logic inside a few well-scoped components so it is easy to audit, extend, or migrate to another hosting target such as Firebase Hosting or Vercel.
Features
- Google sign-in & sign-out –
SignIn.jsuses Firebase Authentication with aGoogleAuthProvider, whileApp.jslistens for auth state changes and exposes a guarded sign-out action. - Real-time chat stream –
ChatRoom.jssubscribes to a Firestoremessagescollection withonSnapshot, ordered bycreatedAtand trimmed to 200 recent entries for predictable bandwidth. - Message composer with optimistic UX –
SendMessage.jsdisables the composer while a write is in-flight, trims whitespace, and storestext,uid,photoURL,displayName, and a FirestoreserverTimestamp. - Profanity filtering –
src/utils/profanity.jswraps thebad-wordsfilter to mask flagged terms before writes, andSendMessage.jsnotifies the user when language is sanitized so the room stays friendly. - Readable, inclusive UI –
ChatMessage.jsshows user avatars or generated initials, differentiates the current user’s messages, uses semantic elements/ARIA attributes, and auto-scrolls to the latest message. - Error & loading states – Authentication failures and initialization lag surface friendly copy via
App.js, while an inline loader prevents layout flicker. - Firebase Hosting ready –
firebase.jsonships a SPA rewrite rule so deep links resolve toindex.html.
Project Structure
chat-app/
├── .firebase/ # Firebase CLI build cache
├── build/ # Production bundle (generated by `npm run build`)
├── public/
│ └── index.html # CRA entry HTML + favicons/manifest
├── src/
│ ├── App.js # Root component: auth flow + conditional routing
│ ├── App.css # Global layout and component styles
│ ├── firebase.js # Firebase app/auth/firestore bootstrapping
│ ├── index.js / index.css # React entry point and base styles
│ ├── setupTests.js # Jest/RTL setup hooks
│ └── components/
│ ├── SignIn.js # Google sign-in button
│ ├── ChatRoom.js # Message subscription + layout
│ ├── ChatMessage.js # Individual bubble rendering
│ └── SendMessage.js # Composer and submission logic
├── package.json # Scripts and npm dependencies
├── firebase.json # Hosting configuration (SPA rewrites)
└── README.md # CRA boilerplate getting-started guide
Tech Stack
- Framework: React 19 (functional components + hooks) scaffolded by Create React App 5.
- Cloud Backend: Firebase Authentication (Google provider) and Cloud Firestore (NoSQL, real-time listeners).
- Tooling:
react-scriptsfor bundling, Jest + Testing Library for unit/UI tests, Web Vitals for runtime metrics. - Styling: Vanilla CSS modules (
App.css,index.css) with BEM-inspired class names for predictable scope. - Deployment: Firebase CLI & Hosting using
.firebaserc/firebase.json.
Data Model
messages collection documents hold the payload written in SendMessage.js:
| Field | Type | Description |
|---|---|---|
text | string | Trimmed message body |
createdAt | Firestore timestamp | Server timestamp, used for ordering & display |
uid | string | Firebase Auth user ID |
photoURL | string | null | Avatar shown beside each message |
displayName | string | Preferred name, falls back to email if unavailable |
The UI reads messages via onSnapshot for instant updates and formats timestamps locally through ChatMessage.js.
Getting Started
- Install dependencies
npm install - Provide Firebase credentials – either keep the sample config in
src/firebase.js(works only for the bundled demo project) or replace it with your project’s keys (see “Firebase configuration” below). - Run locally
CRA serves the app atnpm starthttp://localhost:3000with fast-refresh and ESLint feedback.
Firebase Configuration
src/firebase.js currently hardcodes the Firebase project metadata. To point the app at your own backend:
- Create a Firebase project, enable Authentication → Google and Firestore → Start in production mode.
- Replace the
firebaseConfigobject with your project keys. - (Optional) Move secrets into environment variables using CRA’s
REACT_APP_*naming convention and import them infirebase.js. - Run
npm startto verify that sign-in succeeds and that Firestore writes appear in themessagescollection.
Available Scripts
npm start– Launches the development server with live reload and source maps.npm test– Runs Jest in watch mode;App.test.jscurrently verifies authenticated/unauthenticated flows by mocking Firebase modules.npm run build– Produces an optimized production bundle insidebuild/.npm run eject– Gives full control over the CRA toolchain (irreversible).
Testing Strategy
- Unit/UI tests:
src/App.test.jsstubs Firebase Authentication/Firestore to test the two primary UI states (logged out vs. logged in) without hitting the network. - Integration smoke tests: Recommended before deployments—run the app locally, sign in with a test Google account, and confirm messages round-trip through Firestore.
- Accessibility checks: Spot-check with browser devtools (Lighthouse/axe) to ensure ARIA labels and contrast remain valid after styling changes.
Deployment
- Build:
npm run build - Deploy with Firebase CLI:
Thefirebase deploy --only hostingfirebase.jsonrewrite rule ensures that client-side routing (if added later) loadsindex.html. - For CI/CD, add a step that injects your Firebase config (environment variables or checked-in file) before running the build.
Maintenance Notes
- Security: Never commit private Firebase keys in public repos; migrate
firebaseConfiginto environment variables when open-sourcing. - Scalability:
ChatRoom.jscurrently limits the query to 200 messages. Adjustlimit()or implement pagination / infinite scroll if conversations grow. - Error handling: Authentication failures are surfaced, but Firestore write/read errors only log to the console. Consider adding user-facing toasts for writes and a retry/backoff strategy for reads.
License
No license file is currently included. All rights are therefore reserved by default. If you plan to share or open-source this project, add an explicit license (for example, MIT or Apache-2.0) at the repository root and reference it here.