Skip to content

Auth explicit initialization #4714

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Apr 6, 2021
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions common/api-review/app-exp.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Name } from '@firebase/component';
import { Provider } from '@firebase/component';

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

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

// @internal (undocumented)
export function _registerComponent(component: Component): boolean;
export function _registerComponent<T extends Name>(component: Component<T>): boolean;

// @public
export function registerVersion(libraryKeyOrName: string, version: string, variant?: string): void;
Expand Down
6 changes: 3 additions & 3 deletions packages-exp/app-compat/src/firebaseNamespaceCore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
} from './types';
import * as modularAPIs from '@firebase/app-exp';
import { _FirebaseAppInternal as _FirebaseAppExp } from '@firebase/app-exp';
import { Component, ComponentType } from '@firebase/component';
import { Component, ComponentType, Name } from '@firebase/component';

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

function registerComponentCompat(
component: Component
function registerComponentCompat<T extends Name>(
component: Component<T>
): FirebaseServiceNamespace<_FirebaseService> | null {
const componentName = component.name;
const componentNameWithoutCompat = componentName.replace('-compat', '');
Expand Down
10 changes: 5 additions & 5 deletions packages-exp/app-compat/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

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

export interface FirebaseServiceInternals {
/**
Expand Down Expand Up @@ -50,8 +50,8 @@ export interface FirebaseServiceNamespace<T extends _FirebaseService> {
// eslint-disable-next-line @typescript-eslint/naming-convention
export interface _FirebaseApp extends FirebaseApp {
container: ComponentContainer;
_addComponent(component: Component): void;
_addOrOverwriteComponent(component: Component): void;
_addComponent<T extends Name>(component: Component<T>): void;
_addOrOverwriteComponent<T extends Name>(component: Component<T>): void;
_removeServiceInstance(name: string, instanceIdentifier?: string): void;
}

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

/**
Expand Down
9 changes: 7 additions & 2 deletions packages-exp/app-exp/src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ export const _components = new Map<string, Component<any>>();
*
* @internal
*/
export function _addComponent(app: FirebaseApp, component: Component): void {
export function _addComponent<T extends Name>(
app: FirebaseApp,
component: Component<T>
): void {
try {
(app as FirebaseAppImpl).container.addComponent(component);
} catch (e) {
Expand Down Expand Up @@ -68,7 +71,9 @@ export function _addOrOverwriteComponent(
*
* @internal
*/
export function _registerComponent(component: Component): boolean {
export function _registerComponent<T extends Name>(
component: Component<T>
): boolean {
const componentName = component.name;
if (_components.has(componentName)) {
logger.debug(
Expand Down
8 changes: 3 additions & 5 deletions packages-exp/app-exp/src/platformLoggerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
Provider,
Name
} from '@firebase/component';
import { PlatformLoggerService } from './types';
import { PlatformLoggerService, VersionService } from './types';

export class PlatformLoggerServiceImpl implements PlatformLoggerService {
constructor(private readonly container: ComponentContainer) {}
Expand All @@ -34,7 +34,7 @@ export class PlatformLoggerServiceImpl implements PlatformLoggerService {
return providers
.map(provider => {
if (isVersionServiceProvider(provider)) {
const service = provider.getImmediate();
const service = provider.getImmediate() as VersionService;
return `${service.library}/${service.version}`;
} else {
return null;
Expand All @@ -52,9 +52,7 @@ export class PlatformLoggerServiceImpl implements PlatformLoggerService {
* provides VersionService. The provider is not necessarily a 'app-version'
* provider.
*/
function isVersionServiceProvider(
provider: Provider<Name>
): provider is Provider<'app-version'> {
function isVersionServiceProvider(provider: Provider<Name>): boolean {
const component = provider.getComponent();
return component?.type === ComponentType.VERSION;
}
25 changes: 23 additions & 2 deletions packages-exp/auth-exp/src/core/auth/register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
*/

import { _registerComponent, registerVersion } from '@firebase/app-exp';
import { Component, ComponentType } from '@firebase/component';
import {
Component,
ComponentType,
InstantiationMode
} from '@firebase/component';

import { version } from '../../../package.json';
import { AuthErrorCode } from '../errors';
Expand Down Expand Up @@ -86,6 +90,23 @@ export function registerAuth(clientPlatform: ClientPlatform): void {
},
ComponentType.PUBLIC
)
/**
* Auth can only be initialized by explicitly calling getAuth() or initializeAuth()
* For why we do this, See go/firebase-next-auth-init
*/
.setInstantiationMode(InstantiationMode.EXPLICIT)
/**
* Because all firebase products that depend on auth depend on auth-internal directly,
* we need to initialize auth-internal after auth is initialized to make it available to other firebase products.
*/
.setInstanceCreatedCallback(
(container, _instanceIdentifier, _instance) => {
const authInternalProvider = container.getProvider(
_ComponentName.AUTH_INTERNAL
);
authInternalProvider.initialize();
}
)
);

_registerComponent(
Expand All @@ -98,7 +119,7 @@ export function registerAuth(clientPlatform: ClientPlatform): void {
return (auth => new AuthInterop(auth))(auth);
},
ComponentType.PRIVATE
)
).setInstantiationMode(InstantiationMode.EXPLICIT)
);

registerVersion(
Expand Down
10 changes: 5 additions & 5 deletions packages/app-types/private.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import { FirebaseApp, FirebaseNamespace } from '@firebase/app-types';
import { Observer, Subscribe } from '@firebase/util';
import { FirebaseError, ErrorFactory } from '@firebase/util';
import { Component, ComponentContainer } from '@firebase/component';
import { Component, ComponentContainer, Name } from '@firebase/component';

export interface FirebaseServiceInternals {
/**
Expand Down Expand Up @@ -86,8 +86,8 @@ export interface FirebaseAppInternals {

export interface _FirebaseApp extends FirebaseApp {
container: ComponentContainer;
_addComponent(component: Component): void;
_addOrOverwriteComponent(component: Component): void;
_addComponent<T extends Name>(component: Component<T>): void;
_addOrOverwriteComponent<T extends Name>(component: Component<T>): void;
_removeServiceInstance(name: string, instanceIdentifier?: string): void;
}
export interface _FirebaseNamespace extends FirebaseNamespace {
Expand All @@ -106,8 +106,8 @@ export interface _FirebaseNamespace extends FirebaseNamespace {
* @param allowMultipleInstances Whether the registered service supports
* multiple instances per app. If not specified, the default is false.
*/
registerComponent(
component: Component
registerComponent<T extends Name>(
component: Component<T>
): FirebaseServiceNamespace<FirebaseService> | null;

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/firebaseApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export class FirebaseAppImpl implements FirebaseApp {
/**
* @param component the component being added to this app's container
*/
_addComponent(component: Component): void {
_addComponent<T extends Name>(component: Component<T>): void {
try {
this.container.addComponent(component);
} catch (e) {
Expand Down
6 changes: 2 additions & 4 deletions packages/app/src/platformLoggerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class PlatformLoggerService {
return providers
.map(provider => {
if (isVersionServiceProvider(provider)) {
const service = provider.getImmediate();
const service = (provider as Provider<'app-version'>).getImmediate();
return `${service.library}/${service.version}`;
} else {
return null;
Expand All @@ -51,9 +51,7 @@ export class PlatformLoggerService {
* provides VersionService. The provider is not necessarily a 'app-version'
* provider.
*/
function isVersionServiceProvider(
provider: Provider<Name>
): provider is Provider<'app-version'> {
function isVersionServiceProvider(provider: Provider<Name>): boolean {
const component = provider.getComponent();
return component?.type === ComponentType.VERSION;
}
10 changes: 9 additions & 1 deletion packages/component/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import {
InstanceFactory,
ComponentType,
Dictionary,
Name
Name,
onInstanceCreatedCallback
} from './types';

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

instantiationMode = InstantiationMode.LAZY;

onInstanceCreated: onInstanceCreatedCallback<T> | null = null;

/**
*
* @param name The public service name, e.g. app, auth, firestore, database
Expand All @@ -60,4 +63,9 @@ export class Component<T extends Name = Name> {
this.serviceProps = props;
return this;
}

setInstanceCreatedCallback(callback: onInstanceCreatedCallback<T>): this {
this.onInstanceCreated = callback;
return this;
}
}
4 changes: 2 additions & 2 deletions packages/component/src/component_container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ export class ComponentContainer {
*/
getProvider<T extends Name>(name: T): Provider<T> {
if (this.providers.has(name)) {
return this.providers.get(name) as Provider<T>;
return (this.providers.get(name) as unknown) as Provider<T>;
}

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

return provider as Provider<T>;
}
Expand Down
Loading