From a8fccb4eeadd7dfb4824158cdaf10f3d71babce0 Mon Sep 17 00:00:00 2001 From: "harshoza24@gmail.com" Date: Mon, 6 Apr 2026 15:41:37 -0500 Subject: [PATCH 01/10] initial impl of datbase edition in fs emulator --- npm-shrinkwrap.json | 2 +- src/emulator/controller.ts | 12 ++++++++++++ src/emulator/downloadableEmulators.ts | 1 + src/emulator/firestoreEmulator.ts | 1 + src/firebaseConfig.ts | 1 + 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index d93ac9def70..ed11cbe236b 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -26785,7 +26785,7 @@ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "requires": { - "ajv": "^8.17.1" + "ajv": "^8.0.0" } }, "ansi-align": { diff --git a/src/emulator/controller.ts b/src/emulator/controller.ts index 0d012ffd1ae..ba74264e8bc 100755 --- a/src/emulator/controller.ts +++ b/src/emulator/controller.ts @@ -650,6 +650,13 @@ export async function startAll( auto_download: true, }; + const editionOption = options.config.src.emulators?.firestore?.database_edition; + let edition = "standard"; + if (editionOption !== undefined) { + edition = editionOption; + } + args.database_edition = edition; + if (exportMetadata.firestore) { utils.assertIsString(options.import); const importDirAbsPath = path.resolve(options.import); @@ -730,6 +737,11 @@ export async function startAll( const firestoreEmulator = new FirestoreEmulator(args); await startEmulator(firestoreEmulator); + firestoreLogger.logLabeled( + "SUCCESS", + Emulators.FIRESTORE, + `Firestore Emulator is running on ${edition} database edition.`, + ); firestoreLogger.logLabeled( "SUCCESS", Emulators.FIRESTORE, diff --git a/src/emulator/downloadableEmulators.ts b/src/emulator/downloadableEmulators.ts index d459e4b8b8d..5029b9e2fb9 100755 --- a/src/emulator/downloadableEmulators.ts +++ b/src/emulator/downloadableEmulators.ts @@ -244,6 +244,7 @@ const Commands: { [s in DownloadableEmulators]: DownloadableEmulatorCommand } = "host", "rules", "websocket_port", + "database_edition", "functions_emulator", "seed_from_export", "project_id", diff --git a/src/emulator/firestoreEmulator.ts b/src/emulator/firestoreEmulator.ts index 1254c3f5519..3907d8a8661 100644 --- a/src/emulator/firestoreEmulator.ts +++ b/src/emulator/firestoreEmulator.ts @@ -14,6 +14,7 @@ export interface FirestoreEmulatorArgs { port?: number; host?: string; websocket_port?: number; + database_edition?: string; project_id?: string; rules?: string; functions_emulator?: string; diff --git a/src/firebaseConfig.ts b/src/firebaseConfig.ts index 33c6eaceefe..988f60f8d77 100644 --- a/src/firebaseConfig.ts +++ b/src/firebaseConfig.ts @@ -240,6 +240,7 @@ export type EmulatorsConfig = { host?: string; port?: number; websocketPort?: number; + database_edition?: string; }; functions?: { host?: string; From 3233e772eef612253e75371509049eb10a8762f1 Mon Sep 17 00:00:00 2001 From: "harshoza24@gmail.com" Date: Mon, 6 Apr 2026 17:05:32 -0500 Subject: [PATCH 02/10] updated to include manual CLI override --- schema/firebase-config.json | 3 +++ src/commands/emulators-start.ts | 1 + src/emulator/commandUtils.ts | 3 +++ src/emulator/controller.ts | 16 ++++++++++------ src/firebaseConfig.ts | 2 +- src/options.ts | 1 + 6 files changed, 19 insertions(+), 7 deletions(-) diff --git a/schema/firebase-config.json b/schema/firebase-config.json index a74c1856af4..601e6bfb7a3 100644 --- a/schema/firebase-config.json +++ b/schema/firebase-config.json @@ -1420,6 +1420,9 @@ }, "websocketPort": { "type": "number" + }, + "databaseEdition": { + "type": "string" } }, "type": "object" diff --git a/src/commands/emulators-start.ts b/src/commands/emulators-start.ts index 6ddc4f3d135..3abdc211e48 100644 --- a/src/commands/emulators-start.ts +++ b/src/commands/emulators-start.ts @@ -25,6 +25,7 @@ export const command = new Command("emulators:start") .option(commandUtils.FLAG_IMPORT, commandUtils.DESC_IMPORT) .option(commandUtils.FLAG_EXPORT_ON_EXIT, commandUtils.DESC_EXPORT_ON_EXIT) .option(commandUtils.FLAG_VERBOSITY, commandUtils.DESC_VERBOSITY) + .option(commandUtils.FLAG_DATABASE_EDITION, commandUtils.DESC_DATABASE_EDITION) // eslint-disable-next-line @typescript-eslint/no-explicit-any .action((options: Options) => { const killSignalPromise = commandUtils.shutdownWhenKilled(options); diff --git a/src/emulator/commandUtils.ts b/src/emulator/commandUtils.ts index 843ae373d5e..f982cca046f 100644 --- a/src/emulator/commandUtils.ts +++ b/src/emulator/commandUtils.ts @@ -46,6 +46,9 @@ export const EXPORT_ON_EXIT_USAGE_ERROR = `"${FLAG_EXPORT_ON_EXIT_NAME}" must be used with "${FLAG_IMPORT}"` + ` or provide a dir directly to "${FLAG_EXPORT_ON_EXIT}"`; +export const FLAG_DATABASE_EDITION = "--databaseEdition [edition]"; +export const DESC_DATABASE_EDITION = "start emulator in either standard or enterprise edition."; + export const EXPORT_ON_EXIT_CWD_DANGER = `"${FLAG_EXPORT_ON_EXIT_NAME}" must not point to the current directory or parents. Please choose a new/dedicated directory for exports.`; export const FLAG_VERBOSITY_NAME = "--log-verbosity"; diff --git a/src/emulator/controller.ts b/src/emulator/controller.ts index ba74264e8bc..f65856ea5d2 100755 --- a/src/emulator/controller.ts +++ b/src/emulator/controller.ts @@ -642,20 +642,24 @@ export async function startAll( const firestoreAddr = legacyGetFirstAddr(Emulators.FIRESTORE); const websocketPort = legacyGetFirstAddr("firestore.websocket").port; + const configEdition = options.config.src.emulators?.firestore?.databaseEdition; + const cliEdition = options.databaseEdition; + const edition = cliEdition !== undefined ? cliEdition : configEdition; + const args: FirestoreEmulatorArgs = { host: firestoreAddr.host, port: firestoreAddr.port, websocket_port: websocketPort, + database_edition: edition, project_id: projectId, auto_download: true, }; - const editionOption = options.config.src.emulators?.firestore?.database_edition; - let edition = "standard"; - if (editionOption !== undefined) { - edition = editionOption; - } - args.database_edition = edition; + // let edition = "standard"; + // if (configEdition !== undefined) { + // edition = configEdition; + // } + // args.database_edition = edition; if (exportMetadata.firestore) { utils.assertIsString(options.import); diff --git a/src/firebaseConfig.ts b/src/firebaseConfig.ts index 988f60f8d77..0875ae76721 100644 --- a/src/firebaseConfig.ts +++ b/src/firebaseConfig.ts @@ -240,7 +240,7 @@ export type EmulatorsConfig = { host?: string; port?: number; websocketPort?: number; - database_edition?: string; + databaseEdition?: string; }; functions?: { host?: string; diff --git a/src/options.ts b/src/options.ts index c5c973e45ea..a6c04f3f9e1 100644 --- a/src/options.ts +++ b/src/options.ts @@ -26,6 +26,7 @@ export interface BaseOptions { // Emulator specific import/export options exportOnExit?: boolean | string; import?: string; + databaseEdition?: string; isMCP?: boolean; From 14450d43726f252d4e4754792c8bff0e0339510d Mon Sep 17 00:00:00 2001 From: "harshoza24@gmail.com" Date: Tue, 7 Apr 2026 16:34:36 -0500 Subject: [PATCH 03/10] updated naming of flag --- schema/firebase-config.json | 2 +- src/commands/emulators-start.ts | 2 +- src/emulator/commandUtils.ts | 4 ++-- src/emulator/controller.ts | 22 +++++++++++----------- src/emulator/downloadableEmulators.ts | 2 +- src/emulator/firestoreEmulator.ts | 2 +- src/firebaseConfig.ts | 2 +- src/options.ts | 2 +- 8 files changed, 19 insertions(+), 19 deletions(-) diff --git a/schema/firebase-config.json b/schema/firebase-config.json index 601e6bfb7a3..3800ffd19f8 100644 --- a/schema/firebase-config.json +++ b/schema/firebase-config.json @@ -1421,7 +1421,7 @@ "websocketPort": { "type": "number" }, - "databaseEdition": { + "edition": { "type": "string" } }, diff --git a/src/commands/emulators-start.ts b/src/commands/emulators-start.ts index 3abdc211e48..48482a14885 100644 --- a/src/commands/emulators-start.ts +++ b/src/commands/emulators-start.ts @@ -25,7 +25,7 @@ export const command = new Command("emulators:start") .option(commandUtils.FLAG_IMPORT, commandUtils.DESC_IMPORT) .option(commandUtils.FLAG_EXPORT_ON_EXIT, commandUtils.DESC_EXPORT_ON_EXIT) .option(commandUtils.FLAG_VERBOSITY, commandUtils.DESC_VERBOSITY) - .option(commandUtils.FLAG_DATABASE_EDITION, commandUtils.DESC_DATABASE_EDITION) + .option(commandUtils.FLAG_EDITION, commandUtils.DESC_EDITION) // eslint-disable-next-line @typescript-eslint/no-explicit-any .action((options: Options) => { const killSignalPromise = commandUtils.shutdownWhenKilled(options); diff --git a/src/emulator/commandUtils.ts b/src/emulator/commandUtils.ts index f982cca046f..e64800df36d 100644 --- a/src/emulator/commandUtils.ts +++ b/src/emulator/commandUtils.ts @@ -46,8 +46,8 @@ export const EXPORT_ON_EXIT_USAGE_ERROR = `"${FLAG_EXPORT_ON_EXIT_NAME}" must be used with "${FLAG_IMPORT}"` + ` or provide a dir directly to "${FLAG_EXPORT_ON_EXIT}"`; -export const FLAG_DATABASE_EDITION = "--databaseEdition [edition]"; -export const DESC_DATABASE_EDITION = "start emulator in either standard or enterprise edition."; +export const FLAG_EDITION = "--edition [edition]"; +export const DESC_EDITION = "start emulator in either standard or enterprise edition."; export const EXPORT_ON_EXIT_CWD_DANGER = `"${FLAG_EXPORT_ON_EXIT_NAME}" must not point to the current directory or parents. Please choose a new/dedicated directory for exports.`; diff --git a/src/emulator/controller.ts b/src/emulator/controller.ts index f65856ea5d2..8e68afff5fc 100755 --- a/src/emulator/controller.ts +++ b/src/emulator/controller.ts @@ -642,25 +642,25 @@ export async function startAll( const firestoreAddr = legacyGetFirstAddr(Emulators.FIRESTORE); const websocketPort = legacyGetFirstAddr("firestore.websocket").port; - const configEdition = options.config.src.emulators?.firestore?.databaseEdition; - const cliEdition = options.databaseEdition; - const edition = cliEdition !== undefined ? cliEdition : configEdition; + const configEdition = options.config.src.emulators?.firestore?.edition; + const cliEdition = options.edition + + let edition = "standard"; + if (cliEdition !== undefined) { + edition = cliEdition.toLowerCase(); + } else if (configEdition !== undefined) { + edition = configEdition.toLowerCase(); + } const args: FirestoreEmulatorArgs = { host: firestoreAddr.host, port: firestoreAddr.port, websocket_port: websocketPort, - database_edition: edition, + "database-edition": edition, project_id: projectId, auto_download: true, }; - // let edition = "standard"; - // if (configEdition !== undefined) { - // edition = configEdition; - // } - // args.database_edition = edition; - if (exportMetadata.firestore) { utils.assertIsString(options.import); const importDirAbsPath = path.resolve(options.import); @@ -744,7 +744,7 @@ export async function startAll( firestoreLogger.logLabeled( "SUCCESS", Emulators.FIRESTORE, - `Firestore Emulator is running on ${edition} database edition.`, + `Firestore Emulator was started in ${edition} edition.`, ); firestoreLogger.logLabeled( "SUCCESS", diff --git a/src/emulator/downloadableEmulators.ts b/src/emulator/downloadableEmulators.ts index 5029b9e2fb9..6006a59d007 100755 --- a/src/emulator/downloadableEmulators.ts +++ b/src/emulator/downloadableEmulators.ts @@ -244,7 +244,7 @@ const Commands: { [s in DownloadableEmulators]: DownloadableEmulatorCommand } = "host", "rules", "websocket_port", - "database_edition", + "database-edition", "functions_emulator", "seed_from_export", "project_id", diff --git a/src/emulator/firestoreEmulator.ts b/src/emulator/firestoreEmulator.ts index 3907d8a8661..cfd2c5e909a 100644 --- a/src/emulator/firestoreEmulator.ts +++ b/src/emulator/firestoreEmulator.ts @@ -14,7 +14,7 @@ export interface FirestoreEmulatorArgs { port?: number; host?: string; websocket_port?: number; - database_edition?: string; + "database-edition"?: string; project_id?: string; rules?: string; functions_emulator?: string; diff --git a/src/firebaseConfig.ts b/src/firebaseConfig.ts index 0875ae76721..1e03fbc962d 100644 --- a/src/firebaseConfig.ts +++ b/src/firebaseConfig.ts @@ -240,7 +240,7 @@ export type EmulatorsConfig = { host?: string; port?: number; websocketPort?: number; - databaseEdition?: string; + edition?: string; }; functions?: { host?: string; diff --git a/src/options.ts b/src/options.ts index a6c04f3f9e1..c83baf74517 100644 --- a/src/options.ts +++ b/src/options.ts @@ -26,7 +26,7 @@ export interface BaseOptions { // Emulator specific import/export options exportOnExit?: boolean | string; import?: string; - databaseEdition?: string; + edition?: string; isMCP?: boolean; From 83cf13c11e09bc6c62476b0066cc4c673a193afe Mon Sep 17 00:00:00 2001 From: "harshoza24@gmail.com" Date: Tue, 7 Apr 2026 16:46:27 -0500 Subject: [PATCH 04/10] quick linter fix --- src/emulator/controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emulator/controller.ts b/src/emulator/controller.ts index 8e68afff5fc..67b72589c1e 100755 --- a/src/emulator/controller.ts +++ b/src/emulator/controller.ts @@ -643,7 +643,7 @@ export async function startAll( const websocketPort = legacyGetFirstAddr("firestore.websocket").port; const configEdition = options.config.src.emulators?.firestore?.edition; - const cliEdition = options.edition + const cliEdition = options.edition; let edition = "standard"; if (cliEdition !== undefined) { From 5c11fe8a47fbe3dec1b330ec11acc7ebd61bd72a Mon Sep 17 00:00:00 2001 From: "harshoza24@gmail.com" Date: Tue, 7 Apr 2026 16:58:26 -0500 Subject: [PATCH 05/10] update JSON schema --- schema/firebase-config.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/schema/firebase-config.json b/schema/firebase-config.json index 3800ffd19f8..6a79271c791 100644 --- a/schema/firebase-config.json +++ b/schema/firebase-config.json @@ -1412,6 +1412,9 @@ "firestore": { "additionalProperties": false, "properties": { + "edition": { + "type": "string" + }, "host": { "type": "string" }, @@ -1420,9 +1423,6 @@ }, "websocketPort": { "type": "number" - }, - "edition": { - "type": "string" } }, "type": "object" From 540d8e85102e3515eed7394ee7e85ad22682566d Mon Sep 17 00:00:00 2001 From: "harshoza24@gmail.com" Date: Tue, 7 Apr 2026 17:10:30 -0500 Subject: [PATCH 06/10] fixing check on invalid flag input --- src/emulator/controller.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/emulator/controller.ts b/src/emulator/controller.ts index 67b72589c1e..e507656963b 100755 --- a/src/emulator/controller.ts +++ b/src/emulator/controller.ts @@ -642,14 +642,19 @@ export async function startAll( const firestoreAddr = legacyGetFirstAddr(Emulators.FIRESTORE); const websocketPort = legacyGetFirstAddr("firestore.websocket").port; - const configEdition = options.config.src.emulators?.firestore?.edition; - const cliEdition = options.edition; - - let edition = "standard"; - if (cliEdition !== undefined) { - edition = cliEdition.toLowerCase(); - } else if (configEdition !== undefined) { - edition = configEdition.toLowerCase(); + if (options.edition !== undefined) { + utils.assertIsString(options.edition, "edition"); + } + const edition = ( + (options.edition as string) || + options.config.src.emulators?.firestore?.edition || + "standard" + ).toLowerCase(); + if (edition !== "standard" && edition !== "enterprise") { + throw new FirebaseError( + "The Firestore emulator edition must be either 'standard' or 'enterprise'.", + { exit: 1 }, + ); } const args: FirestoreEmulatorArgs = { From b590be447a944724fbca10a5c2d79b6d598e2d8d Mon Sep 17 00:00:00 2001 From: harshyyy21 Date: Tue, 7 Apr 2026 17:14:00 -0500 Subject: [PATCH 07/10] Undo nom.shrinkwrap.json change.. --- npm-shrinkwrap.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index ed11cbe236b..c99f3d609d9 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -29644,7 +29644,7 @@ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "requires": { - "ajv": "^8.0.0" + "ajv": "^8.17.1" } } } From 031b95b52cafb8d021cb9bc7d45a70faa0b14ee9 Mon Sep 17 00:00:00 2001 From: harshyyy21 Date: Tue, 7 Apr 2026 17:16:19 -0500 Subject: [PATCH 08/10] Changed wrong line oops. --- npm-shrinkwrap.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index c99f3d609d9..d93ac9def70 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -26785,7 +26785,7 @@ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "requires": { - "ajv": "^8.0.0" + "ajv": "^8.17.1" } }, "ansi-align": { @@ -29644,7 +29644,7 @@ "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "requires": { - "ajv": "^8.17.1" + "ajv": "^8.0.0" } } } From 23568a557814486c1896ec2ae83f41655adb6359 Mon Sep 17 00:00:00 2001 From: "harshoza24@gmail.com" Date: Wed, 8 Apr 2026 11:54:04 -0500 Subject: [PATCH 09/10] removing manual flag option --- src/commands/emulators-start.ts | 1 - src/emulator/commandUtils.ts | 3 --- src/emulator/controller.ts | 4 ---- src/options.ts | 1 - 4 files changed, 9 deletions(-) diff --git a/src/commands/emulators-start.ts b/src/commands/emulators-start.ts index 48482a14885..6ddc4f3d135 100644 --- a/src/commands/emulators-start.ts +++ b/src/commands/emulators-start.ts @@ -25,7 +25,6 @@ export const command = new Command("emulators:start") .option(commandUtils.FLAG_IMPORT, commandUtils.DESC_IMPORT) .option(commandUtils.FLAG_EXPORT_ON_EXIT, commandUtils.DESC_EXPORT_ON_EXIT) .option(commandUtils.FLAG_VERBOSITY, commandUtils.DESC_VERBOSITY) - .option(commandUtils.FLAG_EDITION, commandUtils.DESC_EDITION) // eslint-disable-next-line @typescript-eslint/no-explicit-any .action((options: Options) => { const killSignalPromise = commandUtils.shutdownWhenKilled(options); diff --git a/src/emulator/commandUtils.ts b/src/emulator/commandUtils.ts index e64800df36d..843ae373d5e 100644 --- a/src/emulator/commandUtils.ts +++ b/src/emulator/commandUtils.ts @@ -46,9 +46,6 @@ export const EXPORT_ON_EXIT_USAGE_ERROR = `"${FLAG_EXPORT_ON_EXIT_NAME}" must be used with "${FLAG_IMPORT}"` + ` or provide a dir directly to "${FLAG_EXPORT_ON_EXIT}"`; -export const FLAG_EDITION = "--edition [edition]"; -export const DESC_EDITION = "start emulator in either standard or enterprise edition."; - export const EXPORT_ON_EXIT_CWD_DANGER = `"${FLAG_EXPORT_ON_EXIT_NAME}" must not point to the current directory or parents. Please choose a new/dedicated directory for exports.`; export const FLAG_VERBOSITY_NAME = "--log-verbosity"; diff --git a/src/emulator/controller.ts b/src/emulator/controller.ts index e507656963b..a1d9f782905 100755 --- a/src/emulator/controller.ts +++ b/src/emulator/controller.ts @@ -642,11 +642,7 @@ export async function startAll( const firestoreAddr = legacyGetFirstAddr(Emulators.FIRESTORE); const websocketPort = legacyGetFirstAddr("firestore.websocket").port; - if (options.edition !== undefined) { - utils.assertIsString(options.edition, "edition"); - } const edition = ( - (options.edition as string) || options.config.src.emulators?.firestore?.edition || "standard" ).toLowerCase(); diff --git a/src/options.ts b/src/options.ts index c83baf74517..c5c973e45ea 100644 --- a/src/options.ts +++ b/src/options.ts @@ -26,7 +26,6 @@ export interface BaseOptions { // Emulator specific import/export options exportOnExit?: boolean | string; import?: string; - edition?: string; isMCP?: boolean; From 32b635b05762ef34043225dccd6a0e714ed56a1b Mon Sep 17 00:00:00 2001 From: "harshoza24@gmail.com" Date: Wed, 8 Apr 2026 12:02:57 -0500 Subject: [PATCH 10/10] ran npm run format --- src/emulator/controller.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/emulator/controller.ts b/src/emulator/controller.ts index a1d9f782905..5e4a6a1bd30 100755 --- a/src/emulator/controller.ts +++ b/src/emulator/controller.ts @@ -642,10 +642,7 @@ export async function startAll( const firestoreAddr = legacyGetFirstAddr(Emulators.FIRESTORE); const websocketPort = legacyGetFirstAddr("firestore.websocket").port; - const edition = ( - options.config.src.emulators?.firestore?.edition || - "standard" - ).toLowerCase(); + const edition = (options.config.src.emulators?.firestore?.edition || "standard").toLowerCase(); if (edition !== "standard" && edition !== "enterprise") { throw new FirebaseError( "The Firestore emulator edition must be either 'standard' or 'enterprise'.",