Skip to content

dakshcodez/ExpenseTrackerBackend

Repository files navigation

Expense Tracker Backend

A RESTful API backend for managing personal expenses, built with Node.js, Express, MongoDB, and Firebase Authentication.

Project Overview

This backend service provides a complete API for expense management, including user authentication, expense CRUD operations, and expense reporting. The application uses Firebase Admin SDK for secure user authentication and MongoDB for data persistence.

Features

  • User Authentication: Register, login, logout, and profile management using Firebase Authentication
  • Expense Management: Create, read, update, and delete expenses
  • Expense Reports: Generate monthly expense reports and filter expenses by category
  • Secure API: Protected endpoints using Firebase ID token verification

Tech Stack

  • Node.js - Runtime environment
  • Express.js - Web framework
  • MongoDB - Database (using Mongoose ODM)
  • Firebase Admin SDK - Authentication and user management
  • Axios - HTTP client for Firebase API calls

Setup Instructions

Prerequisites

  • Node.js (v14 or higher)
  • npm or yarn
  • MongoDB database (local or cloud instance like MongoDB Atlas)
  • Firebase project with Authentication enabled

Installation

  1. Clone the repository

    git clone https://github.com/dakshcodez/ExpenseTrackerBackend_DakshArora.git
    cd ExpenseTrackerBackend_DakshArora
  2. Install dependencies

    npm install
  3. Firebase Service Account Setup

    • Go to Firebase Console → Project Settings → Service Accounts
    • Generate a new private key and download the JSON file
    • Save it as serviceAccountKey.json in the src/ directory
  4. Create .env file Create a .env file in the root directory with the following variables:

    # Server Configuration
    PORT=3000
    
    # MongoDB Configuration
    MONGO_URI=mongodb://localhost:27017/expense_tracker
    # Or for MongoDB Atlas:
    # MONGO_URI=mongodb+srv://username:password@cluster.mongodb.net/expense_tracker?retryWrites=true&w=majority
    
    # Firebase Configuration
    FIREBASE_API_KEY=your_firebase_web_api_key

    To get your Firebase API Key:

    • Go to Firebase Console → Project Settings → General
    • Scroll down to "Your apps" section
    • Copy the Web API Key
  5. Start the server

    # Production mode
    npm start
    
    # Development mode (with nodemon for auto-reload)
    npm run dev

The server will start on http://localhost:3000 (or the port specified in your .env file).

API Documentation

Base URL

http://localhost:3000/api

Authentication

Most endpoints require authentication. Include the Firebase ID token in the Authorization header:

Authorization: Bearer <idToken>

Endpoints

Authentication Routes (/api)

Register User

  • POST /api/register
  • Body:
    {
      "email": "user@example.com",
      "password": "securePassword123"
    }
  • Response:
    {
      "message": "User registerd successfully",
      "uid": "firebase-user-id"
    }

Login User

  • POST /api/login
  • Body:
    {
      "email": "user@example.com",
      "password": "securePassword123"
    }
  • Response:
    {
      "message": "Login successful",
      "idToken": "firebase-id-token",
      "refreshToken": "firebase-refresh-token",
      "expiresIn": "3600",
      "uid": "firebase-user-id"
    }

Logout User

  • POST /api/logout
  • Headers: Authorization: Bearer <idToken>
  • Response:
    {
      "message": "Logout successful"
    }

View User Profile

  • GET /api/profile
  • Headers: Authorization: Bearer <idToken>
  • Response:
    {
      "user": {
        "uid": "firebase-user-id",
        "email": "user@example.com",
        ...
      }
    }

Expense Routes (/api/expenses)

All expense endpoints require authentication.

Create Expense

  • POST /api/expenses
  • Headers: Authorization: Bearer <idToken>
  • Body:
    {
      "title": "Groceries",
      "amount": 150.50,
      "category": "Food",
      "date": "2024-01-15T00:00:00.000Z"  // Optional, defaults to current date
    }
  • Response:
    {
      "message": "Expense added successfully",
      "id": "expense-id"
    }

Get All Expenses

  • GET /api/expenses
  • Headers: Authorization: Bearer <idToken>
  • Response:
    {
      "expenses": [
        {
          "_id": "expense-id",
          "title": "Groceries",
          "amount": 150.50,
          "category": "Food",
          "date": "2024-01-15T00:00:00.000Z"
        },
        ...
      ]
    }

Get Expense by ID

  • GET /api/expenses/:id
  • Headers: Authorization: Bearer <idToken>
  • Response:
    {
      "expense": {
        "_id": "expense-id",
        "title": "Groceries",
        "amount": 150.50,
        "category": "Food",
        "date": "2024-01-15T00:00:00.000Z"
      }
    }

Update Expense

  • PUT /api/expenses/:id
  • Headers: Authorization: Bearer <idToken>
  • Body:
    {
      "title": "Updated Groceries",
      "amount": 175.00,
      "category": "Food",
      "date": "2024-01-15T00:00:00.000Z"
    }
  • Response:
    {
      "message": "Expense updated successfully"
    }

Delete Expense

  • DELETE /api/expenses/:id
  • Headers: Authorization: Bearer <idToken>
  • Response:
    {
      "message": "Expense deleted successfully"
    }

Report Routes (/api/reports)

All report endpoints require authentication.

Monthly Expense Report

  • GET /api/reports/monthly?month=1&year=2024
  • Headers: Authorization: Bearer <idToken>
  • Query Parameters:
    • month: Month number (1-12)
    • year: Year (e.g., 2024)
  • Response:
    {
      "total": 1500.75,
      "categories": {
        "Food": 500.25,
        "Transport": 300.50,
        "Entertainment": 700.00
      }
    }

Expenses by Category

  • GET /api/reports/category?category=Food
  • Headers: Authorization: Bearer <idToken>
  • Query Parameters:
    • category: Category name (e.g., "Food", "Transport")
  • Response:
    {
      "expenses": [
        {
          "_id": "expense-id",
          "title": "Groceries",
          "amount": 150.50,
          "date": "2024-01-15T00:00:00.000Z"
        },
        ...
      ]
    }

Example API Usage

Using cURL

1. Register a new user:

curl -X POST http://localhost:3000/api/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "securePassword123"
  }'

2. Login:

curl -X POST http://localhost:3000/api/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "securePassword123"
  }'

3. Create an expense (use the idToken from login response):

curl -X POST http://localhost:3000/api/expenses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ID_TOKEN_HERE" \
  -d '{
    "title": "Monthly Groceries",
    "amount": 250.75,
    "category": "Food"
  }'

4. Get all expenses:

curl -X GET http://localhost:3000/api/expenses \
  -H "Authorization: Bearer YOUR_ID_TOKEN_HERE"

5. Get monthly report:

curl -X GET "http://localhost:3000/api/reports/monthly?month=1&year=2024" \
  -H "Authorization: Bearer YOUR_ID_TOKEN_HERE"

Using JavaScript (Fetch API)

// Login
const loginResponse = await fetch('http://localhost:3000/api/login', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    email: 'user@example.com',
    password: 'securePassword123'
  })
});

const loginData = await loginResponse.json();
const idToken = loginData.idToken;

// Create expense
const expenseResponse = await fetch('http://localhost:3000/api/expenses', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${idToken}`
  },
  body: JSON.stringify({
    title: 'Monthly Groceries',
    amount: 250.75,
    category: 'Food'
  })
});

const expenseData = await expenseResponse.json();
console.log(expenseData);

Project Structure

ExpenseTrackerBackend_DakshArora/
├── src/
│   ├── config/
│   │   ├── db.js              # MongoDB connection
│   │   └── firebase.js        # Firebase Admin initialization
│   ├── controllers/
│   │   ├── authController.js  # Authentication logic
│   │   ├── expenseController.js  # Expense CRUD operations
│   │   └── reportController.js   # Report generation logic
│   ├── middlewares/
│   │   └── authMiddleware.js # Firebase token verification
│   ├── models/
│   │   ├── Expense.js         # Expense schema
│   │   └── User.js            # User schema
│   ├── routes/
│   │   ├── authRoutes.js     # Authentication routes
│   │   ├── expenseRoutes.js  # Expense routes
│   │   └── reportRoutes.js   # Report routes
│   ├── serviceAccountKey.json # Firebase service account (not in git)
│   └── index.js               # Application entry point
├── .env                       # Environment variables (not in git)
├── package.json
└── README.md

Error Handling

The API returns standard HTTP status codes:

  • 200 - Success
  • 201 - Created
  • 400 - Bad Request (missing/invalid parameters)
  • 401 - Unauthorized (invalid/missing token)
  • 404 - Not Found
  • 409 - Conflict (e.g., email already exists)
  • 500 - Internal Server Error

Security Notes

  • Never commit serviceAccountKey.json or .env to version control
  • Keep your Firebase API key secure
  • Use HTTPS in production
  • Regularly rotate service account keys
  • Validate and sanitize all user inputs

License

ISC

Author

Daksh Arora

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors