Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Stivenz3/Nexu/llms.txt

Use this file to discover all available pages before exploring further.

Firestore security rules and composite indexes are the two server-side configurations that control data access and query performance in the Nexu platform. Both live as files in the repository root — firestore.rules and firestore.indexes.json — and are deployed to Firebase using a single npm script. You only need to run this deployment after modifying those files; every lesson seed and every Vercel build are completely independent of this step.

Deploy command

npm run firebase:deploy:rules
# Equivalent to:
npx firebase-tools deploy --only firestore:rules,firestore:indexes
This command uploads both firestore.rules and firestore.indexes.json to the Firebase project nexu-156ce. It uses firebase-tools via npx — no global installation is required, and firebase-admin is not involved.

Prerequisites

Before running the deploy command, authenticate the Firebase CLI and point it at the correct project:
  1. Log in to the Firebase CLI:
    npx firebase login
    
    This opens a browser window. Sign in with the team Google account that has Owner or Editor role on project nexu-156ce.
  2. Set the active project:
    npx firebase use nexu-156ce
    
    This writes the selection to .firebaserc so subsequent firebase commands target the right project automatically.

When to deploy rules

SituationDeploy needed?
Modified firestore.rulesYes
Modified firestore.indexes.jsonYes
Added a new lesson via seedNo
Changed React components or Vite configNo
Pushed a new commit to VercelNo
Rule and index changes are not applied instantly. There can be a brief propagation delay after deployment before the updated rules take effect across all Firestore regions. Plan accordingly — do not expect rules to enforce immediately in production testing.
Test rule changes in the Firebase Emulator locally before deploying to production. Start the emulator with npx firebase emulators:start --only firestore and point your local app at it using the Firebase SDK’s connectFirestoreEmulator(). This lets you iterate on rules without affecting the shared nexu-156ce database.

firestore.rules

The rules file controls who can read and write each Firestore collection. The current rules enforce the following policy:
  • /users/{userId} — authenticated users can only read and write their own profile document.
  • /users/{userId}/lessonProgress/{lessonId} — each user can only read and write their own lesson progress.
  • /lessons/{lessonId} and its sub-collections blocks and questions — any authenticated user can read; no user can write (content is loaded exclusively by seed scripts).
  • /certificates/{certificateId} — owners can read their own certificate; any authenticated user can create a certificate for themselves (with validity checks); update and delete are permanently denied.
  • /certificatePublic/{verifyCode} — public read access (used by the /verificar/:code page); any authenticated user can create; update and delete are permanently denied.
  • Catch-all — all other paths deny read and write by default.
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;

      match /lessonProgress/{lessonId} {
        allow read, write: if request.auth != null && request.auth.uid == userId;
      }
    }

    match /lessons/{lessonId} {
      allow read: if request.auth != null;

      match /blocks/{blockId} {
        allow read: if request.auth != null;
      }

      match /questions/{questionId} {
        allow read: if request.auth != null;
      }
    }

    match /certificates/{certificateId} {
      allow read: if request.auth != null && resource.data.userId == request.auth.uid;
      allow create: if request.auth != null
        && request.resource.data.userId == request.auth.uid
        && request.resource.data.certificateId == certificateId
        && request.resource.data.isValid == true;
      allow update, delete: if false;
    }

    match /certificatePublic/{verifyCode} {
      allow read: if true;
      allow create: if request.auth != null
        && request.resource.data.userId == request.auth.uid;
      allow update, delete: if false;
    }

    match /{document=**} {
      allow read, write: if false;
    }
  }
}

firestore.indexes.json

Composite indexes are required for Firestore queries that filter or sort on more than one field. The current file defines two indexes:
  • lessonsisActive (ASC) + order (ASC): used by LearningPathPage to fetch all active lessons in display order.
  • certificatesuserId (ASC) + issuedAt (DESC): used by getUserCertificates() to retrieve a user’s certificates sorted newest-first.
{
  "indexes": [
    {
      "collectionGroup": "lessons",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "isActive", "order": "ASCENDING" },
        { "fieldPath": "order", "order": "ASCENDING" }
      ]
    },
    {
      "collectionGroup": "certificates",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "userId", "order": "ASCENDING" },
        { "fieldPath": "issuedAt", "order": "DESCENDING" }
      ]
    }
  ],
  "fieldOverrides": []
}

Adding a new index

To add a composite index, append an entry to the "indexes" array in firestore.indexes.json following the same structure above, then run:
npm run firebase:deploy:rules
Firestore builds new indexes asynchronously; the Firebase Console shows build progress under Firestore → Indexes.

firebase.json

The firebase.json file tells the Firebase CLI where to find the rules and indexes files:
{
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  }
}

.firebaserc

The .firebaserc file records the default Firebase project alias so the CLI always targets nexu-156ce without requiring --project flags:
{
  "projects": {
    "default": "nexu-156ce"
  }
}

Build docs developers (and LLMs) love