This guide explains how to set up, run, and develop the Hiking Logbook backend API locally.
The backend is an Express.js application that provides:
Before setting up the development API, ensure you have:
backend/
├── auth.js # Authentication routes and middleware
├── users.js # User management routes
├── firebaseAdmin.js # Firebase Admin SDK configuration
├── verifyAuth.js # JWT token verification middleware
├── createUser.js # User creation utilities
├── server.js # Main Express server
├── package.json # Dependencies and scripts
├── serviceAccountKey.json # Firebase service account credentials
├── jest.config.js # Jest testing configuration
└── eslint.config.js # ESLint configuration
# Clone the repository (if not already done)
git clone <your-repo-url>
cd Hiking-Logbook/backend
# Install dependencies
npm install
serviceAccountKey.json
backend/
directory** Security Note:** Never commit serviceAccountKey.json
to version control!
Create a .env
file in the backend directory:
# Backend environment variables
PORT=3000
NODE_ENV=development
FIREBASE_PROJECT_ID=your_project_id
FIREBASE_PRIVATE_KEY_ID=your_private_key_id
FIREBASE_CLIENT_EMAIL=your_client_email
FIREBASE_CLIENT_ID=your_client_id
Note: The Firebase values come from your serviceAccountKey.json
file.
# Check if everything is working
npm run lint
npm run format:check
npm test
npm start
This will:
http://localhost:3000
# Development
npm start # Start development server
npm run dev # Start with nodemon (if configured)
# Code Quality
npm run lint # Check for linting issues
npm run lint:fix # Fix linting issues automatically
npm run format # Format code with Prettier
npm run format:check # Check if code is formatted correctly
# Testing
npm test # Run tests once
npm run test:watch # Run tests in watch mode
npm run test:coverage # Run tests with coverage report
/auth
)// POST /auth/signup
{
"email": "user@example.com",
"password": "securepassword123",
"displayName": "John Doe"
}
// POST /auth/login
{
"email": "user@example.com",
"password": "securepassword123"
}
// POST /auth/verify
{
"token": "jwt_token_here"
}
/users
)// GET /users/profile
// Headers: Authorization: Bearer <token>
// PUT /users/profile
// Headers: Authorization: Bearer <token>
{
"displayName": "Updated Name",
"bio": "Hiking enthusiast",
"preferences": {
"difficulty": "intermediate",
"terrain": "mountain"
}
}
// DELETE /users/profile
// Headers: Authorization: Bearer <token>
// Create a new route file (e.g., trails.js)
import express from "express";
import { verifyAuth } from "./verifyAuth.js";
const router = express.Router();
// Protected route example
router.get("/trails", verifyAuth, async (req, res) => {
try {
// Your route logic here
res.json({ trails: [] });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
export default router;
// Add to server.js
import trailRoutes from "./trails.js";
app.use("/trails", trailRoutes);
# Test authentication endpoint
curl -X POST http://localhost:3000/auth/signup \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"password123","displayName":"Test User"}'
# Test protected endpoint
curl -X GET http://localhost:3000/users/profile \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
// Example: Creating a user document
import { db } from "./firebaseAdmin.js";
async function createUserProfile(uid, userData) {
try {
await db.collection("users").doc(uid).set({
email: userData.email,
displayName: userData.displayName,
createdAt: new Date(),
updatedAt: new Date(),
});
return { success: true };
} catch (error) {
throw new Error(`Failed to create user profile: ${error.message}`);
}
}
The firebaseAdmin.js
file configures:
The server.js
file sets up:
nodemon
for automatic server restart// Add logging to your routes
console.log("Request body:", req.body);
console.log("User ID:", req.user.uid);
console.log("Database result:", result);
.vscode/launch.json
:{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Backend",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/backend/server.js",
"env": {
"NODE_ENV": "development"
}
}
]
}
# Kill process on port 3000
npx kill-port 3000
# Or use a different port
PORT=3001 npm start
# Verify service account key
cat serviceAccountKey.json
# Check environment variables
echo $FIREBASE_PROJECT_ID
# Verify Firebase project exists
# Check Firebase Console
// Add CORS middleware to server.js
import cors from "cors";
app.use(
cors({
origin: "http://localhost:3000", // Frontend URL
credentials: true,
})
);
# Check JWT token format
# Verify token expiration
# Check Firebase project configuration
# Verify service account permissions
/auth/login
verifyAuth
middlewareAfter setting up the development API:
If you encounter issues:
This guide covers Sprint 1 backend API setup. For additional features, check the main README.