@angular/fire 16.0.0-rc.0 → 16.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
 
2
2
  # AngularFire
3
- The official [Angular](https://angular.io/) library for [Firebase](https://firebase.google.com/).
3
+
4
+ AngularFire smooths over the rough edges an Angular developer might encounter when implementing the framework-agnostic
5
+ [Firebase JS SDK](https://github.com/firebase/firebase-js-sdk) & aims to provide a more natural developer experience
6
+ by conforming to Angular conventions.
4
7
 
5
8
  <strong><pre>ng add @angular/fire</pre></strong>
6
9
 
@@ -8,10 +11,6 @@ _Note: If you want to ng add AngularFire and will be using Hosting/Cloud Functio
8
11
  Firebase CLI first so that you are logged in for the schematics that are run as part of `ng add @angular/fire`.
9
12
  Follow [this guide](docs/install-firebase-tools.md) to have the Firebase CLI walk you through the setup._
10
13
 
11
- AngularFire smooths over the rough edges an Angular developer might encounter when implementing the framework-agnostic
12
- [Firebase JS SDK](https://github.com/firebase/firebase-js-sdk) & aims to provide a more natural developer experience
13
- by conforming to Angular conventions.
14
-
15
14
  - **Dependency injection** - Provide and Inject Firebase services in your components
16
15
  - **Zone.js wrappers** - Stable zones allow proper functionality of service workers, forms, SSR, and pre-rendering
17
16
  - **Observable based** - Utilize RxJS rather than callbacks for realtime streams
@@ -68,28 +67,6 @@ export class AppComponent {
68
67
  }
69
68
  ```
70
69
 
71
- ## Compatibility
72
-
73
- ### Angular and Firebase versions
74
-
75
- AngularFire doesn't follow Angular's versioning as Firebase also has breaking changes throughout the year. Instead we try to maintain compatibility with both Firebase and Angular majors for as long as possible, only breaking when we need to support a new major of one or the other.
76
-
77
- | Angular | Firebase | AngularFire |
78
- | --------|----------|--------------|
79
- | 16 | 9 | ^7.6 |
80
- | 15 | 9 | ^7.5 |
81
- | 14 | 9 | ^7.4 |
82
- | 13 | 9 | ^7.2 |
83
- | 12 | 9 | ^7.0 |
84
- | 12 | 7,8 | ^6.1.5 |
85
- | 11 | 7,8 | ^6.1 |
86
- | 10 | 8 | ^6.0.4 |
87
- | 10 | 7 | ^6.0.3 |
88
- | 9 | 8 | ^6.0.4 |
89
- | 9 | 7 | ^6.0 |
90
-
91
- <sub>Version combinations not documented here __may__ work but are untested and you will see NPM peer warnings.</sub>
92
-
93
70
  ### Polyfills
94
71
 
95
72
  Neither AngularFire or Firebase ship with polyfills. To have compatibility across as wide-range of environments we suggest the following polyfills be added to your application:
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "../node_modules/ng-packagr/package.schema.json",
3
3
  "name": "@angular/fire",
4
- "version": "16.0.0-rc.0",
5
- "description": "The official Angular library for Firebase.",
4
+ "version": "16.0.0",
5
+ "description": "Angular + Firebase = ❤️",
6
6
  "schematics": "./schematics/collection.json",
7
7
  "builders": "./schematics/builders.json",
8
8
  "keywords": [
@@ -4,12 +4,13 @@ exports.featureOptions = void 0;
4
4
  exports.featureOptions = [
5
5
  { name: 'ng deploy -- hosting', value: 0 },
6
6
  { name: 'Authentication', value: 1 },
7
- { name: 'Firestore', value: 7 },
8
- { name: 'Realtime Database', value: 3 },
9
- { name: 'Analytics', value: 2 },
10
- { name: 'Cloud Functions (callable)', value: 4 },
11
- { name: 'Cloud Messaging', value: 5 },
12
- { name: 'Performance Monitoring', value: 6 },
13
- { name: 'Cloud Storage', value: 8 },
14
- { name: 'Remote Config', value: 9 },
7
+ { name: 'Google Analytics', value: 2 },
8
+ { name: 'App Check', value: 3 },
9
+ { name: 'Firestore', value: 8 },
10
+ { name: 'Realtime Database', value: 4 },
11
+ { name: 'Cloud Functions (callable)', value: 5 },
12
+ { name: 'Cloud Messaging', value: 6 },
13
+ { name: 'Performance Monitoring', value: 7 },
14
+ { name: 'Cloud Storage', value: 9 },
15
+ { name: 'Remote Config', value: 10 },
15
16
  ];
@@ -14,64 +14,48 @@ const fs_1 = require("fs");
14
14
  const path_1 = require("path");
15
15
  const core_1 = require("@angular-devkit/core");
16
16
  const schematics_1 = require("@angular-devkit/schematics");
17
+ const utility_1 = require("@schematics/angular/utility");
17
18
  const common_1 = require("../common");
18
19
  const firebaseTools_1 = require("../firebaseTools");
19
20
  const utils_1 = require("../utils");
20
21
  const prompts_1 = require("./prompts");
21
- const setupProject = (tree, context, features, config) => __awaiter(void 0, void 0, void 0, function* () {
22
- var _a;
23
- const { path: workspacePath, workspace } = (0, utils_1.getWorkspace)(tree);
24
- const { project, projectName } = (0, utils_1.getProject)(config, tree);
25
- const sourcePath = (_a = project.sourceRoot) !== null && _a !== void 0 ? _a : project.root;
22
+ const setupProject = (tree, context, features, config) => {
23
+ const { projectName } = (0, utils_1.getProject)(config, tree);
26
24
  (0, utils_1.addIgnoreFiles)(tree);
27
- const featuresToImport = features.filter(it => it !== 0);
28
- if (featuresToImport.length > 0) {
29
- (0, utils_1.addToNgModule)(tree, { features: featuresToImport, sourcePath });
30
- (0, utils_1.addFixesToServer)(tree);
31
- }
32
- if (config.sdkConfig) {
33
- const source = `
34
- firebase: {
35
- ${Object.entries(config.sdkConfig).reduce((c, [k, v]) => c.concat(` ${k}: '${v}'`), []).join(',\n')},
36
- }`;
37
- const environmentPath = `${sourcePath}/environments/environment.ts`;
38
- (0, utils_1.addEnvironmentEntry)(tree, `/${environmentPath}`, source);
39
- Object.values(project.architect || {}).forEach(builder => {
40
- Object.values(builder.configurations || {}).forEach(configuration => {
41
- (configuration.fileReplacements || []).forEach((replacement) => {
42
- if (replacement.replace === environmentPath) {
43
- (0, utils_1.addEnvironmentEntry)(tree, `/${replacement.with}`, source);
44
- }
45
- });
46
- });
47
- });
48
- }
49
- const options = {
50
- project: projectName,
51
- firebaseProject: config.firebaseProject,
52
- firebaseApp: config.firebaseApp,
53
- firebaseHostingSite: config.firebaseHostingSite,
54
- sdkConfig: config.sdkConfig,
55
- prerender: undefined,
56
- browserTarget: config.browserTarget,
57
- serverTarget: config.serverTarget,
58
- prerenderTarget: config.prerenderTarget,
59
- ssrRegion: config.ssrRegion,
60
- };
61
25
  if (features.includes(0)) {
62
- return (0, exports.setupFirebase)({
26
+ const { path: workspacePath, workspace } = (0, utils_1.getWorkspace)(tree);
27
+ const { project, projectName } = (0, utils_1.getProject)(config, tree);
28
+ (0, exports.setupFirebase)({
63
29
  workspace,
64
30
  workspacePath,
65
- options,
31
+ options: {
32
+ project: projectName,
33
+ firebaseProject: config.firebaseProject,
34
+ firebaseApp: config.firebaseApp,
35
+ firebaseHostingSite: config.firebaseHostingSite,
36
+ sdkConfig: config.sdkConfig,
37
+ prerender: undefined,
38
+ browserTarget: config.browserTarget,
39
+ serverTarget: config.serverTarget,
40
+ prerenderTarget: config.prerenderTarget,
41
+ ssrRegion: config.ssrRegion,
42
+ },
66
43
  tree,
67
44
  context,
68
45
  project
69
46
  });
70
47
  }
71
- else {
72
- return Promise.resolve();
48
+ const featuresToImport = features.filter(it => it !== 0);
49
+ if (featuresToImport.length > 0) {
50
+ return (0, schematics_1.chain)([
51
+ (0, utility_1.addRootImport)(projectName, ({ code, external }) => {
52
+ external('initializeApp', '@angular/fire/app');
53
+ return code `${external('provideFirebaseApp', '@angular/fire/app')}(() => initializeApp(${JSON.stringify(config.sdkConfig)}))`;
54
+ }),
55
+ ...(0, utils_1.featureToRules)(features, projectName),
56
+ ]);
73
57
  }
74
- });
58
+ };
75
59
  exports.setupProject = setupProject;
76
60
  const ngAddSetupProject = (options) => (host, context) => __awaiter(void 0, void 0, void 0, function* () {
77
61
  let projectRoot = host._backend._root;
@@ -104,7 +88,7 @@ const ngAddSetupProject = (options) => (host, context) => __awaiter(void 0, void
104
88
  const result = yield firebaseTools.apps.sdkconfig('web', firebaseApp.appId, { nonInteractive: true, projectRoot });
105
89
  sdkConfig = result.sdkConfig;
106
90
  }
107
- yield (0, exports.setupProject)(host, context, features, Object.assign(Object.assign(Object.assign({}, options), hosting), { firebaseProject, firebaseApp, firebaseHostingSite, sdkConfig }));
91
+ return (0, exports.setupProject)(host, context, features, Object.assign(Object.assign(Object.assign({}, options), hosting), { firebaseProject, firebaseApp, firebaseHostingSite, sdkConfig }));
108
92
  }
109
93
  });
110
94
  exports.ngAddSetupProject = ngAddSetupProject;
@@ -3,14 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.addIgnoreFiles = exports.addToNgModule = exports.addFixesToServer = exports.addEnvironmentEntry = exports.getFirebaseProjectNameFromFs = exports.getFirebaseProjectNameFromHost = exports.getProject = exports.getWorkspace = exports.shortAppId = exports.hasPrerenderOption = exports.isUniversalApp = void 0;
6
+ exports.addIgnoreFiles = exports.featureToRules = exports.addFixesToServer = exports.addEnvironmentEntry = exports.getFirebaseProjectNameFromFs = exports.getFirebaseProjectNameFromHost = exports.getProject = exports.getWorkspace = exports.shortAppId = exports.hasPrerenderOption = exports.isUniversalApp = void 0;
7
7
  const fs_1 = require("fs");
8
8
  const path_1 = require("path");
9
9
  const schematics_1 = require("@angular-devkit/schematics");
10
10
  const typescript_1 = __importDefault(require("@schematics/angular/third_party/github.com/Microsoft/TypeScript/lib/typescript"));
11
+ const utility_1 = require("@schematics/angular/utility");
11
12
  const ast_utils_1 = require("@schematics/angular/utility/ast-utils");
12
13
  const change_1 = require("@schematics/angular/utility/change");
13
- const find_module_1 = require("@schematics/angular/utility/find-module");
14
14
  const common_1 = require("./common");
15
15
  const isUniversalApp = (project) => { var _a; return (_a = project.architect) === null || _a === void 0 ? void 0 : _a.server; };
16
16
  exports.isUniversalApp = isUniversalApp;
@@ -138,64 +138,80 @@ ${addZonePatch ? 'import \'zone.js/dist/zone-patch-rxjs\';' : ''}`));
138
138
  return host;
139
139
  }
140
140
  exports.addFixesToServer = addFixesToServer;
141
- function addToNgModule(host, options) {
142
- const modulePath = `/${options.sourcePath}/app/app.module.ts`;
143
- if (!host.exists(modulePath)) {
144
- throw new Error(`Specified module path ${modulePath} does not exist`);
145
- }
146
- const text = host.read(modulePath);
147
- if (text === null) {
148
- throw new schematics_1.SchematicsException(`File ${modulePath} does not exist.`);
149
- }
150
- const sourceText = text.toString('utf-8');
151
- const source = typescript_1.default.createSourceFile(modulePath, sourceText, typescript_1.default.ScriptTarget.Latest, true);
152
- const environmentsPath = (0, find_module_1.buildRelativePath)(modulePath, `/${options.sourcePath}/environments/environment`);
153
- const changes = [];
154
- if (!(0, ast_utils_1.findNode)(source, typescript_1.default.SyntaxKind.Identifier, 'provideFirebaseApp')) {
155
- changes.push((0, ast_utils_1.insertImport)(source, modulePath, ['initializeApp', 'provideFirebaseApp'], '@angular/fire/app'), (0, ast_utils_1.insertImport)(source, modulePath, 'environment', environmentsPath), ...(0, ast_utils_1.addImportToModule)(source, modulePath, `provideFirebaseApp(() => initializeApp(environment.firebase))`, null));
156
- }
157
- if (options.features.includes(2) &&
158
- !(0, ast_utils_1.findNode)(source, typescript_1.default.SyntaxKind.Identifier, 'provideAnalytics')) {
159
- changes.push((0, ast_utils_1.insertImport)(source, modulePath, ['provideAnalytics', 'getAnalytics', 'ScreenTrackingService', 'UserTrackingService'], '@angular/fire/analytics'), ...(0, ast_utils_1.addImportToModule)(source, modulePath, `provideAnalytics(() => getAnalytics())`, null), ...(0, ast_utils_1.addProviderToModule)(source, modulePath, ['ScreenTrackingService', 'UserTrackingService'], null));
160
- }
161
- if (options.features.includes(1) &&
162
- !(0, ast_utils_1.findNode)(source, typescript_1.default.SyntaxKind.Identifier, 'provideAuth')) {
163
- changes.push((0, ast_utils_1.insertImport)(source, modulePath, ['provideAuth', 'getAuth'], '@angular/fire/auth'), ...(0, ast_utils_1.addImportToModule)(source, modulePath, `provideAuth(() => getAuth())`, null));
164
- }
165
- if (options.features.includes(3) &&
166
- !(0, ast_utils_1.findNode)(source, typescript_1.default.SyntaxKind.Identifier, 'provideDatabase')) {
167
- changes.push((0, ast_utils_1.insertImport)(source, modulePath, ['provideDatabase', 'getDatabase'], '@angular/fire/database'), ...(0, ast_utils_1.addImportToModule)(source, modulePath, `provideDatabase(() => getDatabase())`, null));
168
- }
169
- if (options.features.includes(7) &&
170
- !(0, ast_utils_1.findNode)(source, typescript_1.default.SyntaxKind.Identifier, 'provideFirestore')) {
171
- changes.push((0, ast_utils_1.insertImport)(source, modulePath, ['provideFirestore', 'getFirestore'], '@angular/fire/firestore'), ...(0, ast_utils_1.addImportToModule)(source, modulePath, `provideFirestore(() => getFirestore())`, null));
172
- }
173
- if (options.features.includes(4) &&
174
- !(0, ast_utils_1.findNode)(source, typescript_1.default.SyntaxKind.Identifier, 'provideFunctions')) {
175
- changes.push((0, ast_utils_1.insertImport)(source, modulePath, ['provideFunctions', 'getFunctions'], '@angular/fire/functions'), ...(0, ast_utils_1.addImportToModule)(source, modulePath, `provideFunctions(() => getFunctions())`, null));
176
- }
177
- if (options.features.includes(5) &&
178
- !(0, ast_utils_1.findNode)(source, typescript_1.default.SyntaxKind.Identifier, 'provideMessaging')) {
179
- changes.push((0, ast_utils_1.insertImport)(source, modulePath, ['provideMessaging', 'getMessaging'], '@angular/fire/messaging'), ...(0, ast_utils_1.addImportToModule)(source, modulePath, `provideMessaging(() => getMessaging())`, null));
180
- }
181
- if (options.features.includes(6) &&
182
- !(0, ast_utils_1.findNode)(source, typescript_1.default.SyntaxKind.Identifier, 'providePerformance')) {
183
- changes.push((0, ast_utils_1.insertImport)(source, modulePath, ['providePerformance', 'getPerformance'], '@angular/fire/performance'), ...(0, ast_utils_1.addImportToModule)(source, modulePath, `providePerformance(() => getPerformance())`, null));
184
- }
185
- if (options.features.includes(9) &&
186
- !(0, ast_utils_1.findNode)(source, typescript_1.default.SyntaxKind.Identifier, 'provideRemoteConfig')) {
187
- changes.push((0, ast_utils_1.insertImport)(source, modulePath, ['provideRemoteConfig', 'getRemoteConfig'], '@angular/fire/remote-config'), ...(0, ast_utils_1.addImportToModule)(source, modulePath, `provideRemoteConfig(() => getRemoteConfig())`, null));
188
- }
189
- if (options.features.includes(8) &&
190
- !(0, ast_utils_1.findNode)(source, typescript_1.default.SyntaxKind.Identifier, 'provideStorage')) {
191
- changes.push((0, ast_utils_1.insertImport)(source, modulePath, ['provideStorage', 'getStorage'], '@angular/fire/storage'), ...(0, ast_utils_1.addImportToModule)(source, modulePath, `provideStorage(() => getStorage())`, null));
192
- }
193
- const recorder = host.beginUpdate(modulePath);
194
- (0, change_1.applyToUpdateRecorder)(recorder, changes);
195
- host.commitUpdate(recorder);
196
- return host;
141
+ function featureToRules(features, projectName) {
142
+ return features.map(feature => {
143
+ switch (feature) {
144
+ case 3:
145
+ return (0, utility_1.addRootImport)(projectName, ({ code, external }) => {
146
+ external('initializeAppCheck', '@angular/fire/app-check');
147
+ external('ReCaptchaEnterpriseProvider', '@angular/fire/app-check');
148
+ return code `${external('provideAppCheck', '@angular/fire/app-check')}(() => {
149
+ // TODO get a reCAPTCHA Enterprise here https://console.cloud.google.com/security/recaptcha?project=_
150
+ const provider = new ReCaptchaEnterpriseProvider(/* reCAPTCHA Enterprise site key */);
151
+ return initializeAppCheck(undefined, { provider, isTokenAutoRefreshEnabled: true });
152
+ })`;
153
+ });
154
+ case 2:
155
+ return (0, schematics_1.chain)([
156
+ (0, utility_1.addRootImport)(projectName, ({ code, external }) => {
157
+ external('getAnalytics', '@angular/fire/analytics');
158
+ return code `${external('provideAnalytics', '@angular/fire/analytics')}(() => getAnalytics())`;
159
+ }),
160
+ (0, utility_1.addRootProvider)(projectName, ({ code, external }) => {
161
+ return code `${external('ScreenTrackingService', '@angular/fire/analytics')}`;
162
+ }),
163
+ ...(features.includes(1) ? [
164
+ (0, utility_1.addRootProvider)(projectName, ({ code, external }) => {
165
+ return code `${external('UserTrackingService', '@angular/fire/analytics')}`;
166
+ })
167
+ ] : []),
168
+ ]);
169
+ case 1:
170
+ return (0, utility_1.addRootImport)(projectName, ({ code, external }) => {
171
+ external('getAuth', '@angular/fire/auth');
172
+ return code `${external('provideAuth', '@angular/fire/auth')}(() => getAuth())`;
173
+ });
174
+ case 4:
175
+ return (0, utility_1.addRootImport)(projectName, ({ code, external }) => {
176
+ external('getDatabase', '@angular/fire/database');
177
+ return code `${external('provideDatabase', '@angular/fire/database')}(() => getDatabase())`;
178
+ });
179
+ case 8:
180
+ return (0, utility_1.addRootImport)(projectName, ({ code, external }) => {
181
+ external('getFirestore', '@angular/fire/firestore');
182
+ return code `${external('provideFirestore', '@angular/fire/firestore')}(() => getFirestore())`;
183
+ });
184
+ case 5:
185
+ return (0, utility_1.addRootImport)(projectName, ({ code, external }) => {
186
+ external('getFunctions', '@angular/fire/functions');
187
+ return code `${external('provideFunctions', '@angular/fire/functions')}(() => getFunctions())`;
188
+ });
189
+ case 6:
190
+ return (0, utility_1.addRootImport)(projectName, ({ code, external }) => {
191
+ external('getMessaging', '@angular/fire/messaging');
192
+ return code `${external('provideMessaging', '@angular/fire/messaging')}(() => getMessaging())`;
193
+ });
194
+ case 7:
195
+ return (0, utility_1.addRootImport)(projectName, ({ code, external }) => {
196
+ external('getPerformance', '@angular/fire/performance');
197
+ return code `${external('providePerformance', '@angular/fire/performance')}(() => getPerformance())`;
198
+ });
199
+ case 9:
200
+ return (0, utility_1.addRootImport)(projectName, ({ code, external }) => {
201
+ external('getStorage', '@angular/fire/storage');
202
+ return code `${external('provideStorage', '@angular/fire/storage')}(() => getStorage())`;
203
+ });
204
+ case 10:
205
+ return (0, utility_1.addRootImport)(projectName, ({ code, external }) => {
206
+ external('getRemoteConfig', '@angular/fire/remote-config');
207
+ return code `${external('provideRemoteConfig', '@angular/fire/remote-config')}(() => getRemoteConfig())`;
208
+ });
209
+ default:
210
+ return undefined;
211
+ }
212
+ }).filter((it) => !!it);
197
213
  }
198
- exports.addToNgModule = addToNgModule;
214
+ exports.featureToRules = featureToRules;
199
215
  const addIgnoreFiles = (host) => {
200
216
  const path = '/.gitignore';
201
217
  if (!host.exists(path)) {