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:
- Enable Firebase Authentication with Email/Password provider
- Create a user account with the same email as
ownerEmail
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');
});
# Install dependencies
npm install express fireenginecms
# Run the server
node server.js
/admin.
Installation
System Requirements
- Node.js 16+
- Firebase project with Firestore enabled
- Firebase Admin SDK service account
Installation Methods
Node.js Application
{
"name": "my-fireengine-app",
"version": "1.0.0",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.18.2",
"fireengine": "latest"
}
}
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
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'
})
);
# 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:
# 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
- Go to Firebase Console
- Select your project
- Go to Project Settings → Service Accounts
- Click "Generate new private key"
- Download and save as
firebase-admin-key.json
2. Web App Configuration
- In Firebase Console, go to Project Settings → General
- Scroll to "Your apps" section
- Select your web app or create one
- Copy the config object and save as
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"
}
Express.js Integration
Once you have your Firebase configuration files, integrate FireEngine with Express.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
- Collection Scanning: Detects all collections in your Firestore database
- Field Analysis: Analyzes document structures to determine field types
- 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
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
- Navigate to Settings → Schema Management
- Click the edit icon (✏️) next to any collection
- Customize field properties using the visual editor
- 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:
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
extendstype. - Single function:
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:
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:
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.
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:
- Go to Firebase Console → Authentication → Sign-in method
- Enable desired authentication providers
- Configure provider settings (OAuth keys, domains, etc.)
- FireEngine will automatically detect enabled methods
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
- Navigate to Users in the admin panel
- Click "Add User"
- Fill in user details (email, role, etc.)
- 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:
# 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:
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
- Navigate to Users → Roles Management
- Click "Add Role"
- Define role name and description
- Set permissions for each collection
- 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
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:
- Go to Firebase Console → Authentication → Sign-in method
- Enable SAML provider
- Configure your SAML provider settings:
- Entity ID
- SSO URL
- X.509 Certificate
- Add callback URL to your identity provider
- Test the connection
OIDC Configuration
Configure OpenID Connect for modern identity providers:
- Enable OpenID Connect in Firebase Authentication
- Configure provider details:
- Provider name
- Client ID
- Client Secret
- Issuer URL
- Map user attributes
- 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