Skip to content

Commit f24d896

Browse files
Feiyang1yuchenshi
andauthored
Auth explicit initialization (#4714)
* Add explicit instantation mode * implement auth explicit initialization * Update packages/component/src/types.ts Co-authored-by: Yuchen Shi <[email protected]> * address comments * fix typeing error * fix typings * fix typings * fix typings * Create chatty-cooks-drop.md * Create stale-zebras-hug.md Co-authored-by: Yuchen Shi <[email protected]>
1 parent 318d9bf commit f24d896

File tree

17 files changed

+232
-77
lines changed

17 files changed

+232
-77
lines changed

.changeset/chatty-cooks-drop.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@firebase/component": minor
3+
---
4+
5+
Support new instantiation mode `EXPLICIT`

.changeset/stale-zebras-hug.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"@firebase/app-types": patch
3+
"@firebase/app": patch
4+
"@firebase/rules-unit-testing": patch
5+
---
6+
7+
Internal typing changes

common/api-review/app-exp.api.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { Name } from '@firebase/component';
1313
import { Provider } from '@firebase/component';
1414

1515
// @internal (undocumented)
16-
export function _addComponent(app: FirebaseApp, component: Component): void;
16+
export function _addComponent<T extends Name>(app: FirebaseApp, component: Component<T>): void;
1717

1818
// @internal (undocumented)
1919
export function _addOrOverwriteComponent(app: FirebaseApp, component: Component): void;
@@ -102,7 +102,7 @@ export function initializeApp(options: FirebaseOptions, config?: FirebaseAppConf
102102
export function onLog(logCallback: LogCallback | null, options?: LogOptions): void;
103103

104104
// @internal (undocumented)
105-
export function _registerComponent(component: Component): boolean;
105+
export function _registerComponent<T extends Name>(component: Component<T>): boolean;
106106

107107
// @public
108108
export function registerVersion(libraryKeyOrName: string, version: string, variant?: string): void;

packages-exp/app-compat/src/firebaseNamespaceCore.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
} from './types';
2424
import * as modularAPIs from '@firebase/app-exp';
2525
import { _FirebaseAppInternal as _FirebaseAppExp } from '@firebase/app-exp';
26-
import { Component, ComponentType } from '@firebase/component';
26+
import { Component, ComponentType, Name } from '@firebase/component';
2727

2828
import { deepExtend, contains } from '@firebase/util';
2929
import { FirebaseAppImpl } from './firebaseApp';
@@ -131,8 +131,8 @@ export function createFirebaseNamespaceCore(
131131
return Object.keys(apps).map(name => apps[name]);
132132
}
133133

134-
function registerComponentCompat(
135-
component: Component
134+
function registerComponentCompat<T extends Name>(
135+
component: Component<T>
136136
): FirebaseServiceNamespace<_FirebaseService> | null {
137137
const componentName = component.name;
138138
const componentNameWithoutCompat = componentName.replace('-compat', '');

packages-exp/app-compat/src/types.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
import { FirebaseApp, FirebaseNamespace } from './public-types';
2424
import { Compat } from '@firebase/util';
25-
import { Component, ComponentContainer } from '@firebase/component';
25+
import { Component, ComponentContainer, Name } from '@firebase/component';
2626

2727
export interface FirebaseServiceInternals {
2828
/**
@@ -50,8 +50,8 @@ export interface FirebaseServiceNamespace<T extends _FirebaseService> {
5050
// eslint-disable-next-line @typescript-eslint/naming-convention
5151
export interface _FirebaseApp extends FirebaseApp {
5252
container: ComponentContainer;
53-
_addComponent(component: Component): void;
54-
_addOrOverwriteComponent(component: Component): void;
53+
_addComponent<T extends Name>(component: Component<T>): void;
54+
_addOrOverwriteComponent<T extends Name>(component: Component<T>): void;
5555
_removeServiceInstance(name: string, instanceIdentifier?: string): void;
5656
}
5757

@@ -72,8 +72,8 @@ export interface _FirebaseNamespace extends FirebaseNamespace {
7272
* @param allowMultipleInstances Whether the registered service supports
7373
* multiple instances per app. If not specified, the default is false.
7474
*/
75-
registerComponent(
76-
component: Component
75+
registerComponent<T extends Name>(
76+
component: Component<T>
7777
): FirebaseServiceNamespace<_FirebaseService> | null;
7878

7979
/**

packages-exp/app-exp/src/internal.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ export const _components = new Map<string, Component<any>>();
3939
*
4040
* @internal
4141
*/
42-
export function _addComponent(app: FirebaseApp, component: Component): void {
42+
export function _addComponent<T extends Name>(
43+
app: FirebaseApp,
44+
component: Component<T>
45+
): void {
4346
try {
4447
(app as FirebaseAppImpl).container.addComponent(component);
4548
} catch (e) {
@@ -68,7 +71,9 @@ export function _addOrOverwriteComponent(
6871
*
6972
* @internal
7073
*/
71-
export function _registerComponent(component: Component): boolean {
74+
export function _registerComponent<T extends Name>(
75+
component: Component<T>
76+
): boolean {
7277
const componentName = component.name;
7378
if (_components.has(componentName)) {
7479
logger.debug(

packages-exp/app-exp/src/platformLoggerService.ts

+3-5
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
Provider,
2222
Name
2323
} from '@firebase/component';
24-
import { PlatformLoggerService } from './types';
24+
import { PlatformLoggerService, VersionService } from './types';
2525

2626
export class PlatformLoggerServiceImpl implements PlatformLoggerService {
2727
constructor(private readonly container: ComponentContainer) {}
@@ -34,7 +34,7 @@ export class PlatformLoggerServiceImpl implements PlatformLoggerService {
3434
return providers
3535
.map(provider => {
3636
if (isVersionServiceProvider(provider)) {
37-
const service = provider.getImmediate();
37+
const service = provider.getImmediate() as VersionService;
3838
return `${service.library}/${service.version}`;
3939
} else {
4040
return null;
@@ -52,9 +52,7 @@ export class PlatformLoggerServiceImpl implements PlatformLoggerService {
5252
* provides VersionService. The provider is not necessarily a 'app-version'
5353
* provider.
5454
*/
55-
function isVersionServiceProvider(
56-
provider: Provider<Name>
57-
): provider is Provider<'app-version'> {
55+
function isVersionServiceProvider(provider: Provider<Name>): boolean {
5856
const component = provider.getComponent();
5957
return component?.type === ComponentType.VERSION;
6058
}

packages-exp/auth-exp/src/core/auth/register.ts

+23-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@
1616
*/
1717

1818
import { _registerComponent, registerVersion } from '@firebase/app-exp';
19-
import { Component, ComponentType } from '@firebase/component';
19+
import {
20+
Component,
21+
ComponentType,
22+
InstantiationMode
23+
} from '@firebase/component';
2024

2125
import { version } from '../../../package.json';
2226
import { AuthErrorCode } from '../errors';
@@ -86,6 +90,23 @@ export function registerAuth(clientPlatform: ClientPlatform): void {
8690
},
8791
ComponentType.PUBLIC
8892
)
93+
/**
94+
* Auth can only be initialized by explicitly calling getAuth() or initializeAuth()
95+
* For why we do this, See go/firebase-next-auth-init
96+
*/
97+
.setInstantiationMode(InstantiationMode.EXPLICIT)
98+
/**
99+
* Because all firebase products that depend on auth depend on auth-internal directly,
100+
* we need to initialize auth-internal after auth is initialized to make it available to other firebase products.
101+
*/
102+
.setInstanceCreatedCallback(
103+
(container, _instanceIdentifier, _instance) => {
104+
const authInternalProvider = container.getProvider(
105+
_ComponentName.AUTH_INTERNAL
106+
);
107+
authInternalProvider.initialize();
108+
}
109+
)
89110
);
90111

91112
_registerComponent(
@@ -98,7 +119,7 @@ export function registerAuth(clientPlatform: ClientPlatform): void {
98119
return (auth => new AuthInterop(auth))(auth);
99120
},
100121
ComponentType.PRIVATE
101-
)
122+
).setInstantiationMode(InstantiationMode.EXPLICIT)
102123
);
103124

104125
registerVersion(

packages/app-types/private.d.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import { FirebaseApp, FirebaseNamespace } from '@firebase/app-types';
2424
import { Observer, Subscribe } from '@firebase/util';
2525
import { FirebaseError, ErrorFactory } from '@firebase/util';
26-
import { Component, ComponentContainer } from '@firebase/component';
26+
import { Component, ComponentContainer, Name } from '@firebase/component';
2727

2828
export interface FirebaseServiceInternals {
2929
/**
@@ -86,8 +86,8 @@ export interface FirebaseAppInternals {
8686

8787
export interface _FirebaseApp extends FirebaseApp {
8888
container: ComponentContainer;
89-
_addComponent(component: Component): void;
90-
_addOrOverwriteComponent(component: Component): void;
89+
_addComponent<T extends Name>(component: Component<T>): void;
90+
_addOrOverwriteComponent<T extends Name>(component: Component<T>): void;
9191
_removeServiceInstance(name: string, instanceIdentifier?: string): void;
9292
}
9393
export interface _FirebaseNamespace extends FirebaseNamespace {
@@ -106,8 +106,8 @@ export interface _FirebaseNamespace extends FirebaseNamespace {
106106
* @param allowMultipleInstances Whether the registered service supports
107107
* multiple instances per app. If not specified, the default is false.
108108
*/
109-
registerComponent(
110-
component: Component
109+
registerComponent<T extends Name>(
110+
component: Component<T>
111111
): FirebaseServiceNamespace<FirebaseService> | null;
112112

113113
/**

packages/app/src/firebaseApp.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ export class FirebaseAppImpl implements FirebaseApp {
148148
/**
149149
* @param component the component being added to this app's container
150150
*/
151-
_addComponent(component: Component): void {
151+
_addComponent<T extends Name>(component: Component<T>): void {
152152
try {
153153
this.container.addComponent(component);
154154
} catch (e) {

packages/app/src/platformLoggerService.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export class PlatformLoggerService {
3333
return providers
3434
.map(provider => {
3535
if (isVersionServiceProvider(provider)) {
36-
const service = provider.getImmediate();
36+
const service = (provider as Provider<'app-version'>).getImmediate();
3737
return `${service.library}/${service.version}`;
3838
} else {
3939
return null;
@@ -51,9 +51,7 @@ export class PlatformLoggerService {
5151
* provides VersionService. The provider is not necessarily a 'app-version'
5252
* provider.
5353
*/
54-
function isVersionServiceProvider(
55-
provider: Provider<Name>
56-
): provider is Provider<'app-version'> {
54+
function isVersionServiceProvider(provider: Provider<Name>): boolean {
5755
const component = provider.getComponent();
5856
return component?.type === ComponentType.VERSION;
5957
}

packages/component/src/component.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import {
1919
InstanceFactory,
2020
ComponentType,
2121
Dictionary,
22-
Name
22+
Name,
23+
onInstanceCreatedCallback
2324
} from './types';
2425

2526
/**
@@ -34,6 +35,8 @@ export class Component<T extends Name = Name> {
3435

3536
instantiationMode = InstantiationMode.LAZY;
3637

38+
onInstanceCreated: onInstanceCreatedCallback<T> | null = null;
39+
3740
/**
3841
*
3942
* @param name The public service name, e.g. app, auth, firestore, database
@@ -60,4 +63,9 @@ export class Component<T extends Name = Name> {
6063
this.serviceProps = props;
6164
return this;
6265
}
66+
67+
setInstanceCreatedCallback(callback: onInstanceCreatedCallback<T>): this {
68+
this.onInstanceCreated = callback;
69+
return this;
70+
}
6371
}

packages/component/src/component_container.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ export class ComponentContainer {
6666
*/
6767
getProvider<T extends Name>(name: T): Provider<T> {
6868
if (this.providers.has(name)) {
69-
return this.providers.get(name) as Provider<T>;
69+
return (this.providers.get(name) as unknown) as Provider<T>;
7070
}
7171

7272
// create a Provider for a service that hasn't registered with Firebase
7373
const provider = new Provider<T>(name, this);
74-
this.providers.set(name, provider);
74+
this.providers.set(name, (provider as unknown) as Provider<Name>);
7575

7676
return provider as Provider<T>;
7777
}

0 commit comments

Comments
 (0)