Register your interest: Tag @Cody, get an agent
BlogEngineering

Firebase and CodeWords: automating around the client SDK

Security rules do not apply to the Admin SDK, Firestore queries are deliberately limited, and reads are what you pay for. What that means for automation sitting beside a Firebase app.

Osman RamadanOsman Ramadan11 min read

Summarize with AI

Firebase and CodeWords: automating around the client SDK
On this page

Firebase is designed around clients talking directly to the database, with security rules deciding what each user may do. Automation enters through a different door — the Admin SDK — and that door bypasses the rules entirely.

That is the fact worth internalising before anything else. Every constraint you carefully expressed in security rules is invisible to your automation, which has full access by design and will do exactly what it is told.

What we'll cover

Rules do not apply to you

The Admin SDK bypasses security rules completely. It is server-side, trusted, and unrestricted.

Validation in rules is not validation of your writes. If the only place a field's shape is enforced is in security rules, automation can write anything, and it eventually will.

Ownership checks do not apply. Rules preventing one user from reading another's data are irrelevant to a process with full access.

A service account key is a full-access credential. Treat it accordingly — scoped where the platform permits, rotated, and never in a repository.

The practical response: validate in your automation what the rules would have validated, restrict the service account to the project it needs, and prefer writing to collections the application does not own where the design allows it.

Queries are deliberately limited

Firestore's query model is constrained on purpose, so that every query stays fast regardless of collection size. The constraints are real and they shape what automation can do.

No arbitrary joins. You denormalise instead, which means data is duplicated and updating it is your responsibility.

Composite indexes are required for most multi-field queries, and the error helpfully gives you a link to create one — but it is a failure at runtime, not at write time.

Inequality filters are restricted, historically to a single field, which rules out several query shapes people expect.

No aggregation beyond counts and a few functions. Summing a field across a large collection means reading it all or maintaining a running total.

Collection group queries search across subcollections of the same name, which is powerful and needs its own indexes.

The consequence for reporting: anything analytical is better done against an export than against Firestore directly, which is covered below.

What Firebase reaches

Firestore documents and collections, through the Admin SDK, with transactions and batched writes.

Realtime Database, the older store, with a different model — a single JSON tree, different query behaviour, and different pricing.

Authentication users can be listed, created, modified, and given custom claims, which is how roles are usually implemented.

Cloud Storage holds files, with its own rules that likewise do not apply to admin access.

Cloud Messaging sends push notifications.

Remote Config holds values the application reads at runtime.

Cloud Functions run code on Firestore events, authentication events, or schedules, inside Google's environment.

BigQuery export streams Firestore and Analytics data into a warehouse, which is where analytical work belongs.

Connecting it to CodeWords

CodeWords connects to more than 3,000 integrations, and the connection is made once and reused.

  1. Open CodeWords and start a new automation.
  2. Describe what should happen in plain language to Cody, the automation builder: which collection, which documents, and what should happen to them.
  3. Authorize the connection with a service account for the specific project, granted the minimum roles.
  4. Describe the exceptions: a document missing a field, a query requiring an index that does not exist, a write that would exceed a batch limit.
  5. Run it against a non-production project before anything touches real data.

You describe the outcome; Cody builds it, connects it, and deploys it. The free plan covers light use, with Pro at $39 per month and Business at $100 per month as usage grows; details are on the pricing page.

Seven automations worth building

Data quality checks. Documents missing required fields, orphaned references after a deletion, and denormalised copies that have drifted from their source. Denormalisation guarantees this class of problem and nothing else detects it.

Read volume reporting. Which collections and which access patterns generate the most reads, since reads are the bill and the biggest consumer is often a query nobody remembers writing.

User lifecycle actions. Provisioning, role assignment through custom claims, and cleanup on deletion, driven by whatever system owns the truth about who a user is.

Export for analysis. Feed a warehouse so analytical questions are answered in SQL rather than by reading a collection.

Cleanup of expired data. Old sessions, orphaned files, and soft-deleted documents past retention. It reduces cost and it is the work nobody schedules.

Aggregate maintenance. Counts and totals kept current, because Firestore cannot compute them cheaply and every application ends up needing them.

Cross-system reconciliation. Firestore against your billing platform or your CRM, which is where drift is genuinely discovered.

Reads are the bill

Firestore charges per document read, and this catches teams out in specific ways.

Every document in a query result is a read, whether or not you use it. A query returning a thousand documents to filter down to three costs a thousand reads.

Filter in the query, not afterwards. This is the difference between an automation that costs pennies and one that costs noticeably.

Select only the fields you need where supported, and prefer narrow queries over broad ones with client-side filtering.

Avoid reading a collection to count it. Maintain a counter, or use the aggregation support available for counts.

Scheduled scans are the classic cost surprise. An automation reading an entire collection every hour costs the collection size times twenty-four, daily, and it does so quietly.

Export for analysis rather than scanning. A BigQuery export scanned freely costs far less than repeated full-collection reads.

Cloud Functions or external automation

Both are reasonable and they suit different work.

Cloud Functions for document triggers. Reacting to a write with low latency, inside Google's environment, is what they are for.

External automation for anything crossing systems. Once the logic involves your CRM, your billing platform, and a notification, it belongs where those connections are maintained rather than in a function whose dependencies nobody upgrades.

External automation for scheduled reporting, which needs no proximity to the data and benefits from living alongside your other reports.

Watch for cold starts and timeouts in functions doing substantial work, which is a common reason a trigger-based approach disappoints.

Avoid trigger loops. A function writing to the collection it watches is a classic and expensive mistake, and the bill arrives before the realisation does.

Auth, custom claims, and the token delay

User management is where Firebase automation most often touches something users notice immediately.

Custom claims are how roles usually work, set through the Admin SDK and carried in the user's token.

Claims do not take effect until the token refreshes. A user granted an upgraded role keeps their old token until it expires or the client forces a refresh, which is the reason for the recurring report of a permission change that did not work.

Claims have a size limit, so they hold a role or a small set of flags, not a profile. Anything larger belongs in a document.

Deleting a user is not deleting their data. Their documents and files remain, and a deletion that leaves them behind is both a retention problem and a source of orphaned references.

Listing users is paginated and large projects take a while, so anything auditing accounts should expect to run for minutes rather than seconds.

Disabling is usually better than deleting for anything reversible, and it is reversible.

Building it so it survives

Validate before writing, since security rules will not do it for you.

Use batched writes and transactions where consistency matters, respecting the batch size limit.

Make writes idempotent. Use a deterministic document identifier derived from the source rather than an auto-generated one.

Create indexes deliberately rather than discovering the need at runtime in production.

Report the outcome. Documents read, written, skipped, and an estimate of the reads consumed, which keeps the cost visible.

Limits worth knowing about

A document has a size limit, which matters for anything appending to an array indefinitely.

There is a sustained write limit per document, so a single counter updated by many processes becomes a bottleneck — the reason distributed counter patterns exist.

Batched writes are capped at a fixed number of operations.

Composite indexes are required for many queries and are not created automatically.

Reads, writes, deletes, and storage are all billed separately, and deletes are not free, which surprises people running a cleanup over a large collection.

What to build first

Read volume reporting: which collections and access patterns generate the most reads, tracked over time. It is cheap, it writes nothing, and it usually identifies one query — often a scheduled scan somebody added and forgot — responsible for a large share of the bill.

Two habits make the difference. Report the change week on week, not just the total, since a new expensive pattern is the thing you want to catch. And include an estimate of the reads your own automations consume, so the reporting is honest about its own cost.

Frequently asked questions

Do security rules protect against automation mistakes?

No. The Admin SDK bypasses rules entirely, so any validation living only in rules does not apply to your automation. Validate in the automation itself, and restrict the service account to the project it needs.

Why is our Firestore bill high?

Reads, almost always, and usually a query returning far more documents than it uses or a scheduled job scanning a whole collection. Every document in a result set is billed whether or not you look at it.

How do I count documents in a collection?

Maintain a counter, or use the aggregation support for counts. Reading the collection to count it charges a read per document, which is the most expensive possible way to obtain a number.

Should I use Cloud Functions or external automation?

Functions for low-latency reactions to document writes inside Google's environment. External automation for anything involving other systems or for scheduled reporting, where the connections and the maintenance live alongside your other work.

Why does my query fail asking for an index?

Because Firestore requires composite indexes for most multi-field queries and does not create them automatically. The error links to the creation page, and the discipline is to create them when you write the query rather than when production fails.

How do I keep denormalised copies consistent?

You write the code that updates them, and you check. Firestore has no joins by design, so duplication is the trade, and a reconciliation report comparing copies against their source is the only thing that catches drift.

Can I run analytical queries against Firestore?

Not usefully. Export to BigQuery and query there. Firestore's query model is built for fast, narrow reads at any scale, and analytical work against it is both slow and expensive.

Why has a role change not taken effect?

Because custom claims travel in the user's token and the old token is still valid. The change applies when the token refreshes, so the client has to force a refresh for anything that should apply immediately.

Does deleting a user delete their data?

No. Their documents and storage objects remain, along with any references to them. Cleanup is your responsibility, and skipping it leaves both a retention problem and orphaned references that break other queries.

Get started today

Your first workflow is free to build.

Describe what you need. Cody handles the build, the connections, and the deployment.