Firestore admin panel for ops, support, and content teams

By General Input

Give your team one safe screen to browse, edit, and export Firebase data, with every change logged, announced in Slack, and confirmed before it saves.

Integrations

  • Firebase
  • Slack Bot
  • Google Sheets

Type

App

Categories

  • Operations
  • Engineering

I want an internal data console for our Firebase Firestore database that ops, support, and content people can open instead of the Firebase console. They need to look things up and fix records every day, and right now that means either giving them access to the real Firebase console, which is confusing and dangerous, or asking an engineer every single time. Build an app where a non-technical viewer can browse, filter, edit, and export Firestore data safely, with hard guardrails around anything destructive.

The left sidebar lists every collection in the database using List Firestore Collection IDs. Each collection is a card showing its name and a document count, and that count must come from Run Firestore Aggregation Query with a count aggregation, never from pulling every document. Cache the counts and refresh them when the viewer reloads a collection or after a write.

Picking a collection opens the main table. Load rows with List Firestore Documents for the plain view and Run Firestore Query when the viewer applies filters or sorting, paging with the next page token rather than loading the whole collection. Firestore wraps every field in a typed envelope such as {"fields":{"name":{"stringValue":"Ada"},"age":{"integerValue":"36"}}}, so the table has to flatten those into plain readable columns: strings as text, integerValue and doubleValue as numbers (integerValue arrives as a JSON string, so convert it), booleanValue as a checkbox, timestampValue as a formatted date, and maps and arrays as a collapsed summary the viewer can expand. Derive the column set from the fields actually present across the loaded page, let the viewer show and hide columns, and give every column a filter and a click-to-sort header. Document names come back as full resource paths like projects/{projectId}/databases/(default)/documents/{collection}/{docId}, so show only the document id in the table and keep the full path for writes.

Clicking a row opens a detail drawer showing every field with an input suited to its type, refreshed with Get Firestore Document so the viewer is always editing current data. Saving must use Update Firestore Document with updateMask.fieldPaths limited to exactly the fields the viewer changed, because a patch without a field mask replaces the entire document and would wipe everything else. Convert edited values back into the correct typed envelope on save, and if a value does not fit the field's existing type, show a clear error rather than silently changing the type.

A New record button opens the same drawer empty and writes with Create Firestore Document, prefilling the field names the rest of the collection already uses so people do not invent new ones by accident. Delete lives in the drawer behind a confirmation dialog where the viewer has to type the document id before the button enables, then calls Delete Firestore Document. Selecting multiple rows in the table reveals a bulk bar that can set one field to one value across the selection, applied with Batch Write Firestore Documents, with a preview of exactly how many documents will change before it runs.

Every write, single or bulk, also writes an audit document into a dedicated Firestore collection (something like console_edits) using Create Firestore Document. Each audit record holds the signed in viewer's name and email, the collection and document id, the action (create, update, delete, bulk update), the before and after values of the affected fields, and a timestamp. A Recent changes tab reads that collection back with Run Firestore Query ordered by timestamp descending and renders a readable feed: who changed what, in which collection, from what value to what value. The audit collection itself must never be editable from inside the console.

After each successful write, post a one line change note to Slack with Slack Bot Send a Message, for example "Priya updated orders/AB12: status from pending to shipped". The destination channel is set in app config, chosen from a picker populated by List Channels. Bulk edits post a single summary line rather than one message per document.

An Export button takes the current filtered and sorted view and appends it to a tab in a Google Sheet with Google Sheets Append Values, headers first and then the flattened human readable values, plus a final row noting who exported it and when. The spreadsheet and tab are set in app config. The whole point is that people stop screenshotting and hand copying data out of the database.

Add a Check this collection button that kicks off a background agent. The agent samples the collection with Run Firestore Query (a few hundred documents, or all of them if the collection is smaller), works out the shape that the majority of documents follow, then compares every sampled document against that shape. It should flag documents missing fields that most others have, fields holding a different type than the majority (a number stored as a string, a date stored as free text), and referenceValue fields pointing at documents that no longer exist, verified with Batch Get Firestore Documents. It writes a findings report back into Firestore as a document in a reports collection with Create Firestore Document, containing the collection checked, the timestamp, how many documents were sampled, the inferred majority shape, and a list of findings where each one carries a document id, the problem, and a suggested fix.

A Data health tab reads the latest report for the selected collection and renders it as grouped findings with counts. Each finding gets a Fix button, but nothing is written until the viewer approves it: clicking Fix shows exactly what will change, and only then applies it with Update Firestore Document using a field mask, or with Batch Write Firestore Documents when the viewer approves a group of identical fixes at once. Approved fixes run through the same audit trail and Slack note as manual edits. Findings the viewer dismisses get marked dismissed on the report so they do not come back.

Bake the safety rules in everywhere, because the reason this app exists is that these people must never touch the real Firebase console. App config holds a list of collections marked read-only: they stay visible and browsable, but every edit, delete, bulk action, and health fix is disabled with a visible reason rather than hidden. Config can also hide collections from the sidebar entirely. Deletes always require the typed confirmation. Counts always come from the aggregation query, never from downloading documents. Show the signed in viewer's name in the header so it is obvious the app is acting as them, and stamp that name onto every audit record.

Related prompts

Explore more prompts
Call overdue Xero customers with an AI collections agentLocal listing health board for every location you manageLet support send one-off Loops emails without an engineerA brand asset library your marketing team actually searchesTurn Mailjet email clicks into ranked HubSpot follow-upsClean out the Looker dashboards and Looks nobody opensStop cold emails to anyone with a live deal in PipedriveLiveKit live operations console for room moderationWake up dormant Keap leads with a researched reasoniMessage campaign console with pre-flight checks and delivery board