Skip to content

Latest commit

Β 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ChatApp Logo

ChatApp β€” Real-Time Messaging Platform

A high-performance, cross-platform real-time chat application built with Flutter, Node.js, Express, Socket.IO, and MongoDB.

Flutter Dart Node.js Express.js Socket.IO MongoDB JWT Status


πŸ“– About the Project

ChatApp is a full-stack, production-ready real-time instant messaging application designed for seamless one-to-one communication across mobile (Android & iOS) and web platforms.

Built with a modern reactive architecture, the application combines a responsive Flutter & Riverpod frontend with an asynchronous Node.js, Express, Socket.IO, and MongoDB backend. The system features persistent bidirectional WebSockets for instant message delivery, live typing status, real-time online/offline presence indicators, optimistic UI state management, paginated chat history, and JWT-authenticated session security.


✨ Features

πŸ” Authentication & Security

  • User Registration & Login: Account creation and login with form validation (email format, password minimum length).
  • Password Hashing: Passwords are encrypted before storage using bcrypt with a salt round of 10.
  • JWT Authorization: Stateless access token generation (jsonwebtoken) with configurable expiration (JWT_EXPIRES_IN=7d).
  • Encrypted Local Storage: Authentication tokens are safely stored on the device using Flutter Secure Storage (Android Keystore / iOS Keychain).
  • Auto-Login & Session Recovery: App verifies stored tokens on startup via /api/auth/me and seamlessly restores user sessions.
  • Session Expiration Guard: Automatic 401 interceptor that clears expired tokens and redirects the user to the login screen.
  • Protected Endpoints & Sockets: All private REST endpoints and Socket.IO handshake connections require valid Bearer tokens.
  • Security Middleware: Configured with Helmet for HTTP security headers, CORS origin verification, and Express Rate Limiting to prevent brute-force attacks.

πŸ’¬ Real-Time Messaging

  • Instant 1-on-1 Chat: Bi-directional real-time communication powered by Socket.IO rooms (user_<id> and <chatId>).
  • Optimistic UI Updates: Sent messages appear immediately in the chat thread with temporary local IDs before server confirmation.
  • REST Fallback Transmission: If socket connectivity is momentarily interrupted, the client transparently falls back to REST API message posting.
  • Typing Indicators: Real-time broadcast of typing state (typing and stop_typing) with automatic 1.5s debouncing timers.
  • Live User Presence: Instant online/offline status tracking with broadcast events (user_online, user_offline, check_online_status).
  • Read Receipts & Delivery Tracking: Real-time read acknowledgment (mark_read, message_read, messages_read) with timestamps and visual status checkmarks.
  • Global In-App Notifications: Background socket listeners automatically update the Home screen's chat list when new messages arrive.

πŸ—‚οΈ Chat & History Management

  • Paginated Message Loading: Reverse infinite scrolling with backend pagination (skip & limit) for fast startup and low memory usage.
  • Smart Conversation Creation: Automated lookup or creation of unique, normalized 1-on-1 chat threads between participant pairs.
  • Recent Chat Ordering: Active conversations are dynamically sorted by latest message timestamp (updatedAt / lastMessageAt).
  • Empty States & Shimmers: Designed with polished empty states for new conversations and initial message feeds.

πŸ‘€ User Discovery & Profile Management

  • Debounced User Search: Live search query system across names and emails with a 400ms debounce to prevent superfluous API calls.
  • Profile Customization: Users can edit their display names and view their account email.
  • Avatar Photo Upload: Native photo library selection (image_picker) and multipart upload via Multer with MIME-type filtering.
  • Initials Fallback Avatars: Automatic generation of colored monogram avatars for contacts without custom profile images.

πŸ“± Application Screens

The application includes a clean Material 3 user interface designed with a cohesive color palette (Deep Emerald #075E54, Vibrant Green #25D366, and Warm Chat Beige #ECE5DD).

πŸ”‘ Authentication & Onboarding

Register Screen Login Screen Empty Chats State
Register Screen Login Screen Empty Chats
User registration with validation Email & password sign-in Clean initial landing empty state

πŸ’¬ Messaging & User Discovery

User Search Screen Active Chat Room Active Chat List
User Search Screen Chat Room Screen Chat List Screen
Debounced user search by name/email 1-on-1 chat with status & bubbles Recent chats with unread & preview

πŸ‘€ Profile & Settings

Profile View Photo Attachment Picker Updated Avatar Profile
Profile Screen Photo Picker Updated Avatar
View and edit account information Native photo gallery picker Live avatar image update

βš™οΈ Preferences & Live Multi-Device Synchronization

Settings Screen Logout Confirmation Cross-Platform Live Sync
Settings Screen Logout Dialog Dual Device Live Sync
Account & app preferences Secure session sign-out dialog Real-time sync on iOS & Android

πŸ—„οΈ Database & Terminal

The backend utilizes MongoDB via Mongoose with optimized indexes on lookup fields, timestamps, and relational ObjectIds.

MongoDB mongosh Query & Collections

MongoDB mongosh session displaying active database chatapp, collections (chats, messages, users), and indexed documents.

Database Architecture & Collections

Collection Model File Purpose & Stored Attributes Indexes
users User.js Stores user profiles: name, email (unique, lowercase), password (bcrypt hash, select: false), avatar URL, isOnline boolean, lastSeen date, createdAt, updatedAt. Unique index on email, Compound text index on { name: "text", email: "text" }.
chats Chat.js Stores 1-on-1 conversation records: participants (Array of 2 User ObjectIds), lastMessage (Message ObjectId reference), lastMessageAt date, createdAt, updatedAt. Index on participants, Descending index on updatedAt.
messages Message.js Stores individual chat messages: chatId (Chat reference), sender (User reference), receiver (User reference), message text, messageType (text, image, file, emoji), fileUrl, fileName, fileSize, isRead, readAt, delivered, deliveredAt. Compound index on { chatId: 1, createdAt: -1 }, { sender: 1, receiver: 1 }, { isRead: 1 }, { delivered: 1 }.

Database Connection Lifecycle

  • Connected via Mongoose in backend/src/config/database.js using the MONGO_URI environment variable.
  • Connection state is monitored and exposed via the /health diagnostic endpoint (mongodb: connected).

πŸ›οΈ System Architecture

flowchart TB
    subgraph Client["Flutter Cross-Platform Frontend"]
        UI["UI Layer (Material 3 Screens & Widgets)"]
        State["Riverpod State Notifiers (Auth, Chat, Message, Socket)"]
        Router["GoRouter (Route Guards & Redirection)"]
        Storage["Flutter Secure Storage (JWT Auth Token)"]
        DioClient["Dio HTTP Client (REST with Bearer Interceptor)"]
        SocketClient["Socket.IO Client (WebSocket Connection)"]
        
        UI --> State
        State --> Router
        State --> Storage
        State --> DioClient
        State --> SocketClient
    end

    subgraph Gateway["Express & Socket Gateway (Port 5001)"]
        MW["Middleware (Helmet, CORS, Morgan, RateLimiter, Multer)"]
        AuthMW["JWT Auth Middleware & Socket Handshake Auth"]
        
        subgraph RESTControllers["Express REST API"]
            AuthCtrl["Auth Controller (/api/auth)"]
            UserCtrl["User Controller (/api/users)"]
            ChatCtrl["Chat Controller (/api/chats)"]
        end
        
        subgraph SocketEngine["Socket.IO Engine"]
            Presence["Presence Engine (user_online / user_offline)"]
            MsgRelay["Message Relay (send_message -> receive_message)"]
            Typing["Typing Handler (typing / stop_typing)"]
            ReadRec["Read Receipts (mark_read / message_read)"]
        end
        
        DioClient -- "HTTP REST Requests" --> MW --> AuthMW --> RESTControllers
        SocketClient -- "WebSocket Events" --> AuthMW --> SocketEngine
    end

    subgraph Database["Database & File Persistence"]
        MongoDB[(MongoDB Database: 'chatapp')]
        Uploads[("/uploads Static Avatar Storage")]
        
        RESTControllers --> MongoDB
        SocketEngine --> MongoDB
        UserCtrl --> Uploads
    end
Loading

πŸ”„ Application & Data Flows

1. Authentication & Route Guard Flow

sequenceDiagram
    autonumber
    actor User as User
    participant App as Flutter App
    participant Storage as Secure Storage
    participant API as Express API
    participant DB as MongoDB

    User->>App: Launch App
    App->>Storage: Read 'auth_token'
    alt Token Found
        App->>API: GET /api/auth/me (Bearer Token)
        alt Token Valid
            API->>DB: User.findById(decoded.userId)
            DB-->>API: User Document
            API-->>App: { success: true, user }
            App->>App: Navigate to /home
        else Token Expired / Invalid
            API-->>App: 401 Unauthorized
            App->>Storage: Delete 'auth_token'
            App->>App: Navigate to /login
        end
    else No Token Found
        App->>App: Navigate to /login
    end
Loading

2. Real-Time Messaging & Presence Flow

sequenceDiagram
    autonumber
    actor UserA as Alice (Sender)
    participant ClientA as Alice's App
    participant Server as Socket.IO Server
    participant DB as MongoDB
    participant ClientB as Bob's App
    actor UserB as Bob (Receiver)

    Note over ClientA, Server: Connected & Joined Rooms ('user_AliceID', 'chat_123')
    Note over ClientB, Server: Connected & Joined Rooms ('user_BobID', 'chat_123')

    UserA->>ClientA: Types message in ChatScreen
    ClientA->>Server: emit('typing', { chatId, receiver: BobID })
    Server-->>ClientB: emit('typing', { userId: AliceID, chatId })
    ClientB->>UserB: Display Typing Indicator (● ● ●)

    UserA->>ClientA: Press Send Button
    ClientA->>ClientA: Render optimistic message bubble (temp_id)
    ClientA->>Server: emitWithAck('send_message', { chatId, receiver, message })
    
    Server->>DB: Message.create() & Chat.update(lastMessage)
    DB-->>Server: Saved Message Document
    
    Server-->>ClientA: Ack / emit('message_sent', savedMessage)
    ClientA->>ClientA: Replace temp_id with permanent MongoDB _id
    
    Server-->>ClientB: emit('receive_message', savedMessage)
    ClientB->>UserB: Display incoming message bubble
    
    ClientB->>Server: emit('mark_read', { chatId })
    Server->>DB: Message.updateMany({ chatId, isRead: true })
    Server-->>ClientA: emit('message_read', { chatId, readBy: BobID })
    ClientA->>UserA: Update message bubble to Double Checkmarks (Read)
Loading

πŸ“‚ Frontend Structure

frontend/
β”œβ”€β”€ assets/
β”‚   └── logo.png                             # App icon and branding asset
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ main.dart                            # Application entry point, dotenv initialization & ProviderScope
β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”œβ”€β”€ api/
β”‚   β”‚   β”‚   β”œβ”€β”€ api_client.dart              # Dio HTTP instance, auth interceptors & Android localhost rewriter
β”‚   β”‚   β”‚   β”œβ”€β”€ api_endpoints.dart           # Centralized REST route constants
β”‚   β”‚   β”‚   β”œβ”€β”€ environment.dart             # Environment config and fallback URLs
β”‚   β”‚   β”‚   └── socket_client.dart           # Socket.IO client singleton abstraction
β”‚   β”‚   └── constants/
β”‚   β”‚       β”œβ”€β”€ app_colors.dart              # Material 3 theme color palette
β”‚   β”‚       β”œβ”€β”€ app_strings.dart             # Localized UI string constants & storage keys
β”‚   β”‚       └── app_theme.dart               # ThemeData definition (AppBar, Buttons, Inputs)
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”œβ”€β”€ api_response.dart                # Generic API response wrapper model
β”‚   β”‚   β”œβ”€β”€ chat.dart                        # Chat room model & participant resolver
β”‚   β”‚   β”œβ”€β”€ message.dart                     # Message entity model & type parser (text/image/file/emoji)
β”‚   β”‚   └── user.dart                        # User entity model (Equatable)
β”‚   β”œβ”€β”€ providers/
β”‚   β”‚   β”œβ”€β”€ auth_provider.dart               # AuthStateNotifier (login, register, auto-login, logout)
β”‚   β”‚   β”œβ”€β”€ chat_provider.dart               # ChatListNotifier (live chat list state & ordering)
β”‚   β”‚   β”œβ”€β”€ message_provider.dart            # ChatMessagesNotifier (chat room state, pagination, optimistic UI)
β”‚   β”‚   β”œβ”€β”€ socket_provider.dart             # SocketController & OnlineUsersNotifier (global presence)
β”‚   β”‚   └── user_provider.dart               # UserSearchNotifier & ProfileEditNotifier
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   └── app_router.dart                  # GoRouter configuration with auth-state refresh listeners
β”‚   β”œβ”€β”€ screens/
β”‚   β”‚   β”œβ”€β”€ chat/
β”‚   β”‚   β”‚   β”œβ”€β”€ widgets/
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ chat_input_field.dart    # Chat textfield with dynamic send button
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ message_bubble.dart      # Chat bubble with timestamp and delivery status
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ message_input.dart       # Auxiliary input components
β”‚   β”‚   β”‚   β”‚   └── typing_indicator.dart    # Animated pulsing typing indicator
β”‚   β”‚   β”‚   └── chat_screen.dart             # 1-on-1 chat room with reverse pagination
β”‚   β”‚   β”œβ”€β”€ home/
β”‚   β”‚   β”‚   β”œβ”€β”€ widgets/
β”‚   β”‚   β”‚   β”‚   └── chat_list_tile.dart      # Chat tile with avatar, last message preview & unread dot
β”‚   β”‚   β”‚   └── home_screen.dart             # Recent conversations feed with search FAB
β”‚   β”‚   β”œβ”€β”€ login/
β”‚   β”‚   β”‚   └── login_screen.dart            # Sign-in form with email/password validation
β”‚   β”‚   β”œβ”€β”€ profile/
β”‚   β”‚   β”‚   └── profile_screen.dart          # Profile editing & avatar image picker upload
β”‚   β”‚   β”œβ”€β”€ register/
β”‚   β”‚   β”‚   └── register_screen.dart         # Account registration form
β”‚   β”‚   β”œβ”€β”€ search/
β”‚   β”‚   β”‚   └── user_search_screen.dart      # Live debounced user search & direct chat initiation
β”‚   β”‚   β”œβ”€β”€ settings/
β”‚   β”‚   β”‚   └── settings_screen.dart         # Settings list & logout confirmation modal
β”‚   β”‚   └── splash/
β”‚   β”‚       └── splash_screen.dart           # Startup splash screen during auth verification
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ auth_service.dart                # REST authentication endpoints service
β”‚   β”‚   β”œβ”€β”€ chat_service.dart                # REST chat creation & fetch service
β”‚   β”‚   β”œβ”€β”€ message_service.dart             # REST message pagination & fallback service
β”‚   β”‚   β”œβ”€β”€ socket_service.dart              # Low-level Socket.IO emitter and listener wrapper
β”‚   β”‚   β”œβ”€β”€ storage_service.dart             # FlutterSecureStorage wrapper for tokens
β”‚   β”‚   └── user_service.dart                # REST user search and avatar upload service
β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   β”œβ”€β”€ date_formatter.dart              # Time formatting for chat timestamps
β”‚   β”‚   └── validators.dart                  # Form validation logic (Email, Password, Name)
β”‚   └── widgets/
β”‚       β”œβ”€β”€ custom_button.dart               # Reusable primary action button with loading spinner
β”‚       β”œβ”€β”€ custom_text_field.dart           # Reusable styled text input with prefix/suffix icons
β”‚       β”œβ”€β”€ empty_state.dart                 # Reusable placeholder illustration & caption widget
β”‚       β”œβ”€β”€ error_widget.dart                # Reusable error display with retry callback
β”‚       └── loading_indicator.dart           # Centered progress indicator
β”œβ”€β”€ pubspec.yaml                             # Flutter project configuration and package dependencies
└── analysis_options.yaml                    # Dart analyzer and linting rules

πŸ“‚ Backend Structure

backend/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ config/
β”‚   β”‚   β”œβ”€β”€ cors.js                          # Dynamic CORS origin validator & Socket.IO CORS rules
β”‚   β”‚   └── database.js                      # Mongoose connection initialization
β”‚   β”œβ”€β”€ controllers/
β”‚   β”‚   β”œβ”€β”€ authController.js                # Register, login, getMe, logout handlers
β”‚   β”‚   β”œβ”€β”€ chatController.js                # Fetch chats, create chat, get messages, send message, mark read
β”‚   β”‚   └── userController.js                # Get users, search users, update profile, upload avatar
β”‚   β”œβ”€β”€ middleware/
β”‚   β”‚   β”œβ”€β”€ auth.js                          # JWT verification middleware for protected routes
β”‚   β”‚   β”œβ”€β”€ errorHandler.js                  # Centralized JSON error responder with environment checks
β”‚   β”‚   β”œβ”€β”€ rateLimiter.js                   # Express-rate-limit configuration
β”‚   β”‚   └── upload.js                        # Multer diskStorage and image fileFilter configuration
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”œβ”€β”€ Chat.js                          # Mongoose schema for conversations
β”‚   β”‚   β”œβ”€β”€ Message.js                       # Mongoose schema for messages
β”‚   β”‚   └── User.js                          # Mongoose schema for users (with password hiding & index rules)
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   β”œβ”€β”€ authRoutes.js                    # Route definitions for /api/auth
β”‚   β”‚   β”œβ”€β”€ chatRoutes.js                    # Route definitions for /api/chats
β”‚   β”‚   └── userRoutes.js                    # Route definitions for /api/users
β”‚   β”œβ”€β”€ sockets/
β”‚   β”‚   β”œβ”€β”€ events.js                        # Socket message sending, typing broadcast & read handlers
β”‚   β”‚   └── index.js                         # Socket.IO connection lifecycle & auth middleware
β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   β”œβ”€β”€ bcrypt.js                        # Password hashing and comparison utilities
β”‚   β”‚   └── jwt.js                           # JWT signing and verification helpers
β”‚   β”œβ”€β”€ validators/
β”‚   β”‚   β”œβ”€β”€ authValidator.js                 # Express-validator rules for registration & login
β”‚   β”‚   └── chatValidator.js                 # Express-validator rules for messages
β”‚   β”œβ”€β”€ app.js                               # Express app configuration, route mounting & /health endpoint
β”‚   └── server.js                            # HTTP server, Socket.IO binding & port listener
β”œβ”€β”€ uploads/                                 # Static storage directory for uploaded user avatars
β”œβ”€β”€ .env.example                             # Environment variable template
└── package.json                             # Node.js dependencies, scripts and package metadata

πŸ› οΈ Tech Stack

Frontend

Backend

Database

  • Database: MongoDB (Local Community Server or MongoDB Atlas Cloud)

βš™οΈ Prerequisites

Before getting started, make sure you have the following installed on your development machine:

Requirement Minimum / Recommended Version Verification Command
Flutter SDK >= 3.12.2 flutter --version
Dart SDK >= 3.12.2 dart --version
Node.js >= 18.0.0 (LTS Recommended) node --version
npm >= 9.0.0 npm --version
MongoDB >= 6.0 (Local or MongoDB Atlas) mongosh --version
Git >= 2.30.0 git --version
Android Studio / Xcode Latest stable (for emulator & simulator testing) flutter doctor

Verify your Flutter environment by running:

flutter doctor

πŸš€ Installation & Setup

Follow these step-by-step instructions to set up and run the application locally.

Step 1 β€” Clone the Repository

git clone https://github.com/manab-ghh/basic-chat-app.git
cd basic-chat-app

Step 2 β€” Backend Configuration & Setup

  1. Navigate to the backend directory:

    cd backend
  2. Install the required Node.js dependencies:

    npm install
  3. Create your .env configuration file from the provided example template:

    cp .env.example .env
  4. Open .env and verify the settings (see Environment Variables for details).

  5. Start the backend development server:

    npm run dev

    The server will start on port 5001 (or your configured PORT) and connect to MongoDB.


Step 3 β€” Frontend Configuration & Setup

  1. Open a new terminal window and navigate to the frontend directory:

    cd frontend
  2. Install Flutter package dependencies:

    flutter pub get
  3. Ensure a .env file exists in the frontend/ directory (or create one):

    cat <<EOF > .env
    BASE_URL=http://localhost:5001/api
    SOCKET_URL=http://localhost:5001
    EOF

    [!TIP] Android Emulator Support: The frontend codebase automatically rewrites localhost and 127.0.0.1 to 10.0.2.2 when running on Android emulators, so you do not need to manually change the URL.

  4. Launch the Flutter application:

    # Run on the default connected device / simulator
    flutter run
    
    # Or run explicitly on Android / iOS / Chrome
    flutter run -d chrome
    flutter run -d ios
    flutter run -d android

πŸ” Environment Variables

Backend Configuration (backend/.env)

Variable Required Default / Example Purpose
PORT No 5001 The HTTP & WebSocket server port.
NODE_ENV No development Environment mode (development or production).
MONGO_URI Yes mongodb://localhost:27017/chatapp MongoDB connection URI string (Local or Atlas).
JWT_SECRET Yes your_super_secret_jwt_key_here Secret key used to sign and verify JWT authentication tokens.
JWT_EXPIRES_IN No 7d Lifespan of generated JWT tokens.
CLIENT_URL No http://localhost:3000 Allowed client origins for CORS validation.
MAX_FILE_SIZE No 5242880 Maximum file upload size in bytes (5 MB).
UPLOAD_DIR No uploads/ Destination folder for uploaded avatar files.
RATE_LIMIT_WINDOW No 15 Rate limiting window duration in minutes.
RATE_LIMIT_MAX No 100 Maximum requests allowed per IP per time window.

Frontend Configuration (frontend/.env)

Variable Required Default / Example Purpose
BASE_URL Yes http://localhost:5001/api Base URL for REST API calls.
SOCKET_URL Yes http://localhost:5001 Server URL for Socket.IO WebSocket connections.

πŸƒ MongoDB Setup

You can run MongoDB locally or use MongoDB Atlas in the cloud.

Option A: Local MongoDB

  1. Start your local MongoDB server:
    # macOS (Homebrew)
    brew services start mongodb-community
    
    # Linux (systemd)
    sudo systemctl start mongod
    
    # Windows
    net start MongoDB
  2. Verify connection via mongosh:
    mongosh
  3. Set your MONGO_URI in backend/.env:
    MONGO_URI=mongodb://localhost:27017/chatapp

Option B: MongoDB Atlas (Cloud)

  1. Log in to MongoDB Atlas and create a free Shared Cluster.
  2. Under Database Access, create a database user with password authentication.
  3. Under Network Access, add 0.0.0.0/0 (or your specific IP) to the IP Access List.
  4. Click Connect > Drivers (Node.js) to obtain your connection URI.
  5. Set the URI in backend/.env:
    MONGO_URI=mongodb+srv://<username>:<password>@<cluster-url>/chatapp?retryWrites=true&w=majority

πŸ”‘ Authentication

The application uses JSON Web Tokens (JWT) for secure, stateless authentication.

  1. Registration (POST /api/auth/register): Validates email uniqueness and formats, hashes password with bcrypt, creates user, and returns user profile with JWT.
  2. Login (POST /api/auth/login): Validates credentials against hashed password, updates lastSeen, and issues a new JWT.
  3. Token Storage: Flutter saves the token securely via FlutterSecureStorage under the key auth_token.
  4. REST Authorization: The ApiClient Dio interceptor automatically attaches the header Authorization: Bearer <token> to all protected endpoints.
  5. Socket Authorization: The SocketService supplies the token in the socket connection handshake:
    socket = io(socketUrl, {
      auth: { token: token },
      transports: ['websocket']
    });
  6. Token Verification: Backend middleware auth.js verifies the token signature and attaches the active User document to req.user.

πŸ”Œ API Endpoints

πŸ›‘οΈ Authentication Endpoints (/api/auth)

Method Endpoint Auth Required Description
POST /api/auth/register No Register a new user account.
POST /api/auth/login No Authenticate user and obtain a JWT token.
GET /api/auth/me Yes Retrieve authenticated user's profile.
POST /api/auth/logout Yes Logout user session.

Example: Register User

POST /api/auth/register
Content-Type: application/json

{
  "name": "Manabendra Mondal",
  "email": "manab@dev.com",
  "password": "securepassword123"
}

Response (201 Created):

{
  "success": true,
  "message": "User registered successfully",
  "data": {
    "user": {
      "id": "66c75a1b2e1f3a001a123456",
      "name": "Manabendra Mondal",
      "email": "manab@dev.com",
      "avatar": null,
      "isOnline": false,
      "lastSeen": "2026-08-23T10:00:00.000Z",
      "createdAt": "2026-08-23T10:00:00.000Z",
      "updatedAt": "2026-08-23T10:00:00.000Z"
    },
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}

πŸ‘₯ User Endpoints (/api/users)

Method Endpoint Auth Required Description
GET /api/users Yes Get all registered users (excluding current user).
GET /api/users/search?q=:query Yes Search users by name or email (min 2 chars).
PUT /api/users/profile Yes Update name or avatar URL.
POST /api/users/avatar Yes Upload an avatar image file (multipart/form-data).

πŸ’¬ Chat & Message Endpoints (/api/chats)

Method Endpoint Auth Required Description
GET /api/chats Yes Get all active conversation threads for current user.
POST /api/chats Yes Get existing chat or create new chat with userId.
GET /api/chats/:chatId/messages Yes Get paginated message history (?page=1&limit=20).
POST /api/chats/messages Yes Send message via REST fallback.
PUT /api/chats/:chatId/read Yes Mark all unread messages in chat as read.

⚑ Socket.IO Real-Time Events

Client β†’ Server Events

  • join_room: { "chatId": "string" } β€” Join a specific chat room.
  • leave_room: { "chatId": "string" } β€” Leave a chat room.
  • send_message: { "chatId": "string", "receiver": "string", "message": "string", "messageType": "text" } β€” Send real-time message.
  • typing: { "chatId": "string", "receiver": "string" } β€” Broadcast typing indicator.
  • stop_typing: { "chatId": "string", "receiver": "string" } β€” Clear typing indicator.
  • mark_read: { "chatId": "string" } β€” Mark received messages as read.
  • check_online_status: { "targetUserId": "string" } β€” Request presence status for a user.

Server β†’ Client Events

  • receive_message: Emitted to recipient room (user_<receiverId>) and chat room with the new message payload.
  • message_sent: Emitted back to sender with confirmed message payload.
  • user_online: Broadcast when a user connects ({ "userId": "string", "isOnline": true }).
  • user_offline: Broadcast when a user disconnects ({ "userId": "string", "isOnline": false, "lastSeen": Date }).
  • typing / stop_typing: Forwarded to the recipient user.
  • message_read / messages_read: Emitted to chat room when messages are read.
  • online_status: Responded to check_online_status.

▢️ Running the Application

1. Terminal 1 β€” Backend Server

cd backend
npm run dev

2. Terminal 2 β€” Flutter Frontend

cd frontend
flutter run

Recommended Execution Order

  1. Ensure MongoDB is running (Local service or Atlas cluster reachable).
  2. Start Backend on port 5001 (npm run dev).
  3. Launch Frontend via Flutter (flutter run).
  4. Register two accounts (e.g. across two simulators/browsers) and start real-time messaging!

βœ… Ready-to-Use Checklist

  • Clone the repository
  • Node.js and Flutter SDK prerequisites verified
  • MongoDB database started and accessible
  • backend/.env configured with MONGO_URI and JWT_SECRET
  • Backend dependencies installed (npm install)
  • Backend server running on http://localhost:5001
  • Frontend dependencies installed (flutter pub get)
  • Frontend .env configured with BASE_URL and SOCKET_URL
  • User registration & login verified
  • Real-time messaging, typing indicators, and presence verified

πŸ› Troubleshooting

1. MongoDB Connection Failed (ECONNREFUSED)

  • Cause: Local MongoDB daemon is not running, or Atlas IP whitelist does not permit connection.
  • Solution:
    • For local: Start MongoDB with brew services start mongodb-community or sudo systemctl start mongod.
    • For Atlas: Add 0.0.0.0/0 under Network Access in MongoDB Atlas console.

2. Port Already in Use (EADDRINUSE: 5001)

  • Cause: A background Node process is already using port 5001.
  • Solution: Terminate the existing process or change PORT in .env:
    lsof -ti :5001 | xargs kill -9

3. Android Emulator Cannot Reach Backend

  • Cause: Android emulators refer to their own host loopback when using localhost.
  • Solution: The app includes built-in rewriting (10.0.2.2), but ensure backend/.env allows CORS from local origins.

4. CORS Error on Web Browser

  • Cause: Browser requests blocked by CORS headers.
  • Solution: Add your web origin URL to CLIENT_URL in backend/.env (e.g. CLIENT_URL=http://localhost:3000,http://localhost:8080).

πŸ”’ Security Best Practices

  • Never Commit Secrets: Ensure .env is listed in .gitignore and never committed to public repositories.
  • Strong JWT Secrets: Generate cryptographically secure keys (e.g. openssl rand -base64 32) for JWT_SECRET.
  • Bcrypt Salt Hashing: All user passwords are salted and hashed with bcrypt prior to database persistence.
  • Sanitized JSON Output: User Mongoose schema strips password and __v from all JSON responses.
  • Rate Limiting: Protected API routes use express-rate-limit to mitigate brute-force and DoS attempts.
  • HTTPS & WSS in Production: Always enable SSL/TLS termination in production environments.

πŸ—ΊοΈ Roadmap & Future Enhancements

  • Group Chats: Create group conversations with multiple participants and admin management.
  • Push Notifications: Firebase Cloud Messaging (FCM) integration for background message delivery.
  • Media & Audio Messages: Voice notes, audio recording, and full document file sharing.
  • Message Reactions: Quick emoji reactions on individual message bubbles.
  • End-to-End Encryption (E2EE): Signal Protocol integration for zero-knowledge end-to-end encryption.
  • Dark Mode Theme: Dynamic theme switching (Light / Dark mode).
  • Message Deletion & Editing: "Delete for everyone" and message edit history.

πŸ“‚ GitHub Repository Structure

basic-chat-app/
β”œβ”€β”€ app-screens/                             # Application screenshots and terminal previews
β”‚   β”œβ”€β”€ database.png                         # MongoDB mongosh collections preview
β”‚   β”œβ”€β”€ screen01.png                         # Register screen
β”‚   β”œβ”€β”€ screen02.png                         # Login screen
β”‚   β”œβ”€β”€ screen03.png                         # Empty chats screen
β”‚   β”œβ”€β”€ screen04.png                         # Profile screen
β”‚   β”œβ”€β”€ screen05.png                         # Settings screen
β”‚   β”œβ”€β”€ screen06.png                         # Logout dialog
β”‚   β”œβ”€β”€ screen07.png                         # User search screen
β”‚   β”œβ”€β”€ screen08.png                         # 1-on-1 chat room screen
β”‚   β”œβ”€β”€ screen09.png                         # Active chat list screen
β”‚   β”œβ”€β”€ screen10.png                         # Photo picker interface
β”‚   β”œβ”€β”€ screen11.png                         # Profile avatar updated
β”‚   └── screen12.png                         # Dual device live cross-platform sync
β”œβ”€β”€ backend/                                 # Node.js + Express + Socket.IO backend
β”‚   β”œβ”€β”€ src/                                 # Server source code (controllers, models, routes, sockets)
β”‚   β”œβ”€β”€ uploads/                             # Avatar uploads directory
β”‚   β”œβ”€β”€ .env.example                         # Backend environment variables template
β”‚   └── package.json                         # Node dependencies & start scripts
β”œβ”€β”€ frontend/                                # Flutter cross-platform mobile & web client
β”‚   β”œβ”€β”€ assets/                              # App logos and images
β”‚   β”œβ”€β”€ lib/                                 # Dart source code (screens, providers, services, models)
β”‚   β”œβ”€β”€ pubspec.yaml                         # Flutter dependencies and asset registrations
β”‚   └── analysis_options.yaml                # Linting configuration
β”œβ”€β”€ .gitignore                               # Git ignore rules for Flutter, Node, and .env
└── README.md                                # Project documentation

πŸ“„ License

The backend package configuration specifies the ISC License. For repository-wide usage terms, refer to project settings or repository maintainers.


πŸ‘¨β€πŸ’» Author

Manabendra Mondal


Built with ❀️ by Manabendra Mondal using Flutter & Node.js

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages