Skip to content

The JavaScript editor

Some questions cannot be expressed as a where clause. The JavaScript editor gives you the real Firestore Admin SDK and gets out of the way.

Writing a script

Scripts export an async run function. Whatever you return is rendered as documents in the current view.

async function run() {
  const snap = await db.collection('users').where('plan', '==', 'pro').get();
  return snap.docs;
}

Press Ctrl+Enter (Cmd+Enter on macOS) to run.

If you return a Query without calling .get(), FireFetch executes it for you:

async function run() {
  return db.collection('orders').orderBy('createdAt', 'desc').limit(20);
}

What is available

Global What it is
db The Firestore instance for the current database
admin The Firebase Admin namespace, including admin.auth()
_ lodash
FieldValue Server transforms: serverTimestamp(), increment(), arrayUnion()
Timestamp Exact timestamps, microseconds preserved
GeoPoint, FieldPath The remaining Firestore value types
Filter, AggregateField Composite filters and aggregation queries
fetch Call an HTTP API from inside a script
fs Read and write local files
uuid, sleep Generate ids; pause between batches
require Node built-ins and FireFetch’s bundled dependencies
projectId, databaseId Which database this script is pointed at

Because these are the genuine SDK objects, everything the SDK supports works — getAll, listCollections, batch(), runTransaction, bulkWriter, count(), aggregations and cursors included.

Autocomplete

The editor is Monaco, loaded with the real type definitions for the Admin SDK and lodash. Autocomplete and hover documentation reflect the actual API, not a hand-maintained list.

Output and logging

console.log, console.table, console.group and console.time stream into the Log view as the script runs, not after it finishes. A long migration shows progress rather than a spinner.

async function run() {
  const snap = await db.collection('orders').get();
  console.log(`Processing ${snap.size} orders`);

  for (const [i, doc] of snap.docs.entries()) {
    if (i % 100 === 0) console.log(`  …${i}`);
  }
}

Stopping a script

Scripts run in a separate process. Pressing Stop kills that process, so a runaway while (true) never freezes the application — which means you can experiment without being careful.

Errors

When a script throws, the stack trace refers to script.js and your own line numbers, so the reported line is the line you wrote.

Write access

Scripts are subject to the same write gate as everything else. A script cannot write to a database that is still read-only, regardless of what the code says. See Enabling write access.

Saving scripts

Scripts worth keeping go in the script library, where they can be named, tagged and run against any database you have connected.

Something unclear or out of date? Email[email protected].