diff --git a/.changeset/thin-bikes-tan.md b/.changeset/thin-bikes-tan.md
new file mode 100644
index 00000000000..121b3208d52
--- /dev/null
+++ b/.changeset/thin-bikes-tan.md
@@ -0,0 +1,6 @@
+---
+'@firebase/app': minor
+'firebase': minor
+---
+
+initializeServerApp now supports auto-initialization for Firebase App Hosting.
diff --git a/common/api-review/app.api.md b/common/api-review/app.api.md
index 4e93f1ae87f..c12089c1520 100644
--- a/common/api-review/app.api.md
+++ b/common/api-review/app.api.md
@@ -110,14 +110,20 @@ export function initializeApp(options: FirebaseOptions, config?: FirebaseAppSett
export function initializeApp(): FirebaseApp;
// @public
-export function initializeServerApp(options: FirebaseOptions | FirebaseApp, config: FirebaseServerAppSettings): FirebaseServerApp;
+export function initializeServerApp(options: FirebaseOptions | FirebaseApp, config?: FirebaseServerAppSettings): FirebaseServerApp;
+
+// @public
+export function initializeServerApp(config?: FirebaseServerAppSettings): FirebaseServerApp;
// @internal (undocumented)
-export function _isFirebaseApp(obj: FirebaseApp | FirebaseOptions): obj is FirebaseApp;
+export function _isFirebaseApp(obj: FirebaseApp | FirebaseOptions | FirebaseAppSettings): obj is FirebaseApp;
// @internal (undocumented)
export function _isFirebaseServerApp(obj: FirebaseApp | FirebaseServerApp | null | undefined): obj is FirebaseServerApp;
+// @internal (undocumented)
+export function _isFirebaseServerAppSettings(obj: FirebaseApp | FirebaseOptions | FirebaseAppSettings): obj is FirebaseServerAppSettings;
+
// @public
export function onLog(logCallback: LogCallback | null, options?: LogOptions): void;
diff --git a/docs-devsite/app.md b/docs-devsite/app.md
index 9c3b322aaaf..0c9b2d03e4b 100644
--- a/docs-devsite/app.md
+++ b/docs-devsite/app.md
@@ -23,6 +23,8 @@ This package coordinates the communication between the different Firebase compon
| function() |
| [getApps()](./app.md#getapps) | A (read-only) array of all initialized apps. |
| [initializeApp()](./app.md#initializeapp) | Creates and initializes a FirebaseApp instance. |
+| function(config, ...) |
+| [initializeServerApp(config)](./app.md#initializeserverapp_e7d0728) | Creates and initializes a [FirebaseServerApp](./app.firebaseserverapp.md#firebaseserverapp_interface) instance. |
| function(libraryKeyOrName, ...) |
| [registerVersion(libraryKeyOrName, version, variant)](./app.md#registerversion_f673248) | Registers a library's name and version for platform logging purposes. |
| function(logCallback, ...) |
@@ -116,6 +118,38 @@ export declare function initializeApp(): FirebaseApp;
[FirebaseApp](./app.firebaseapp.md#firebaseapp_interface)
+## function(config, ...)
+
+### initializeServerApp(config) {:#initializeserverapp_e7d0728}
+
+Creates and initializes a [FirebaseServerApp](./app.firebaseserverapp.md#firebaseserverapp_interface) instance.
+
+Signature:
+
+```typescript
+export declare function initializeServerApp(config?: FirebaseServerAppSettings): FirebaseServerApp;
+```
+
+#### Parameters
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| config | [FirebaseServerAppSettings](./app.firebaseserverappsettings.md#firebaseserverappsettings_interface) | Optional FirebaseServerApp
settings. |
+
+Returns:
+
+[FirebaseServerApp](./app.firebaseserverapp.md#firebaseserverapp_interface)
+
+The initialized `FirebaseServerApp`.
+
+#### Exceptions
+
+If invoked in an unsupported non-server environment such as a browser.
+
+If [FirebaseServerAppSettings.releaseOnDeref](./app.firebaseserverappsettings.md#firebaseserverappsettingsreleaseonderef) is defined but the runtime doesn't provide Finalization Registry support.
+
+If the `FIREBASE_OPTIONS` enviornment variable does not contain a valid project configuration required for auto-initialization.
+
## function(libraryKeyOrName, ...)
### registerVersion(libraryKeyOrName, version, variant) {:#registerversion_f673248}
@@ -260,6 +294,12 @@ export declare function initializeApp(options: FirebaseOptions, name?: string):
The initialized app.
+#### Exceptions
+
+If the optional `name` parameter is malformed or empty.
+
+If a `FirebaseApp` already exists with the same name but with a different configuration.
+
### Example 1
@@ -312,6 +352,12 @@ export declare function initializeApp(options: FirebaseOptions, config?: Firebas
[FirebaseApp](./app.firebaseapp.md#firebaseapp_interface)
+#### Exceptions
+
+If [FirebaseAppSettings.name](./app.firebaseappsettings.md#firebaseappsettingsname) is defined but the value is malformed or empty.
+
+If a `FirebaseApp` already exists with the same name but with a different configuration.
+
### initializeServerApp(options, config) {:#initializeserverapp_30ab697}
Creates and initializes a [FirebaseServerApp](./app.firebaseserverapp.md#firebaseserverapp_interface) instance.
@@ -323,7 +369,7 @@ See [Add Firebase to your app](https://firebase.google.com/docs/web/setup#add_fi
Signature:
```typescript
-export declare function initializeServerApp(options: FirebaseOptions | FirebaseApp, config: FirebaseServerAppSettings): FirebaseServerApp;
+export declare function initializeServerApp(options: FirebaseOptions | FirebaseApp, config?: FirebaseServerAppSettings): FirebaseServerApp;
```
#### Parameters
@@ -331,7 +377,7 @@ export declare function initializeServerApp(options: FirebaseOptions | FirebaseA
| Parameter | Type | Description |
| --- | --- | --- |
| options | [FirebaseOptions](./app.firebaseoptions.md#firebaseoptions_interface) \| [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) | Firebase.AppOptions
to configure the app's services, or a a FirebaseApp
instance which contains the AppOptions
within. |
-| config | [FirebaseServerAppSettings](./app.firebaseserverappsettings.md#firebaseserverappsettings_interface) | FirebaseServerApp
configuration. |
+| config | [FirebaseServerAppSettings](./app.firebaseserverappsettings.md#firebaseserverappsettings_interface) | Optional FirebaseServerApp
settings. |
Returns:
@@ -339,6 +385,12 @@ export declare function initializeServerApp(options: FirebaseOptions | FirebaseA
The initialized `FirebaseServerApp`.
+#### Exceptions
+
+If invoked in an unsupported non-server environment such as a browser.
+
+If [FirebaseServerAppSettings.releaseOnDeref](./app.firebaseserverappsettings.md#firebaseserverappsettingsreleaseonderef) is defined but the runtime doesn't provide Finalization Registry support.
+
### Example
diff --git a/packages/app/src/api.ts b/packages/app/src/api.ts
index 9cba8ec6f50..6fd50060a6a 100644
--- a/packages/app/src/api.ts
+++ b/packages/app/src/api.ts
@@ -37,6 +37,7 @@ import {
_apps,
_components,
_isFirebaseApp,
+ _isFirebaseServerAppSettings,
_registerComponent,
_serverApps
} from './internal';
@@ -106,6 +107,10 @@ export const SDK_VERSION = version;
*
* @returns The initialized app.
*
+ * @throws If the optional `name` parameter is malformed or empty.
+ *
+ * @throws If a `FirebaseApp` already exists with the same name but with a different configuration.
+ *
* @public
*/
export function initializeApp(
@@ -118,6 +123,9 @@ export function initializeApp(
* @param options - Options to configure the app's services.
* @param config - FirebaseApp Configuration
*
+ * @throws If {@link FirebaseAppSettings.name} is defined but the value is malformed or empty.
+ *
+ * @throws If a `FirebaseApp` already exists with the same name but with a different configuration.
* @public
*/
export function initializeApp(
@@ -220,41 +228,75 @@ export function initializeApp(
*
* @param options - `Firebase.AppOptions` to configure the app's services, or a
* a `FirebaseApp` instance which contains the `AppOptions` within.
- * @param config - `FirebaseServerApp` configuration.
+ * @param config - Optional `FirebaseServerApp` settings.
*
* @returns The initialized `FirebaseServerApp`.
*
+ * @throws If invoked in an unsupported non-server environment such as a browser.
+ *
+ * @throws If {@link FirebaseServerAppSettings.releaseOnDeref} is defined but the runtime doesn't
+ * provide Finalization Registry support.
+ *
* @public
*/
export function initializeServerApp(
options: FirebaseOptions | FirebaseApp,
- config: FirebaseServerAppSettings
+ config?: FirebaseServerAppSettings
): FirebaseServerApp;
+/**
+ * Creates and initializes a {@link @firebase/app#FirebaseServerApp} instance.
+ *
+ * @param config - Optional `FirebaseServerApp` settings.
+ *
+ * @returns The initialized `FirebaseServerApp`.
+ *
+ * @throws If invoked in an unsupported non-server environment such as a browser.
+ * @throws If {@link FirebaseServerAppSettings.releaseOnDeref} is defined but the runtime doesn't
+ * provide Finalization Registry support.
+ * @throws If the `FIREBASE_OPTIONS` enviornment variable does not contain a valid project
+ * configuration required for auto-initialization.
+ *
+ * @public
+ */
export function initializeServerApp(
- _options: FirebaseOptions | FirebaseApp,
- _serverAppConfig: FirebaseServerAppSettings
+ config?: FirebaseServerAppSettings
+): FirebaseServerApp;
+export function initializeServerApp(
+ _options?: FirebaseApp | FirebaseServerAppSettings | FirebaseOptions,
+ _serverAppConfig: FirebaseServerAppSettings = {}
): FirebaseServerApp {
if (isBrowser() && !isWebWorker()) {
// FirebaseServerApp isn't designed to be run in browsers.
throw ERROR_FACTORY.create(AppError.INVALID_SERVER_APP_ENVIRONMENT);
}
- if (_serverAppConfig.automaticDataCollectionEnabled === undefined) {
- _serverAppConfig.automaticDataCollectionEnabled = true;
+ let firebaseOptions: FirebaseOptions | undefined;
+ let serverAppSettings: FirebaseServerAppSettings = _serverAppConfig || {};
+
+ if (_options) {
+ if (_isFirebaseApp(_options)) {
+ firebaseOptions = _options.options;
+ } else if (_isFirebaseServerAppSettings(_options)) {
+ serverAppSettings = _options;
+ } else {
+ firebaseOptions = _options;
+ }
}
- let appOptions: FirebaseOptions;
- if (_isFirebaseApp(_options)) {
- appOptions = _options.options;
- } else {
- appOptions = _options;
+ if (serverAppSettings.automaticDataCollectionEnabled === undefined) {
+ serverAppSettings.automaticDataCollectionEnabled = true;
+ }
+
+ firebaseOptions ||= getDefaultAppConfig();
+ if (!firebaseOptions) {
+ throw ERROR_FACTORY.create(AppError.NO_OPTIONS);
}
// Build an app name based on a hash of the configuration options.
const nameObj = {
- ..._serverAppConfig,
- ...appOptions
+ ...serverAppSettings,
+ ...firebaseOptions
};
// However, Do not mangle the name based on releaseOnDeref, since it will vary between the
@@ -270,7 +312,7 @@ export function initializeServerApp(
);
};
- if (_serverAppConfig.releaseOnDeref !== undefined) {
+ if (serverAppSettings.releaseOnDeref !== undefined) {
if (typeof FinalizationRegistry === 'undefined') {
throw ERROR_FACTORY.create(
AppError.FINALIZATION_REGISTRY_NOT_SUPPORTED,
@@ -283,7 +325,7 @@ export function initializeServerApp(
const existingApp = _serverApps.get(nameString) as FirebaseServerApp;
if (existingApp) {
(existingApp as FirebaseServerAppImpl).incRefCount(
- _serverAppConfig.releaseOnDeref
+ serverAppSettings.releaseOnDeref
);
return existingApp;
}
@@ -294,8 +336,8 @@ export function initializeServerApp(
}
const newApp = new FirebaseServerAppImpl(
- appOptions,
- _serverAppConfig,
+ firebaseOptions,
+ serverAppSettings,
nameString,
container
);
diff --git a/packages/app/src/internal.ts b/packages/app/src/internal.ts
index cbcdcb26501..422c941aba3 100644
--- a/packages/app/src/internal.ts
+++ b/packages/app/src/internal.ts
@@ -17,6 +17,8 @@
import {
FirebaseApp,
+ FirebaseAppSettings,
+ FirebaseServerAppSettings,
FirebaseOptions,
FirebaseServerApp
} from './public-types';
@@ -147,18 +149,40 @@ export function _removeServiceInstance(
/**
*
- * @param obj - an object of type FirebaseApp or FirebaseOptions.
+ * @param obj - an object of type FirebaseApp, FirebaseOptions or FirebaseAppSettings.
*
* @returns true if the provide object is of type FirebaseApp.
*
* @internal
*/
export function _isFirebaseApp(
- obj: FirebaseApp | FirebaseOptions
+ obj: FirebaseApp | FirebaseOptions | FirebaseAppSettings
): obj is FirebaseApp {
return (obj as FirebaseApp).options !== undefined;
}
+/**
+ *
+ * @param obj - an object of type FirebaseApp, FirebaseOptions or FirebaseAppSettings.
+ *
+ * @returns true if the provided object is of type FirebaseServerAppImpl.
+ *
+ * @internal
+ */
+export function _isFirebaseServerAppSettings(
+ obj: FirebaseApp | FirebaseOptions | FirebaseAppSettings
+): obj is FirebaseServerAppSettings {
+ if (_isFirebaseApp(obj)) {
+ return false;
+ }
+ return (
+ 'authIdToken' in obj ||
+ 'appCheckToken' in obj ||
+ 'releaseOnDeref' in obj ||
+ 'automaticDataCollectionEnabled' in obj
+ );
+}
+
/**
*
* @param obj - an object of type FirebaseApp.