FireEngine Documentation

FireEngine is a self-hosted Content Management System built on Express.js that automatically detects Firestore database schemas and generates a complete admin interface.

Key Features

  • Automatic Schema Detection: Scans Firestore collections and generates forms, tables, and validation
  • Self-Hosted: Deploy on your own infrastructure with full data control
  • Advanced Authentication: Support for SAML, OIDC, social logins, and MFA
  • Role-Based Access: Custom roles with granular permissions

Quick Start

Get FireEngine running in under 5 minutes with Node.js:

Prerequisites:
  • Enable Firebase Authentication with Email/Password provider
  • Create a user account with the same email as ownerEmail
server.js
const express = require('express');
const fireengine = require('fireenginecms');

const app = express();

app.use('/admin', fireengine({
  adminCredentials: './firebase-admin-key.json',
  webappConfig: './firebase-config.json',
  ownerEmail: 'admin@example.com'
}));

app.listen(3000, () => {
  console.log('🔥 FireEngine admin: http://localhost:3000/admin');
});
Terminal
# Install dependencies
npm install express fireenginecms

# Run the server
node server.js
✅ That's it! FireEngine will automatically detect your Firestore schema and generate the admin interface at /admin.

Installation

System Requirements

  • Node.js 16+
  • Firebase project with Firestore enabled
  • Firebase Admin SDK service account

Installation Methods

Node.js Application

package.json
{
  "name": "my-fireengine-app",
  "version": "1.0.0",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.18.2",
    "fireengine": "latest"
  }
}
server.js
const express = require('express');
const fireengine = require('fireenginecms');

const app = express();
const port = process.env.PORT || 3000;

// FireEngine admin interface
app.use('/admin', fireengine({
  adminCredentials: './firebase-admin-key.json',
  webappConfig: './firebase-config.json',
  ownerEmail: 'admin@yourdomain.com'
}));

// Your other routes
app.get('/', (req, res) => {
  res.send('App is running! Admin: /admin');
});

app.listen(port, () => {
  console.log(`🔥 Server running at http://localhost:${port}`);
  console.log(`🔥 FireEngine admin: http://localhost:${port}/admin`);
});

Firebase Cloud Functions

functions/index.js
const functions = require('firebase-functions');
const fireengine = require('fireenginecms');

// Export the Cloud Function
exports.admin = functions.https.onRequest(
  fireengine({
    adminCredentials: './firebase-admin-key.json',
    webappConfig: './firebase-config.json',
    ownerEmail: 'admin@yourdomain.com'
  })
);
Deploy to Firebase
# Install Firebase CLI and deploy
npm install -g firebase-tools
firebase login
firebase init functions
firebase deploy --only functions

Configuration

Flexible Configuration

FireEngine can be configured either through code (config files) or environment variables - choose what suits your development workflow. FireEngine auto-detects environment variables when launching:

.env
# Installation Configuration (Required)
FIREENGINE_OWNER_EMAIL=owner@yourdomain.com

# Firebase Admin Configuration (alternatively use config files)
FIREENGINE_ADMIN_TYPE=service_account
FIREENGINE_FIREBASE_PROJECT_ID=your-project-id
FIREENGINE_ADMIN_PRIVATE_KEY_ID=your-private-key-id
FIREENGINE_ADMIN_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
FIREENGINE_ADMIN_CLIENT_EMAIL=your-service-account@project.iam.gserviceaccount.com
FIREENGINE_ADMIN_CLIENT_ID=your-client-id
FIREENGINE_ADMIN_AUTH_URI=https://accounts.google.com/o/oauth2/auth
FIREENGINE_ADMIN_TOKEN_URI=https://oauth2.googleapis.com/token
FIREENGINE_ADMIN_AUTH_PROVIDER_X509_CERT_URL=https://www.googleapis.com/oauth2/v1/certs
FIREENGINE_ADMIN_CLIENT_X509_CERT_URL=https://www.googleapis.com/robot/v1/metadata/x509/your-service-account%40project.iam.gserviceaccount.com

# Alternative: Firebase Admin JSON (instead of individual vars)
FIREENGINE_ADMIN_CREDENTIALS_JSON={"type":"service_account","project_id":"..."}
FIREENGINE_ADMIN_CREDENTIALS_FILE=/path/to/firebase-admin-key.json

# Firebase Web App Configuration (alternatively use config files)
FIREENGINE_WEBAPP_API_KEY=your-api-key
FIREENGINE_WEBAPP_AUTH_DOMAIN=your-project.firebaseapp.com
FIREENGINE_WEBAPP_STORAGE_BUCKET=your-project.appspot.com
FIREENGINE_WEBAPP_MESSAGING_SENDER_ID=123456789
FIREENGINE_WEBAPP_APP_ID=your-app-id
FIREENGINE_WEBAPP_MEASUREMENT_ID=G-XXXXXXXXXX

# Alternative: Firebase Web App JSON (instead of individual vars)
FIREENGINE_WEBAPP_CONFIG_JSON={"apiKey":"...","authDomain":"..."}
FIREENGINE_WEBAPP_CONFIG_FILE=/path/to/firebase-config.json

# Optional Configurations
FIREENGINE_FIRESTORE_DATABASE=your-database-id
FIREENGINE_USE_FIRESTORE_ACCESS_RULES=false
FIREENGINE_GOOGLE_MAPS_API_KEY=your-google-maps-api-key
FIREENGINE_GOOGLE_MAPS_OPTIONS={"zoom":10,"center":{"lat":0,"lng":0}}
FIREENGINE_IGNORE_COLLECTIONS=["_internal","_temp"]
FIREENGINE_SCHEMA_OVERRIDES={"users":{"title":"User Management"}}
FIREENGINE_SIGNIN_METHODS=["email","google"]

Firebase Setup

FireEngine requires two configuration files from Firebase:

1. Admin Service Account Key

  1. Go to Firebase Console
  2. Select your project
  3. Go to Project Settings → Service Accounts
  4. Click "Generate new private key"
  5. Download and save as firebase-admin-key.json

2. Web App Configuration

  1. In Firebase Console, go to Project Settings → General
  2. Scroll to "Your apps" section
  3. Select your web app or create one
  4. Copy the config object and save as firebase-config.json:
firebase-config.json
{
  "apiKey": "your-api-key",
  "authDomain": "your-project.firebaseapp.com",
  "projectId": "your-project-id",
  "storageBucket": "your-project.appspot.com",
  "messagingSenderId": "123456789",
  "appId": "your-app-id"
}
⚠️ Security Note: Never commit your private key to version control. Use environment variables or secure secret management.

Express.js Integration

Once you have your Firebase configuration files, integrate FireEngine with Express.js:

server.js
const express = require('express');
const fireengine = require('fireenginecms');

const app = express();

// Configure FireEngine middleware
app.use('/admin', fireengine({
  adminCredentials: './firebase-admin-key.json',
  webappConfig: './firebase-config.json',
  ownerEmail: 'admin@yourdomain.com'
}));

app.listen(3000, () => {
  console.log('FireEngine running at http://localhost:3000/admin');
});

Schema Detection

FireEngine automatically scans your Firestore collections and generates admin interfaces:

How It Works

  1. Collection Scanning: Detects all collections in your Firestore database
  2. Field Analysis: Analyzes document structures to determine field types
  3. UI Generation: Creates forms, tables, and validation rules automatically

Supported Field Types

Firestore Type UI Component Description
string Text Input Single-line text field
number Number Input Numeric input with validation
boolean Toggle Switch On/off toggle control
timestamp Date Picker Date and time selection
array Dynamic List Add/remove items dynamically
reference Dropdown Select Select from referenced collection
geopoint Map Picker Geographic coordinate selection
map JSON Editor Edit complex objects as JSON
Custom Types Custom JavaScript User-defined field types with custom rendering functions

Schema Overrides

Override auto-detected schemas with custom field properties and validation:

Configuration Methods

1. Code Configuration

config.js
const fireengine = require('fireenginecms');

app.use('/', fireengine({
  // ... other config
  schemaOverrides: {
    "users": {
      title: "User Management",
      titleTemplate: "${displayName} (${email})",
      fields: [
        {
          name: "email",
          title: "Email Address",
          required: true,
          width: 0.5
        },
        {
          name: "role",
          title: "User Role",
          required: true,
          options: ["admin", "editor", "viewer"],
          width: 0.25
        },
        {
          name: "status",
          title: "Account Status",
          options: [
            ["active", "Active User"],
            ["pending", "Pending Approval"], 
            ["disabled", "Disabled Account"]
          ],
          width: 0.25
        }
      ]
    }
  }
}));

2. GUI Editor 🔥 Pro Plan Feature

  1. Navigate to Settings → Schema Management
  2. Click the edit icon (✏️) next to any collection
  3. Customize field properties using the visual editor
  4. Save changes to apply immediately

Field Properties

Property Type Description
name string Field name (must match database field)
title string Custom display label
type string Field type override
required boolean Mark field as required
options array Dropdown options for select fields
width number Grid width (0.08333 to 1)
default any Default value for new documents

Field Validation

Add custom JavaScript validation functions to your schema fields for real-time validation with custom error messages:

Validation Functions
schemaOverrides: {
  "users": {
    title: "User Management",
    fields: [
      {
        name: "email",
        type: "string",
        required: true,
        validate: (value) => {
          const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
          if (!emailRegex.test(value)) {
            return "Please enter a valid email address";
          }
          return true; // Validation passed
        }
      },
      {
        name: "age",
        type: "number",
        validate: (value) => {
          if (value < 18) {
            return "Must be 18 years or older";
          }
          if (value > 120) {
            return "Please enter a realistic age";
          }
          return true;
        }
      },
      {
        name: "username",
        type: "string",
        required: true,
        validate: (value) => {
          if (value.length < 3) {
            return "Username must be at least 3 characters";
          }
          if (!/^[a-zA-Z0-9_]+$/.test(value)) {
            return "Username can only contain letters, numbers, and underscores";
          }
          return true;
        }
      }
    ]
  }
}

Validation Function Rules

Return Value Result Description
true ✅ Valid Field passes validation, no error shown
string ❌ Invalid Field fails validation, string displayed as error message
null/undefined ✅ Valid Treated as validation passed

When Validation Runs

  • Field Blur: When user clicks away from the field (onBlur event)
  • Form Save: Before saving the document to Firestore
  • Frontend & Backend: Validation runs both client-side and server-side for security

Error Display

  • Field-level: Error message appears as helper text below the input field
  • Toast notifications: All validation errors are displayed in a combined toast notification when saving
  • Visual feedback: Invalid fields are highlighted in red

💡 Pro Tip

Validation functions are serialized when sent to the frontend, so they cannot reference external variables or functions. Keep validation logic self-contained within each function.

Custom Field Types

Create custom field types with specialized rendering and validation logic using JavaScript functions. FireEngine automatically serializes functions when needed for frontend execution.

How It Works

Custom field types allow you to:

  • Form Input Rendering: Define how fields appear in forms using renderInput
  • Display Output Rendering: Customize how values are displayed on details pages using renderOutput (optional)
  • Custom Validation: Implement specialized validation rules
  • Reusable Logic: Share custom field definitions across collections
  • Extend Base Types: Build on existing field types like string, number, etc.

Render Functions

Custom field types support two render functions:

  • renderInput (required): Used for form input rendering. Must return [render, getValue, cleanup?]
  • renderOutput (optional): Used for details page display. Can return either:
    • Single function: render() - Returns HTML string for display
    • Array: [render, cleanup?] - With optional cleanup function
    If undefined, uses built-in rendering for the field's extends type.

Function Interface

Both render functions receive a props object with the following structure:

Property Type Description
name string Field name (used for DOM element IDs)
value any Current field value
label string Field label for display (falls back to name if not set)

Configuration

Define custom fields in your Node.js configuration:

server.js
const fireengine = require('fireenginecms');

// Define custom field render functions
const renderDoubleInput = ({ name, value, label }) => [
  function render() {
    const [first, last] = (value || '').split(' ');
    return `
      <div class="double-input">
        <label>${label || name}</label>
        <input id="${name}_first" value="${first || ''}" placeholder="First" />
        <input id="${name}_last" value="${last || ''}" placeholder="Last" />
      </div>
    `;
  },
  function getValue() {
    const first = document.getElementById(\`\${name}_first\`).value;
    const last = document.getElementById(\`\${name}_last\`).value;
    return \`\${first} \${last}\`.trim();
  },
  function cleanup() {
    // Optional cleanup logic
  }
];

// Optional: Custom display rendering for details page
const renderDoubleInputOutput = ({ name, value, label }) => {
  // Simple function return for display
  return function render() {
    return `<strong style="color: #2196F3;">${value || 'No name provided'}</strong>`;
  };
};

app.use('/admin', fireengine({
  // ... other config
  customFields: {
    "double_input": {
      extends: "string",
      label: "Double Input",
      renderInput: renderDoubleInput,
      renderOutput: renderDoubleInputOutput // Optional - uses built-in rendering if undefined
    }
  }
}));

Using Custom Fields

Once defined, custom field types can be used in schema overrides:

Schema Override
schemaOverrides: {
  "users": {
    title: "User Management", 
    fields: [
      {
        name: "email",
        title: "Email Address",
        type: "string",
        required: true
      },
      {
        name: "fullName",
        title: "Full Name",
        type: "double_input", // Custom field type
        required: true
      },
      {
        name: "role",
        title: "User Role",
        type: "string",
        options: ["admin", "user", "moderator"]
      }
    ]
  }
}

Function Requirements

Function Required Description
render() Yes Returns HTML string for field display
getValue() Yes Returns current field value for form submission
cleanup() No Optional cleanup function when field is unmounted

Available in Schema Override GUI

Pro plan users can select custom field types in the visual Schema Override editor, making them available alongside standard field types like string, number, and boolean.

🆓 Free Plan Feature: Custom field types are available to all users through code configuration. Pro users additionally get access through the visual Schema Override GUI.

Authentication

FireEngine supports multiple authentication methods based on your plan:

Free Plan Authentication

  • Email/Password: Standard email and password authentication

Pro Plan Authentication

  • Social Logins: Google, Microsoft, GitHub, Facebook, Apple
  • Phone/SMS: Phone number verification
  • SAML SSO: Enterprise single sign-on
  • OIDC: OpenID Connect providers

Configuring Authentication Methods

Authentication methods are configured in your Firebase Console:

  1. Go to Firebase Console → Authentication → Sign-in method
  2. Enable desired authentication providers
  3. Configure provider settings (OAuth keys, domains, etc.)
  4. FireEngine will automatically detect enabled methods
🔍 Auto-Detection: FireEngine automatically detects which authentication methods are enabled in your Firebase project and shows only available options.

User Management

User Limits by Plan

  • Free Plan: 1 user maximum
  • Pro Plan: Unlimited users

Default Roles

Role Permissions Description
admin Full access Complete system administration
editor Read/Write data Content management and editing
viewer Read-only View data without modification

Adding Users

  1. Navigate to Users in the admin panel
  2. Click "Add User"
  3. Fill in user details (email, role, etc.)
  4. User receives invitation email

File Management

FireEngine provides comprehensive file upload and storage management with Firebase Storage integration.

Features

  • Drag & Drop Upload: Intuitive file uploading with visual feedback
  • Multi-file Support: Upload multiple files simultaneously
  • Image Previews: Automatic thumbnail generation for images
  • File Type Validation: Restrict uploads by file type and size
  • Folder Organization: Create and manage folder structures
  • Asset Browser: Visual file browser with search and filters

Configuration

Configure file upload limits using environment variables or configuration:

.env
# Maximum file upload size
FIREENGINE_STORAGE_MAX_UPLOAD_SIZE=5GB

# Or set via configuration
storageMaxUploadSize: "2GB"  # Supports GB, MB, KB units

Asset Field Type

Use the assets field type in your schema for file uploads:

Schema Configuration
fields: [
  {
    name: "featuredImage",
    type: "assets",
    min: 1,  // Required
    max: 1,  // Single file
    label: "Featured Image"
  },
  {
    name: "gallery",
    type: "assets",
    min: 3,  // Minimum 3 images
    max: 10,  // Maximum 10 images
    label: "Photo Gallery"
  }
]

Storage Security

FireEngine handles Firebase Storage access based on your configuration:

  • Default Mode (FIREENGINE_USE_FIRESTORE_ACCESS_RULES=false): FireEngine uses Firebase Admin SDK with full access, bypassing Storage security rules. Access control is managed through FireEngine's role-based permissions.
  • Direct Mode (FIREENGINE_USE_FIRESTORE_ACCESS_RULES=true): FireEngine respects your Firebase Storage security rules. Configure rules in Firebase Console → Storage → Rules.

Custom Roles

🔥 Pro Plan Feature

Create custom roles with granular permissions for specific collections and operations:

Creating Custom Roles

  1. Navigate to Users → Roles Management
  2. Click "Add Role"
  3. Define role name and description
  4. Set permissions for each collection
  5. Save and assign to users

Permission Types

  • Read: View collection data
  • Create: Add new documents
  • Update: Edit existing documents
  • Delete: Remove documents
  • Admin: Full collection management
💡 Best Practice: Create roles based on job functions (e.g., "Content Manager", "Customer Service", "Analytics Viewer") rather than generic permissions.

SSO Setup

🔥 Pro Plan Feature

Configure Single Sign-On (SSO) for enterprise authentication using SAML or OIDC providers.

SAML Configuration

Set up SAML authentication with providers like Okta, Auth0, or Active Directory:

  1. Go to Firebase Console → Authentication → Sign-in method
  2. Enable SAML provider
  3. Configure your SAML provider settings:
    • Entity ID
    • SSO URL
    • X.509 Certificate
  4. Add callback URL to your identity provider
  5. Test the connection

OIDC Configuration

Configure OpenID Connect for modern identity providers:

  1. Enable OpenID Connect in Firebase Authentication
  2. Configure provider details:
    • Provider name
    • Client ID
    • Client Secret
    • Issuer URL
  3. Map user attributes
  4. Set up redirect URLs

Supported Providers

Provider Protocol Configuration
Okta SAML/OIDC Full support
Auth0 SAML/OIDC Full support
Azure AD SAML/OIDC Full support
Google Workspace SAML Full support
Custom IdP SAML/OIDC Configurable

User Provisioning

FireEngine automatically creates user accounts on first SSO login with:

  • Email address from IdP
  • Display name mapping
  • Default role assignment (configurable)
  • Custom attributes mapping
⚠️ Important: SSO users bypass FireEngine's user limit as they're managed by your identity provider.