fix(app): Add more detailed warning for duplicate app error (#10182)

This commit is contained in:
Christina Holland
2026-07-21 15:12:46 -07:00
committed by GitHub
parent cfd27492aa
commit 0feb45343b
4 changed files with 33 additions and 13 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@firebase/app': patch
---
Add more detailed error when `initializeApp()` is called a second time with different options or config, that prints the different options or config.
+5 -5
View File
@@ -102,7 +102,7 @@ describe('API tests', () => {
initializeApp({
apiKey: 'test2'
})
).throws(/\[DEFAULT\].*exists/i);
).throws(/\[DEFAULT\].*exists with different options.*test1.*test2/i);
});
it('throws when creating duplicate named Apps with different options', () => {
@@ -120,7 +120,7 @@ describe('API tests', () => {
},
appName
)
).throws(/'MyApp'.*exists/i);
).throws(/'MyApp'.*exists with different options.*test1.*test2/i);
});
it('throws when creating duplicate DEFAULT Apps with different config values', () => {
@@ -137,7 +137,7 @@ describe('API tests', () => {
},
{ automaticDataCollectionEnabled: true }
)
).throws(/\[DEFAULT\].*exists/i);
).throws(/\[DEFAULT\].*exists with different config.*false.*true/i);
});
it('throws when creating duplicate named Apps with different config values', () => {
@@ -155,7 +155,7 @@ describe('API tests', () => {
},
{ name: appName, automaticDataCollectionEnabled: true }
)
).throws(/'MyApp'.*exists/i);
).throws(/'MyApp'.*exists with different config.*false.*true/i);
});
it('takes an object as the second parameter to create named App', () => {
@@ -479,7 +479,7 @@ describe('API tests', () => {
expect(count).to.equal(0);
count++;
}
} as _FirebaseService),
}) as _FirebaseService,
ComponentType.PUBLIC
);
_registerComponent(comp1);
+15 -6
View File
@@ -171,13 +171,22 @@ export function initializeApp(
const existingApp = _apps.get(name) as FirebaseAppImpl;
if (existingApp) {
// return the existing app if options and config deep equal the ones in the existing app.
if (
deepEqual(options, existingApp.options) &&
deepEqual(config, existingApp.config)
) {
return existingApp;
if (!deepEqual(options, existingApp.options)) {
throw ERROR_FACTORY.create(AppError.DUPLICATE_APP, {
appName: name,
mismatchedParam: 'options',
oldValue: JSON.stringify(existingApp.options),
newValue: JSON.stringify(options)
});
} else if (!deepEqual(config, existingApp.config)) {
throw ERROR_FACTORY.create(AppError.DUPLICATE_APP, {
appName: name,
mismatchedParam: 'config',
oldValue: JSON.stringify(existingApp.config),
newValue: JSON.stringify(config)
});
} else {
throw ERROR_FACTORY.create(AppError.DUPLICATE_APP, { appName: name });
return existingApp;
}
}
+8 -2
View File
@@ -40,7 +40,8 @@ const ERRORS: ErrorMap<AppError> = {
'call initializeApp() first',
[AppError.BAD_APP_NAME]: "Illegal App name: '{$appName}'",
[AppError.DUPLICATE_APP]:
"Firebase App named '{$appName}' already exists with different options or config",
"Firebase App named '{$appName}' already exists with different {$mismatchedParam}." +
" Existing: '{$oldValue}'. New: '{$newValue}'.",
[AppError.APP_DELETED]: "Firebase App named '{$appName}' already deleted",
[AppError.SERVER_APP_DELETED]: 'Firebase Server App has been deleted',
[AppError.NO_OPTIONS]:
@@ -67,7 +68,12 @@ const ERRORS: ErrorMap<AppError> = {
interface ErrorParams {
[AppError.NO_APP]: { appName: string };
[AppError.BAD_APP_NAME]: { appName: string };
[AppError.DUPLICATE_APP]: { appName: string };
[AppError.DUPLICATE_APP]: {
appName: string;
mismatchedParam: string;
oldValue: string;
newValue: string;
};
[AppError.APP_DELETED]: { appName: string };
[AppError.INVALID_APP_ARGUMENT]: { appName: string };
[AppError.IDB_OPEN]: { originalErrorMessage?: string };