Skip to main content

Overview

Study Sync uses Firebase Authentication for securing API endpoints. All authenticated requests must include a valid Firebase ID token in the Authorization header.

Authentication Methods

Firebase ID Token

The API uses Firebase ID tokens for authentication. These tokens are obtained from Firebase Authentication after a user signs in.

Header Format

Authorization: Bearer YOUR_FIREBASE_ID_TOKEN

Getting a Firebase ID Token

Using Firebase SDK (Client-side)

import { getAuth } from 'firebase/auth';

const auth = getAuth();
const user = auth.currentUser;

if (user) {
  const token = await user.getIdToken();
  // Use this token in API requests
}

Token Refresh

Firebase ID tokens expire after 1 hour. The Firebase SDK automatically refreshes tokens, but you can manually refresh:
const token = await user.getIdToken(true); // Force refresh

Making Authenticated Requests

cURL Example

curl -X GET "https://your-domain.com/api/users/me" \
  -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjFkYzBmMTc..." \
  -H "Content-Type: application/json"

JavaScript Fetch Example

const token = await user.getIdToken();

const response = await fetch('https://your-domain.com/api/users/me', {
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  }
});

const data = await response.json();

Axios Example

import axios from 'axios';

const token = await user.getIdToken();

const response = await axios.get('https://your-domain.com/api/users/me', {
  headers: {
    'Authorization': `Bearer ${token}`
  }
});

Authentication Flow

  1. User signs in via Firebase Authentication (email/password, Google, etc.)
  2. Firebase returns an ID token
  3. Client includes token in Authorization header for API requests
  4. API verifies token using Firebase Admin SDK
  5. If token is valid, API processes the request
  6. If user doesn’t exist in database, API auto-creates user profile

User Auto-Creation

When a valid Firebase token is provided for a new user, the API automatically creates a user profile with:
firebaseUid
string
Firebase user ID from the token
email
string
User’s email address
displayName
string
Display name (from Firebase or extracted from email)
photoURL
string
Profile photo URL (if available from Firebase)
role
string
User role, defaults to "user"

Optional Authentication

Some endpoints use optional authentication, where:
  • Public content is accessible without a token
  • Additional features/data are available with authentication
  • No error is returned for missing/invalid tokens
Examples:
  • GET /api/study-plans (public plans viewable without auth)
  • GET /api/study-plans/:id (public plans accessible without auth)

Authentication Errors

401 Unauthorized

Returned when authentication is required but missing or invalid. Missing Token:
{
  "error": "No token provided"
}
Invalid Token:
{
  "error": "Invalid or expired token"
}

403 Forbidden

Returned when authenticated but lacking permission to access the resource.
{
  "error": "Access denied"
}

Security Best Practices

  1. Never expose tokens - Don’t log or store tokens in plain text
  2. Use HTTPS - Always use secure connections in production
  3. Refresh tokens - Implement automatic token refresh before expiration
  4. Handle errors - Properly handle 401/403 errors and redirect to login
  5. Validate on client - Check authentication state before making requests

Test Authentication

Use this endpoint to verify your authentication is working:
curl -X GET "https://your-domain.com/api/auth/me" \
  -H "Authorization: Bearer YOUR_TOKEN"
Successful response:
{
  "_id": "507f1f77bcf86cd799439011",
  "firebaseUid": "abc123xyz",
  "email": "[email protected]",
  "displayName": "John Doe",
  "photoURL": "https://example.com/photo.jpg",
  "role": "user"
}

Build docs developers (and LLMs) love