Configuration files
Fireemu reads both TOML (fireemu.toml) and JSON (fireemu.json); discovery loads the file in the current directory and refuses to start if both exist, unless you select one with --config.
Fireemu reads two kinds of files:
fireemu.tomlholds Fireemu’s own settings, such as the profile, Authentication project configuration and the clock. It containsschemaVersion = 1. See the configuration schema.firebase.jsonis the file the Firebase CLI uses. Fireemu reads ports, Security Rules, indexes and Functions codebases from it, every time it starts.
Keep Fireemu-specific settings in fireemu.toml rather than in firebase.json. To use both, name the firebase.json in fireemu.toml:
#:schema https://raw.githubusercontent.com/t-k/fireemu/main/spec/config/fireemu.schema.jsonschemaVersion = 1profile = "strict"firebaseJson = "firebase.json"{ "schemaVersion": 1, "profile": "strict", "firebaseJson": "firebase.json"}npx fireemu init --firebase-json firebase.json writes this for you.
Which files are loaded
Section titled “Which files are loaded”up, exec, emulators:start and emulators:exec choose their configuration files as follows.
--config <file>and--firebase-json <file>load exactly the files they name, and nothing is searched for.--configparses a.tomlpath as TOML (case-insensitive, including.TOML) and every other extension as JSON. A TOML configuration must setschemaVersion = 1; it is never read as afirebase.json, which is JSON only.--firebase-jsonalways reads JSON.- Otherwise, the single
fireemu.tomlorfireemu.jsonin the current directory is loaded. If both files exist, startup is refused: remove one or select a file with--config. ItsfirebaseJsonentry, resolved relative to the loaded file, names thefirebase.jsonto load. Afirebase.jsonbeside afireemu.tomlwithout afirebaseJsonentry is not loaded, and the startup output says so. Neitherfireemu.tomlnorfireemu.jsonin a parent directory is used. Relative paths inside a canonical file (rules.source,storage.rules,functions.source,firestore.indexFileand the other file settings) are read from the working directory, whichever directory the file is in; onlyfirebaseJsonand the paths inside afirebase.jsonare read from the file’s own directory. - Otherwise, the nearest
firebase.jsonis loaded: the one in the current directory, else the first one found in a parent directory, as the Firebase CLI finds it. The.firebasercbeside it is read too. - Otherwise, the built-in defaults apply, and no Security Rules are loaded.
--no-config-discovery skips steps 2 and 3. The config: line of the startup output names the files that were loaded.
File ownership checks
Section titled “File ownership checks”A discovered file can name Functions code to run and the rules to enforce, so on Unix the search checks who owns what it finds, as git checks repository ownership. The Firebase CLI does not check this. The trusted owners are you, root, and, when you run as root through sudo, the user in SUDO_UID.
- A
fireemu.toml,fireemu.jsonorfirebase.jsonwhose owner is not trusted, or that any user can write, is skipped with a warning. Group write is allowed. - The search stops before a parent directory whose owner is not trusted or that any user can write, such as
/tmp. - A current directory that any user can write is not searched at all.
- A discovered file larger than 16 MiB is refused.
To load a skipped file anyway, name it with --config or --firebase-json. To silence the warning, pass --no-config-discovery. On Windows, ownership is not checked.
Two common setups run into this rule:
- A root container with a bind-mounted checkout, such as a GitHub Actions
container:job, ordocker run -v "$PWD":/appas root. The files are owned by a host user the container’s root does not trust. Use the explicit flags, orchownthe checkout. Rootless Podman maps your user to the container’s root, so it is not affected. sudo. Files owned by the user inSUDO_UIDare trusted.
Validate your configuration
Section titled “Validate your configuration”fireemu.toml is validated at startup, and a value Fireemu does not accept stops it with an error. A key the schema does not list and a value of the wrong type are refused in both formats by up, exec and config show, naming the file, the key and the type it should have had, for example fireemu.toml: daemon.firestorePort must be an integer, found a string. Integer settings refuse floats even when their value is integral: write 8080 rather than 8080.0, as the error message suggests. The configuration schema is a JSON Schema you can also use in your editor.
fireemu capabilities prints the capability manifest for the profile your configuration resolves to.
TOML values and JSON null
Section titled “TOML values and JSON null”TOML files use the same JSON Schema, validation and defaults as JSON files. Start a file with #:schema https://raw.githubusercontent.com/t-k/fireemu/main/spec/config/fireemu.schema.json to select the schema in Taplo or Even Better TOML. Quote timestamp values: TOML datetimes are refused with the key name because the schema has no datetime type.
TOML has no null. For every nullable setting below, omit the key in its containing table; for nullable array items, omit the item. Keep the containing table or array when its presence is intentional. Empty arrays and empty tables retain their existing meaning.
| Nullable JSON keys | Meaning of null and TOML omission |
|---|---|
limits.queryCatalog, firestore.textSearch.visibilityLag |
Accepted with no runtime effect. Omission also removes the explicit value and startup note for these keys. |
limits.firestorePlan.compositeIndexLimitOverride, limits.firestorePlan.singleFieldConfigLimitOverride, limits.firestorePlan.enterpriseIndexLimitOverride |
No override; non-null overrides are currently refused. |
auth.providers, auth.providers.oidc, auth.providers.saml |
No provider seed declaration. An empty array explicitly declares an empty replacement and is different from omission. |
auth.providers.oidc[].displayName, auth.providers.oidc[].clientSecret, auth.providers.saml[].displayName |
No optional provider value. |
auth.authorizedDomains |
No seed; preserve the default domains. An empty array declares no domains. |
auth.authorizedDomains[] |
Ignore this item; leave it out of the TOML array. |
auth.mfa, auth.multiTenant, auth.tenants |
No declaration; keep the applicable defaults. |
auth.mfa.enabledProviders, auth.mfa.providerConfigs |
No providers of this kind in the declared MFA configuration. Keep the auth.mfa table if declaring MFA. |
auth.mfa.providerConfigs[].totpProviderConfig |
Ignore this provider entry; omit the key in that entry. |
auth.mfa.providerConfigs[].totpProviderConfig.adjacentIntervals |
Use zero adjacent intervals in the declared TOTP provider; keep its table. |
auth.blockingFunctions.triggers.beforeCreate, auth.blockingFunctions.triggers.beforeSignIn |
Disable this trigger in an explicit trigger selection. Keep [auth.blockingFunctions.triggers]; omitting that entire table enables discovery instead. |
auth.quota.signUpQuotaConfig |
Clear the temporary quota override, including an imported override. Keep [auth.quota] empty; omitting the entire quota table preserves an imported override. |
auth.passwordPolicy.constraints.maxLength, auth.passwordPolicyOverrides[].passwordPolicy.constraints.maxLength |
No custom maximum length. |