Skip to content

Commit 1d86793

Browse files
committed
Implement lightweight FirebaseApp (#109)
* Implement lightweight firebase app Add firebaseApp Lite add tests for firebaseApp Lite add firebaseApp lite entry point [AUTOMATED]: Prettier Code Styling [AUTOMATED]: License Headers * share code between regular firebaseNamespace and the lite version * [AUTOMATED]: Prettier Code Styling * [AUTOMATED]: License Headers * check self for existing firebase instance * [AUTOMATED]: Prettier Code Styling * remove unused code * update to use a shorter message * [AUTOMATED]: Prettier Code Styling * update warning message * [AUTOMATED]: Prettier Code Styling * update warning message * resolve mertcan's comments * [AUTOMATED]: Prettier Code Styling * use readonly * use _ as suffix * address code style issues * add a build target for app lite * [AUTOMATED]: Prettier Code Styling * add readonly attribute * use const * use String to coerce to string type * remove unnecessary assertion * misc style fixes * [AUTOMATED]: Prettier Code Styling * rename variables * add type to parameters * reformat comments * use object instead Object * use uppercase for const
1 parent d2a7198 commit 1d86793

11 files changed

+994
-596
lines changed

packages/app/index.lite.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @license
3+
* Copyright 2019 Google Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import { createFirebaseNamespaceLite } from './src/lite/firebaseNamespaceLite';
19+
20+
export const firebase = createFirebaseNamespaceLite();
21+
22+
export default firebase;

packages/app/index.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,22 @@ to false and "main" to true:
4040
https://github.com/rollup/rollup-plugin-node-resolve
4141
`);
4242

43+
// Firebase Lite detection
44+
if (self && 'firebase' in self) {
45+
console.warn(`
46+
Warning: Firebase is already defined in the global scope. Please make sure
47+
Firebase library is only loaded once.
48+
`);
49+
50+
const sdkVersion = ((self as any).firebase as FirebaseNamespace).SDK_VERSION;
51+
if (sdkVersion.includes('LITE')) {
52+
console.warn(`
53+
Warning: You are trying to load Firebase while using Firebase Performance standalone script.
54+
You should load Firebase Performance with this instance of Firebase to avoid loading duplicate code.
55+
`);
56+
}
57+
}
58+
4359
export const firebase = createFirebaseNamespace();
4460

4561
export default firebase;

packages/app/rollup.config.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,15 @@ export default [
6969
[...deps, 'react-native'].some(
7070
dep => id === dep || id.startsWith(`${dep}/`)
7171
)
72+
},
73+
{
74+
input: 'index.lite.ts',
75+
output: {
76+
file: 'dist/index.lite.js',
77+
format: 'esm',
78+
sourcemap: true
79+
},
80+
plugins,
81+
external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`))
7282
}
7383
];

packages/app/src/constants.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* @license
3+
* Copyright 2019 Google Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
export const DEFAULT_ENTRY_NAME = '[DEFAULT]';

packages/app/src/errors.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const enum AppError {
2626
INVALID_APP_ARGUMENT = 'invalid-app-argument'
2727
}
2828

29-
const errors: ErrorMap<AppError> = {
29+
const ERRORS: ErrorMap<AppError> = {
3030
[AppError.NO_APP]:
3131
"No Firebase App '{$name}' has been created - " +
3232
'call Firebase App.initializeApp()',
@@ -40,7 +40,7 @@ const errors: ErrorMap<AppError> = {
4040
'Firebase App instance.'
4141
};
4242

43-
const appErrors = new ErrorFactory('app', 'Firebase', errors);
43+
const appErrors = new ErrorFactory<AppError>('app', 'Firebase', ERRORS);
4444

4545
export function error(code: AppError, args?: { [name: string]: any }) {
4646
throw appErrors.create(code, args);

packages/app/src/firebaseApp.ts

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,23 @@
1818
import {
1919
FirebaseApp,
2020
FirebaseOptions,
21-
FirebaseNamespace,
2221
FirebaseAppConfig
2322
} from '@firebase/app-types';
2423
import {
2524
_FirebaseApp,
2625
_FirebaseNamespace,
27-
FirebaseService
26+
FirebaseService,
27+
FirebaseAppInternals
2828
} from '@firebase/app-types/private';
2929
import { deepCopy, deepExtend } from '@firebase/util';
3030
import { error, AppError } from './errors';
31+
import { DEFAULT_ENTRY_NAME } from './constants';
3132

32-
export const DEFAULT_ENTRY_NAME = '[DEFAULT]';
33+
interface ServicesCache {
34+
[name: string]: {
35+
[serviceName: string]: FirebaseService;
36+
};
37+
}
3338

3439
// An array to capture listeners before the true auth functions
3540
// exist
@@ -40,25 +45,21 @@ let tokenListeners: any[] = [];
4045
* a shared authentication state.
4146
*/
4247
export class FirebaseAppImpl implements FirebaseApp {
43-
private options_: FirebaseOptions;
44-
private name_: string;
48+
private readonly options_: FirebaseOptions;
49+
private readonly name_: string;
4550
private isDeleted_ = false;
46-
private services_: {
47-
[name: string]: {
48-
[serviceName: string]: FirebaseService;
49-
};
50-
} = {};
51-
private _automaticDataCollectionEnabled: boolean;
51+
private services_: ServicesCache = {};
52+
private automaticDataCollectionEnabled_: boolean;
5253

53-
public INTERNAL;
54+
INTERNAL: FirebaseAppInternals;
5455

5556
constructor(
5657
options: FirebaseOptions,
5758
config: FirebaseAppConfig,
58-
private firebase_: FirebaseNamespace
59+
private readonly firebase_: _FirebaseNamespace
5960
) {
6061
this.name_ = config.name!;
61-
this._automaticDataCollectionEnabled =
62+
this.automaticDataCollectionEnabled_ =
6263
config.automaticDataCollectionEnabled || false;
6364
this.options_ = deepCopy<FirebaseOptions>(options);
6465
this.INTERNAL = {
@@ -79,12 +80,12 @@ export class FirebaseAppImpl implements FirebaseApp {
7980

8081
get automaticDataCollectionEnabled(): boolean {
8182
this.checkDestroyed_();
82-
return this._automaticDataCollectionEnabled;
83+
return this.automaticDataCollectionEnabled_;
8384
}
8485

8586
set automaticDataCollectionEnabled(val) {
8687
this.checkDestroyed_();
87-
this._automaticDataCollectionEnabled = val;
88+
this.automaticDataCollectionEnabled_ = val;
8889
}
8990

9091
get name(): string {
@@ -103,16 +104,18 @@ export class FirebaseAppImpl implements FirebaseApp {
103104
resolve();
104105
})
105106
.then(() => {
106-
(this.firebase_ as _FirebaseNamespace).INTERNAL.removeApp(this.name_);
107-
let services: FirebaseService[] = [];
108-
Object.keys(this.services_).forEach(serviceKey => {
109-
Object.keys(this.services_[serviceKey]).forEach(instanceKey => {
107+
this.firebase_.INTERNAL.removeApp(this.name_);
108+
const services: FirebaseService[] = [];
109+
110+
for (const serviceKey of Object.keys(this.services_)) {
111+
for (const instanceKey of Object.keys(this.services_[serviceKey])) {
110112
services.push(this.services_[serviceKey][instanceKey]);
111-
});
112-
});
113+
}
114+
}
115+
113116
return Promise.all(
114117
services.map(service => {
115-
return service.INTERNAL!.delete();
118+
return service.INTERNAL.delete();
116119
})
117120
);
118121
})
@@ -157,9 +160,11 @@ export class FirebaseAppImpl implements FirebaseApp {
157160
instanceIdentifier !== DEFAULT_ENTRY_NAME
158161
? instanceIdentifier
159162
: undefined;
160-
const service = (this.firebase_ as _FirebaseNamespace).INTERNAL.factories[
161-
name
162-
](this, this.extendApp.bind(this), instanceSpecifier);
163+
const service = this.firebase_.INTERNAL.factories[name](
164+
this,
165+
this.extendApp.bind(this),
166+
instanceSpecifier
167+
);
163168
this.services_[name][instanceIdentifier] = service;
164169
}
165170

0 commit comments

Comments
 (0)