Skip to content

firestore:rules deploy silently no-ops against multi-DB array form in firebase.json; scoped form crashes in deployIndexes #10468

@yusufalways

Description

@yusufalways

[REQUIRED] Environment info

firebase-tools: Reproduces on 14.2.1, 13.x latest, and 13.29 (all three tested).

Platform: macOS, Node 20, pnpm.

[REQUIRED] Test case

firebase.json declares Firestore as an array of database-scoped entries (the multi-DB shape from the docs):

{
  "firestore": [
    { "database": "(default)", "rules": "firestore.rules", "indexes": "firestore.indexes.json" },
    { "database": "devdb",     "rules": "firestore.rules", "indexes": "firestore.indexes.json" }
  ]
}

Local firestore.rules has at least one rule that differs from the live ruleset on either database.

[REQUIRED] Steps to reproduce

Reproducer 1 — silent no-op:

firebase deploy --only firestore:rules --project <project-id>

Reproducer 2 — scoped form crashes:

firebase deploy --only 'firestore:rules:(default)' --project <project-id>

Reproducer 3 — debug log:

firebase deploy --only firestore:rules --debug --project <project-id> 2>&1 | tee /tmp/rules-debug.log

[REQUIRED] Expected behavior

  • Reproducer 1 should deploy the rules file to every database in the array whose rules differ from live, printing one released rules ... to cloud.firestore (<db-name>) line per release.
  • Reproducer 2 should be the way to deploy rules to a single database in the array — either work, or fail with an actionable error like firestore:rules:<db-name> is not a recognized filter; use firestore:<db-name> to deploy rules + indexes for that database.
  • At minimum, when the planner produces an empty rules changeset against a non-empty rules diff vs. live, the CLI should print i firestore: rules unchanged on all databases so the operator knows nothing was uploaded. The silent no-op is the most operationally dangerous of the three — indistinguishable from a successful deploy.

[REQUIRED] Actual behavior

Reproducer 1 (silent no-op). Output is just:

=== Deploying to '<project-id>'...

i  deploying firestore
✔  Deploy complete!

No rules are released. Live ruleset unchanged. Exit 0. The --debug log shows only datastore.indexes.* IAM permissions being checked, then i deploying firestore, then ✔ Deploy complete!. No rules-related lifecycle lines anywhere — the rules planner is producing an empty changeset against the multi-DB array form.

Reproducer 2 (scoped form crash). Output is:

i  firestore: deploying indexes...
TypeError: Cannot read properties of undefined (reading 'map')
    at deployIndexes (.../firebase-tools/lib/deploy/firestore/deploy.js:24:38)

Two problems visible: (a) the :rules filter isn't honored — the CLI still tries the indexes path; (b) when filtered to one DB, the indexes config it receives is undefined and it crashes before reaching the rules step.

Working incantation (current workaround). --only firestore:(default) (no :rules) deploys rules + indexes for that single DB:

i  firestore: reading indexes from firestore.indexes.json...
i  cloud.firestore: checking firestore.rules for compilation errors...
✔  cloud.firestore: rules file firestore.rules compiled successfully
i  firestore: deploying indexes...
i  firestore: uploading rules firestore.rules...
✔  firestore: deployed indexes in firestore.indexes.json successfully for (default) database
✔  firestore: released rules firestore.rules to cloud.firestore

✔  Deploy complete!

This works, but force-co-deploys indexes — there's no way to deploy only the rules, and it doesn't iterate the array (deploys to one DB at a time, requires running the command once per database).

Versions tested:

firebase-tools --only firestore:rules --only firestore:rules:(default) --only firestore:(default)
14.2.1 silent no-op TypeError: ... map ✓ works
13.x (latest) silent no-op not tested not tested
13.29 silent no-op not tested not tested

Suggested triage. Most likely the rules-deploy planner in lib/deploy/firestore/ doesn't iterate the array-shape firestore config and instead expects the legacy single-object shape, falling back to "no databases to deploy rules to" when it sees the array. The scoped-filter crash in deployIndexes looks like a separate bug where the per-DB-scoped path skips the indexes config load.

Happy to provide a full debug log if it'd help triage.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions