Skip to content

Commit d91169f

Browse files
authored
(feat) initializeServerApp support for App Hosting auto init (#9151)
Implement Auto Init for `initializeServerApp`. Auto init was previously implemented for `initializeApp` in #8483. This PR adds the same functionality to the `initializeServerApp` API surface. Fixes #8863
1 parent 2d72099 commit d91169f

File tree

5 files changed

+153
-23
lines changed

5 files changed

+153
-23
lines changed

.changeset/thin-bikes-tan.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@firebase/app': minor
3+
'firebase': minor
4+
---
5+
6+
initializeServerApp now supports auto-initialization for Firebase App Hosting.

common/api-review/app.api.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,20 @@ export function initializeApp(options: FirebaseOptions, config?: FirebaseAppSett
110110
export function initializeApp(): FirebaseApp;
111111

112112
// @public
113-
export function initializeServerApp(options: FirebaseOptions | FirebaseApp, config: FirebaseServerAppSettings): FirebaseServerApp;
113+
export function initializeServerApp(options: FirebaseOptions | FirebaseApp, config?: FirebaseServerAppSettings): FirebaseServerApp;
114+
115+
// @public
116+
export function initializeServerApp(config?: FirebaseServerAppSettings): FirebaseServerApp;
114117

115118
// @internal (undocumented)
116-
export function _isFirebaseApp(obj: FirebaseApp | FirebaseOptions): obj is FirebaseApp;
119+
export function _isFirebaseApp(obj: FirebaseApp | FirebaseOptions | FirebaseAppSettings): obj is FirebaseApp;
117120

118121
// @internal (undocumented)
119122
export function _isFirebaseServerApp(obj: FirebaseApp | FirebaseServerApp | null | undefined): obj is FirebaseServerApp;
120123

124+
// @internal (undocumented)
125+
export function _isFirebaseServerAppSettings(obj: FirebaseApp | FirebaseOptions | FirebaseAppSettings): obj is FirebaseServerAppSettings;
126+
121127
// @public
122128
export function onLog(logCallback: LogCallback | null, options?: LogOptions): void;
123129

docs-devsite/app.md

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ This package coordinates the communication between the different Firebase compon
2323
| <b>function()</b> |
2424
| [getApps()](./app.md#getapps) | A (read-only) array of all initialized apps. |
2525
| [initializeApp()](./app.md#initializeapp) | Creates and initializes a FirebaseApp instance. |
26+
| <b>function(config, ...)</b> |
27+
| [initializeServerApp(config)](./app.md#initializeserverapp_e7d0728) | Creates and initializes a [FirebaseServerApp](./app.firebaseserverapp.md#firebaseserverapp_interface) instance. |
2628
| <b>function(libraryKeyOrName, ...)</b> |
2729
| [registerVersion(libraryKeyOrName, version, variant)](./app.md#registerversion_f673248) | Registers a library's name and version for platform logging purposes. |
2830
| <b>function(logCallback, ...)</b> |
@@ -116,6 +118,38 @@ export declare function initializeApp(): FirebaseApp;
116118

117119
[FirebaseApp](./app.firebaseapp.md#firebaseapp_interface)
118120

121+
## function(config, ...)
122+
123+
### initializeServerApp(config) {:#initializeserverapp_e7d0728}
124+
125+
Creates and initializes a [FirebaseServerApp](./app.firebaseserverapp.md#firebaseserverapp_interface) instance.
126+
127+
<b>Signature:</b>
128+
129+
```typescript
130+
export declare function initializeServerApp(config?: FirebaseServerAppSettings): FirebaseServerApp;
131+
```
132+
133+
#### Parameters
134+
135+
| Parameter | Type | Description |
136+
| --- | --- | --- |
137+
| config | [FirebaseServerAppSettings](./app.firebaseserverappsettings.md#firebaseserverappsettings_interface) | Optional <code>FirebaseServerApp</code> settings. |
138+
139+
<b>Returns:</b>
140+
141+
[FirebaseServerApp](./app.firebaseserverapp.md#firebaseserverapp_interface)
142+
143+
The initialized `FirebaseServerApp`<!-- -->.
144+
145+
#### Exceptions
146+
147+
If invoked in an unsupported non-server environment such as a browser.
148+
149+
If [FirebaseServerAppSettings.releaseOnDeref](./app.firebaseserverappsettings.md#firebaseserverappsettingsreleaseonderef) is defined but the runtime doesn't provide Finalization Registry support.
150+
151+
If the `FIREBASE_OPTIONS` enviornment variable does not contain a valid project configuration required for auto-initialization.
152+
119153
## function(libraryKeyOrName, ...)
120154

121155
### registerVersion(libraryKeyOrName, version, variant) {:#registerversion_f673248}
@@ -260,6 +294,12 @@ export declare function initializeApp(options: FirebaseOptions, name?: string):
260294

261295
The initialized app.
262296

297+
#### Exceptions
298+
299+
If the optional `name` parameter is malformed or empty.
300+
301+
If a `FirebaseApp` already exists with the same name but with a different configuration.
302+
263303
### Example 1
264304

265305

@@ -312,6 +352,12 @@ export declare function initializeApp(options: FirebaseOptions, config?: Firebas
312352

313353
[FirebaseApp](./app.firebaseapp.md#firebaseapp_interface)
314354

355+
#### Exceptions
356+
357+
If [FirebaseAppSettings.name](./app.firebaseappsettings.md#firebaseappsettingsname) is defined but the value is malformed or empty.
358+
359+
If a `FirebaseApp` already exists with the same name but with a different configuration.
360+
315361
### initializeServerApp(options, config) {:#initializeserverapp_30ab697}
316362

317363
Creates and initializes a [FirebaseServerApp](./app.firebaseserverapp.md#firebaseserverapp_interface) instance.
@@ -323,22 +369,28 @@ See [Add Firebase to your app](https://firebase.google.com/docs/web/setup#add_fi
323369
<b>Signature:</b>
324370

325371
```typescript
326-
export declare function initializeServerApp(options: FirebaseOptions | FirebaseApp, config: FirebaseServerAppSettings): FirebaseServerApp;
372+
export declare function initializeServerApp(options: FirebaseOptions | FirebaseApp, config?: FirebaseServerAppSettings): FirebaseServerApp;
327373
```
328374

329375
#### Parameters
330376

331377
| Parameter | Type | Description |
332378
| --- | --- | --- |
333379
| options | [FirebaseOptions](./app.firebaseoptions.md#firebaseoptions_interface) \| [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) | <code>Firebase.AppOptions</code> to configure the app's services, or a a <code>FirebaseApp</code> instance which contains the <code>AppOptions</code> within. |
334-
| config | [FirebaseServerAppSettings](./app.firebaseserverappsettings.md#firebaseserverappsettings_interface) | <code>FirebaseServerApp</code> configuration. |
380+
| config | [FirebaseServerAppSettings](./app.firebaseserverappsettings.md#firebaseserverappsettings_interface) | Optional <code>FirebaseServerApp</code> settings. |
335381

336382
<b>Returns:</b>
337383

338384
[FirebaseServerApp](./app.firebaseserverapp.md#firebaseserverapp_interface)
339385

340386
The initialized `FirebaseServerApp`<!-- -->.
341387

388+
#### Exceptions
389+
390+
If invoked in an unsupported non-server environment such as a browser.
391+
392+
If [FirebaseServerAppSettings.releaseOnDeref](./app.firebaseserverappsettings.md#firebaseserverappsettingsreleaseonderef) is defined but the runtime doesn't provide Finalization Registry support.
393+
342394
### Example
343395

344396

packages/app/src/api.ts

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
_apps,
3838
_components,
3939
_isFirebaseApp,
40+
_isFirebaseServerAppSettings,
4041
_registerComponent,
4142
_serverApps
4243
} from './internal';
@@ -106,6 +107,10 @@ export const SDK_VERSION = version;
106107
*
107108
* @returns The initialized app.
108109
*
110+
* @throws If the optional `name` parameter is malformed or empty.
111+
*
112+
* @throws If a `FirebaseApp` already exists with the same name but with a different configuration.
113+
*
109114
* @public
110115
*/
111116
export function initializeApp(
@@ -118,6 +123,9 @@ export function initializeApp(
118123
* @param options - Options to configure the app's services.
119124
* @param config - FirebaseApp Configuration
120125
*
126+
* @throws If {@link FirebaseAppSettings.name} is defined but the value is malformed or empty.
127+
*
128+
* @throws If a `FirebaseApp` already exists with the same name but with a different configuration.
121129
* @public
122130
*/
123131
export function initializeApp(
@@ -220,41 +228,75 @@ export function initializeApp(
220228
*
221229
* @param options - `Firebase.AppOptions` to configure the app's services, or a
222230
* a `FirebaseApp` instance which contains the `AppOptions` within.
223-
* @param config - `FirebaseServerApp` configuration.
231+
* @param config - Optional `FirebaseServerApp` settings.
224232
*
225233
* @returns The initialized `FirebaseServerApp`.
226234
*
235+
* @throws If invoked in an unsupported non-server environment such as a browser.
236+
*
237+
* @throws If {@link FirebaseServerAppSettings.releaseOnDeref} is defined but the runtime doesn't
238+
* provide Finalization Registry support.
239+
*
227240
* @public
228241
*/
229242
export function initializeServerApp(
230243
options: FirebaseOptions | FirebaseApp,
231-
config: FirebaseServerAppSettings
244+
config?: FirebaseServerAppSettings
232245
): FirebaseServerApp;
233246

247+
/**
248+
* Creates and initializes a {@link @firebase/app#FirebaseServerApp} instance.
249+
*
250+
* @param config - Optional `FirebaseServerApp` settings.
251+
*
252+
* @returns The initialized `FirebaseServerApp`.
253+
*
254+
* @throws If invoked in an unsupported non-server environment such as a browser.
255+
* @throws If {@link FirebaseServerAppSettings.releaseOnDeref} is defined but the runtime doesn't
256+
* provide Finalization Registry support.
257+
* @throws If the `FIREBASE_OPTIONS` enviornment variable does not contain a valid project
258+
* configuration required for auto-initialization.
259+
*
260+
* @public
261+
*/
234262
export function initializeServerApp(
235-
_options: FirebaseOptions | FirebaseApp,
236-
_serverAppConfig: FirebaseServerAppSettings
263+
config?: FirebaseServerAppSettings
264+
): FirebaseServerApp;
265+
export function initializeServerApp(
266+
_options?: FirebaseApp | FirebaseServerAppSettings | FirebaseOptions,
267+
_serverAppConfig: FirebaseServerAppSettings = {}
237268
): FirebaseServerApp {
238269
if (isBrowser() && !isWebWorker()) {
239270
// FirebaseServerApp isn't designed to be run in browsers.
240271
throw ERROR_FACTORY.create(AppError.INVALID_SERVER_APP_ENVIRONMENT);
241272
}
242273

243-
if (_serverAppConfig.automaticDataCollectionEnabled === undefined) {
244-
_serverAppConfig.automaticDataCollectionEnabled = true;
274+
let firebaseOptions: FirebaseOptions | undefined;
275+
let serverAppSettings: FirebaseServerAppSettings = _serverAppConfig || {};
276+
277+
if (_options) {
278+
if (_isFirebaseApp(_options)) {
279+
firebaseOptions = _options.options;
280+
} else if (_isFirebaseServerAppSettings(_options)) {
281+
serverAppSettings = _options;
282+
} else {
283+
firebaseOptions = _options;
284+
}
245285
}
246286

247-
let appOptions: FirebaseOptions;
248-
if (_isFirebaseApp(_options)) {
249-
appOptions = _options.options;
250-
} else {
251-
appOptions = _options;
287+
if (serverAppSettings.automaticDataCollectionEnabled === undefined) {
288+
serverAppSettings.automaticDataCollectionEnabled = true;
289+
}
290+
291+
firebaseOptions ||= getDefaultAppConfig();
292+
if (!firebaseOptions) {
293+
throw ERROR_FACTORY.create(AppError.NO_OPTIONS);
252294
}
253295

254296
// Build an app name based on a hash of the configuration options.
255297
const nameObj = {
256-
..._serverAppConfig,
257-
...appOptions
298+
...serverAppSettings,
299+
...firebaseOptions
258300
};
259301

260302
// However, Do not mangle the name based on releaseOnDeref, since it will vary between the
@@ -270,7 +312,7 @@ export function initializeServerApp(
270312
);
271313
};
272314

273-
if (_serverAppConfig.releaseOnDeref !== undefined) {
315+
if (serverAppSettings.releaseOnDeref !== undefined) {
274316
if (typeof FinalizationRegistry === 'undefined') {
275317
throw ERROR_FACTORY.create(
276318
AppError.FINALIZATION_REGISTRY_NOT_SUPPORTED,
@@ -283,7 +325,7 @@ export function initializeServerApp(
283325
const existingApp = _serverApps.get(nameString) as FirebaseServerApp;
284326
if (existingApp) {
285327
(existingApp as FirebaseServerAppImpl).incRefCount(
286-
_serverAppConfig.releaseOnDeref
328+
serverAppSettings.releaseOnDeref
287329
);
288330
return existingApp;
289331
}
@@ -294,8 +336,8 @@ export function initializeServerApp(
294336
}
295337

296338
const newApp = new FirebaseServerAppImpl(
297-
appOptions,
298-
_serverAppConfig,
339+
firebaseOptions,
340+
serverAppSettings,
299341
nameString,
300342
container
301343
);

packages/app/src/internal.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
import {
1919
FirebaseApp,
20+
FirebaseAppSettings,
21+
FirebaseServerAppSettings,
2022
FirebaseOptions,
2123
FirebaseServerApp
2224
} from './public-types';
@@ -147,18 +149,40 @@ export function _removeServiceInstance<T extends Name>(
147149

148150
/**
149151
*
150-
* @param obj - an object of type FirebaseApp or FirebaseOptions.
152+
* @param obj - an object of type FirebaseApp, FirebaseOptions or FirebaseAppSettings.
151153
*
152154
* @returns true if the provide object is of type FirebaseApp.
153155
*
154156
* @internal
155157
*/
156158
export function _isFirebaseApp(
157-
obj: FirebaseApp | FirebaseOptions
159+
obj: FirebaseApp | FirebaseOptions | FirebaseAppSettings
158160
): obj is FirebaseApp {
159161
return (obj as FirebaseApp).options !== undefined;
160162
}
161163

164+
/**
165+
*
166+
* @param obj - an object of type FirebaseApp, FirebaseOptions or FirebaseAppSettings.
167+
*
168+
* @returns true if the provided object is of type FirebaseServerAppImpl.
169+
*
170+
* @internal
171+
*/
172+
export function _isFirebaseServerAppSettings(
173+
obj: FirebaseApp | FirebaseOptions | FirebaseAppSettings
174+
): obj is FirebaseServerAppSettings {
175+
if (_isFirebaseApp(obj)) {
176+
return false;
177+
}
178+
return (
179+
'authIdToken' in obj ||
180+
'appCheckToken' in obj ||
181+
'releaseOnDeref' in obj ||
182+
'automaticDataCollectionEnabled' in obj
183+
);
184+
}
185+
162186
/**
163187
*
164188
* @param obj - an object of type FirebaseApp.

0 commit comments

Comments
 (0)