@angular/fire 7.5.0 → 7.6.0-canary.59b95af

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.
Files changed (60) hide show
  1. package/README.md +86 -71
  2. package/bundles/angular-fire.umd.js +1 -1
  3. package/bundles/angular-fire.umd.js.map +1 -1
  4. package/compat/firestore/interfaces.d.ts +4 -4
  5. package/docs/analytics.md +67 -0
  6. package/docs/app-check.md +53 -0
  7. package/docs/auth.md +165 -0
  8. package/docs/{analytics → compat/analytics}/getting-started.md +2 -0
  9. package/docs/{auth → compat/auth}/getting-started.md +2 -0
  10. package/docs/{auth → compat/auth}/router-guards.md +2 -0
  11. package/docs/{emulators → compat/emulators}/emulators.md +2 -0
  12. package/docs/{firestore → compat/firestore}/collections.md +2 -0
  13. package/docs/{firestore → compat/firestore}/documents.md +2 -0
  14. package/docs/{firestore → compat/firestore}/offline-data.md +2 -0
  15. package/docs/{firestore → compat/firestore}/querying-collections.md +2 -0
  16. package/docs/{functions → compat/functions}/functions.md +2 -0
  17. package/docs/{messaging → compat/messaging}/messaging.md +2 -0
  18. package/docs/{performance → compat/performance}/getting-started.md +2 -0
  19. package/docs/{remote-config → compat/remote-config}/getting-started.md +2 -0
  20. package/docs/{rtdb → compat/rtdb}/lists.md +2 -0
  21. package/docs/{rtdb → compat/rtdb}/objects.md +2 -0
  22. package/docs/{rtdb → compat/rtdb}/querying-lists.md +2 -0
  23. package/docs/{storage → compat/storage}/storage.md +2 -0
  24. package/docs/compat.md +70 -0
  25. package/docs/database.md +175 -0
  26. package/docs/firestore.md +148 -0
  27. package/docs/functions.md +52 -0
  28. package/docs/images/analytics-illo_1x.png +0 -0
  29. package/docs/images/auth-illo_1x.png +0 -0
  30. package/docs/images/cloud-messaging-illo_1x.png +0 -0
  31. package/docs/images/database-illo_1x.png +0 -0
  32. package/docs/images/firestore-illo_1x.png +0 -0
  33. package/docs/images/functions-illo_1x.png +0 -0
  34. package/docs/images/hosting-illo_1x.png +0 -0
  35. package/docs/images/performance-illo_1x.png +0 -0
  36. package/docs/images/reCAPTCHA-logo@1x.png +0 -0
  37. package/docs/images/remote-config-illo_1x.png +0 -0
  38. package/docs/images/storage-illo_1x.png +0 -0
  39. package/docs/install-and-setup.md +39 -86
  40. package/docs/messaging.md +25 -0
  41. package/docs/performance.md +57 -0
  42. package/docs/remote-config.md +53 -0
  43. package/docs/storage.md +90 -0
  44. package/esm2015/compat/firestore/interfaces.js +1 -1
  45. package/esm2015/core.js +1 -1
  46. package/fesm2015/angular-fire.js +1 -1
  47. package/fesm2015/angular-fire.js.map +1 -1
  48. package/package.json +9 -10
  49. package/schematics/deploy/actions.js +23 -14
  50. package/schematics/deploy/builder.js +2 -2
  51. package/schematics/firebaseTools.js +4 -2
  52. package/schematics/setup/index.js +58 -29
  53. package/schematics/setup/prompts.js +18 -46
  54. package/schematics/utils.js +32 -28
  55. package/docs/ionic/authentication.md +0 -104
  56. package/docs/ionic/cli.md +0 -218
  57. package/docs/ionic/v2.md +0 -531
  58. package/docs/ionic/v3.md +0 -705
  59. package/schematics/setup/ssr.js +0 -100
  60. package/schematics/setup/static.js +0 -78
@@ -93,7 +93,7 @@ const deployToHosting = (firebaseTools, context, workspaceRoot, options, firebas
93
93
  yield firebaseTools.serve({
94
94
  port: DEFAULT_EMULATOR_PORT,
95
95
  host: DEFAULT_EMULATOR_HOST,
96
- targets: [`hosting:${siteTarget}`],
96
+ only: `hosting:${siteTarget}`,
97
97
  nonInteractive: true,
98
98
  projectRoot: workspaceRoot,
99
99
  });
@@ -105,6 +105,7 @@ const deployToHosting = (firebaseTools, context, workspaceRoot, options, firebas
105
105
  if (!deployProject) {
106
106
  return;
107
107
  }
108
+ process.env.FIREBASE_FRAMEWORKS_SKIP_BUILD = 'true';
108
109
  }
109
110
  return yield firebaseTools.deploy({
110
111
  only: `hosting:${siteTarget}`,
@@ -319,22 +320,30 @@ function deploy(firebaseTools, context, staticBuildTarget, serverBuildTarget, pr
319
320
  const user = yield firebaseTools.login({ projectRoot: context.workspaceRoot });
320
321
  console.log(`Logged into Firebase as ${user.email}.`);
321
322
  }
322
- if (prerenderBuildTarget) {
323
- const run = yield context.scheduleTarget(architect_1.targetFromTargetString(prerenderBuildTarget.name), prerenderBuildTarget.options);
324
- yield run.result;
323
+ if (options.version && options.version >= 2) {
324
+ if (semver_1.lt(firebaseTools.cli.version(), '12.2.0')) {
325
+ throw new schematics_1.SchematicsException('firebase-tools version 12.2+ is required.');
326
+ }
327
+ process.env.FIREBASE_FRAMEWORK_BUILD_TARGET = (prerenderBuildTarget || serverBuildTarget || staticBuildTarget).name;
325
328
  }
326
329
  else {
327
- if (!context.target) {
328
- throw new Error('Cannot execute the build target');
330
+ if (prerenderBuildTarget) {
331
+ const run = yield context.scheduleTarget(architect_1.targetFromTargetString(prerenderBuildTarget.name), prerenderBuildTarget.options);
332
+ yield run.result;
329
333
  }
330
- context.logger.info(`📦 Building "${context.target.project}"`);
331
- const builders = [
332
- context.scheduleTarget(architect_1.targetFromTargetString(staticBuildTarget.name), staticBuildTarget.options).then(run => run.result)
333
- ];
334
- if (serverBuildTarget) {
335
- builders.push(context.scheduleTarget(architect_1.targetFromTargetString(serverBuildTarget.name), serverBuildTarget.options).then(run => run.result));
334
+ else {
335
+ if (!context.target) {
336
+ throw new Error('Cannot execute the build target');
337
+ }
338
+ context.logger.info(`📦 Building "${context.target.project}"`);
339
+ const builders = [
340
+ context.scheduleTarget(architect_1.targetFromTargetString(staticBuildTarget.name), staticBuildTarget.options).then(run => run.result)
341
+ ];
342
+ if (serverBuildTarget) {
343
+ builders.push(context.scheduleTarget(architect_1.targetFromTargetString(serverBuildTarget.name), serverBuildTarget.options).then(run => run.result));
344
+ }
345
+ yield Promise.all(builders);
336
346
  }
337
- yield Promise.all(builders);
338
347
  }
339
348
  try {
340
349
  yield firebaseTools.use(firebaseProject, {
@@ -364,7 +373,7 @@ function deploy(firebaseTools, context, staticBuildTarget, serverBuildTarget, pr
364
373
  })
365
374
  });
366
375
  firebaseTools.logger.logger.add(logger);
367
- if (serverBuildTarget) {
376
+ if ((!options.version || options.version < 2) && serverBuildTarget) {
368
377
  if (options.ssr === 'cloud-run') {
369
378
  yield exports.deployToCloudRun(firebaseTools, context, context.workspaceRoot, staticBuildTarget, serverBuildTarget, options, firebaseToken);
370
379
  }
@@ -23,14 +23,14 @@ exports.default = architect_1.createBuilder((options, context) => __awaiter(void
23
23
  const [defaultFirebaseProject, defulatFirebaseHostingSite] = utils_1.getFirebaseProjectNameFromFs(context.workspaceRoot, context.target.project);
24
24
  const firebaseProject = options.firebaseProject || defaultFirebaseProject;
25
25
  if (!firebaseProject) {
26
- throw new Error('Cannot detirmine the Firebase Project from your angular.json or .firebaserc');
26
+ throw new Error('Cannot determine the Firebase Project from your angular.json or .firebaserc');
27
27
  }
28
28
  if (firebaseProject !== defaultFirebaseProject) {
29
29
  throw new Error('The Firebase Project specified by your angular.json or .firebaserc is in conflict');
30
30
  }
31
31
  const firebaseHostingSite = options.firebaseHostingSite || defulatFirebaseHostingSite;
32
32
  if (!firebaseHostingSite) {
33
- throw new Error(`Cannot detirmine the Firebase Hosting Site from your angular.json or .firebaserc`);
33
+ throw new Error(`Cannot determine the Firebase Hosting Site from your angular.json or .firebaserc`);
34
34
  }
35
35
  if (firebaseHostingSite !== defulatFirebaseHostingSite) {
36
36
  throw new Error('The Firebase Hosting Site specified by your angular.json or .firebaserc is in conflict');
@@ -29,12 +29,14 @@ const semver = __importStar(require("semver"));
29
29
  const getFirebaseTools = () => globalThis.firebaseTools ?
30
30
  Promise.resolve(globalThis.firebaseTools) :
31
31
  new Promise((resolve, reject) => {
32
+ var _a;
33
+ (_a = process.env).FIREBASE_CLI_EXPERIMENTS || (_a.FIREBASE_CLI_EXPERIMENTS = 'webframeworks');
32
34
  try {
33
35
  resolve(require('firebase-tools'));
34
36
  }
35
37
  catch (e) {
36
38
  try {
37
- const root = child_process_1.execSync('npm root -g').toString().trim();
39
+ const root = child_process_1.execSync('npm root --location=global').toString().trim();
38
40
  resolve(require(`${root}/firebase-tools`));
39
41
  }
40
42
  catch (e) {
@@ -42,7 +44,7 @@ const getFirebaseTools = () => globalThis.firebaseTools ?
42
44
  text: `Installing firebase-tools...`,
43
45
  discardStdin: process.platform !== 'win32',
44
46
  }).start();
45
- child_process_1.spawn('npm', ['i', '-g', 'firebase-tools'], {
47
+ child_process_1.spawn('npm', ['i', '--location=global', 'firebase-tools'], {
46
48
  stdio: 'pipe',
47
49
  shell: true,
48
50
  }).on('close', (code) => {
@@ -9,16 +9,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.ngAddSetupProject = exports.setupProject = void 0;
12
+ exports.setupFirebase = exports.generateFirebaseJson = exports.ngAddSetupProject = exports.setupProject = void 0;
13
13
  const core_1 = require("@angular-devkit/core");
14
14
  const schematics_1 = require("@angular-devkit/schematics");
15
15
  const utils_1 = require("../utils");
16
16
  const prompts_1 = require("./prompts");
17
- const ssr_1 = require("./ssr");
18
- const static_1 = require("./static");
19
17
  const firebaseTools_1 = require("../firebaseTools");
20
18
  const fs_1 = require("fs");
21
19
  const path_1 = require("path");
20
+ const common_1 = require("../common");
22
21
  const setupProject = (tree, context, features, config) => __awaiter(void 0, void 0, void 0, function* () {
23
22
  var _a;
24
23
  const { path: workspacePath, workspace } = utils_1.getWorkspace(tree);
@@ -53,36 +52,21 @@ ${Object.entries(config.sdkConfig).reduce((c, [k, v]) => c.concat(` ${k}: '${
53
52
  firebaseApp: config.firebaseApp,
54
53
  firebaseHostingSite: config.firebaseHostingSite,
55
54
  sdkConfig: config.sdkConfig,
56
- prerender: config.prerender,
55
+ prerender: undefined,
57
56
  browserTarget: config.browserTarget,
58
57
  serverTarget: config.serverTarget,
59
58
  prerenderTarget: config.prerenderTarget,
59
+ ssrRegion: config.ssrRegion,
60
60
  };
61
61
  if (features.includes(0)) {
62
- switch (config.projectType) {
63
- case 1:
64
- case 2:
65
- return ssr_1.setupUniversalDeployment({
66
- workspace,
67
- workspacePath,
68
- options,
69
- tree,
70
- context,
71
- project,
72
- projectType: config.projectType,
73
- nodeVersion: config.nodeVersion,
74
- });
75
- case 0:
76
- return static_1.setupStaticDeployment({
77
- workspace,
78
- workspacePath,
79
- options,
80
- tree,
81
- context,
82
- project
83
- });
84
- default: throw (new schematics_1.SchematicsException(`Unimplemented PROJECT_TYPE ${config.projectType}`));
85
- }
62
+ return exports.setupFirebase({
63
+ workspace,
64
+ workspacePath,
65
+ options,
66
+ tree,
67
+ context,
68
+ project
69
+ });
86
70
  }
87
71
  else {
88
72
  return Promise.resolve();
@@ -105,7 +89,7 @@ const ngAddSetupProject = (options) => (host, context) => __awaiter(void 0, void
105
89
  const { project: ngProject, projectName: ngProjectName } = utils_1.getProject(options, host);
106
90
  const [defaultProjectName] = utils_1.getFirebaseProjectNameFromHost(host, ngProjectName);
107
91
  const firebaseProject = yield prompts_1.projectPrompt(defaultProjectName, { projectRoot, account: user.email });
108
- let hosting = { projectType: 0, prerender: false };
92
+ let hosting = {};
109
93
  let firebaseHostingSite;
110
94
  if (features.includes(0)) {
111
95
  const results = yield prompts_1.projectTypePrompt(ngProject, ngProjectName);
@@ -124,3 +108,48 @@ const ngAddSetupProject = (options) => (host, context) => __awaiter(void 0, void
124
108
  }
125
109
  });
126
110
  exports.ngAddSetupProject = ngAddSetupProject;
111
+ function generateFirebaseJson(tree, path, project, region) {
112
+ const firebaseJson = tree.exists(path)
113
+ ? common_1.safeReadJSON(path, tree)
114
+ : {};
115
+ const newConfig = {
116
+ target: project,
117
+ source: '.',
118
+ frameworksBackend: {
119
+ region
120
+ }
121
+ };
122
+ if (firebaseJson.hosting === undefined) {
123
+ firebaseJson.hosting = [newConfig];
124
+ }
125
+ else if (Array.isArray(firebaseJson.hosting)) {
126
+ const existingConfigIndex = firebaseJson.hosting.findIndex(config => config.target === newConfig.target);
127
+ if (existingConfigIndex > -1) {
128
+ firebaseJson.hosting.splice(existingConfigIndex, 1, newConfig);
129
+ }
130
+ else {
131
+ firebaseJson.hosting.push(newConfig);
132
+ }
133
+ }
134
+ else {
135
+ firebaseJson.hosting = [firebaseJson.hosting, newConfig];
136
+ }
137
+ common_1.overwriteIfExists(tree, path, common_1.stringifyFormatted(firebaseJson));
138
+ }
139
+ exports.generateFirebaseJson = generateFirebaseJson;
140
+ const setupFirebase = (config) => {
141
+ const { tree, workspacePath, workspace, options } = config;
142
+ const project = workspace.projects[options.project];
143
+ if (!project.architect) {
144
+ throw new schematics_1.SchematicsException(`Angular project "${options.project}" has a malformed angular.json`);
145
+ }
146
+ project.architect.deploy = {
147
+ builder: '@angular/fire:deploy',
148
+ options: Object.assign(Object.assign({ version: 2, browserTarget: options.browserTarget }, (options.serverTarget ? { serverTarget: options.serverTarget } : {})), (options.prerenderTarget ? { prerenderTarget: options.prerenderTarget } : {}))
149
+ };
150
+ tree.overwrite(workspacePath, JSON.stringify(workspace, null, 2));
151
+ generateFirebaseJson(tree, 'firebase.json', options.project, options.ssrRegion);
152
+ common_1.generateFirebaseRc(tree, '.firebaserc', options.firebaseProject.projectId, options.firebaseHostingSite, options.project);
153
+ return tree;
154
+ };
155
+ exports.setupFirebase = setupFirebase;
@@ -243,61 +243,33 @@ const sitePrompt = ({ projectId: project }, options) => __awaiter(void 0, void 0
243
243
  return (yield sites).find(it => common_1.shortSiteName(it) === siteName);
244
244
  });
245
245
  exports.sitePrompt = sitePrompt;
246
+ const DEFAULT_REGION = 'us-central1';
247
+ const ALLOWED_SSR_REGIONS = [
248
+ { name: 'us-central1 (Iowa)', value: 'us-central1' },
249
+ { name: 'us-west1 (Oregon)', value: 'us-west1' },
250
+ { name: 'us-east1 (South Carolina)', value: 'us-east1' },
251
+ { name: 'europe-west1 (Belgium)', value: 'europe-west1' },
252
+ { name: 'asia-east1 (Taiwan)', value: 'asia-east1' },
253
+ ];
246
254
  const projectTypePrompt = (project, name) => __awaiter(void 0, void 0, void 0, function* () {
247
- var _b, _c, _d, _e, _f, _g, _h, _j;
248
- let prerender = false;
249
- let nodeVersion;
255
+ var _b, _c, _d, _e, _f, _g;
250
256
  let serverTarget;
251
257
  let browserTarget = `${name}:build:${((_c = (_b = project.architect) === null || _b === void 0 ? void 0 : _b.build) === null || _c === void 0 ? void 0 : _c.defaultConfiguration) || 'production'}`;
252
258
  let prerenderTarget;
253
259
  if (utils_1.isUniversalApp(project)) {
254
260
  serverTarget = `${name}:server:${((_e = (_d = project.architect) === null || _d === void 0 ? void 0 : _d.server) === null || _e === void 0 ? void 0 : _e.defaultConfiguration) || 'production'}`;
255
261
  browserTarget = `${name}:build:${((_g = (_f = project.architect) === null || _f === void 0 ? void 0 : _f.build) === null || _g === void 0 ? void 0 : _g.defaultConfiguration) || 'production'}`;
256
- if (utils_1.hasPrerenderOption(project)) {
257
- prerenderTarget = `${name}:prerender:${((_j = (_h = project.architect) === null || _h === void 0 ? void 0 : _h.prerender) === null || _j === void 0 ? void 0 : _j.defaultConfiguration) || 'production'}`;
258
- const { shouldPrerender } = yield inquirer.prompt({
259
- type: 'confirm',
260
- name: 'shouldPrerender',
261
- message: 'Should we prerender before deployment?',
262
- default: true
263
- });
264
- prerender = shouldPrerender;
265
- }
266
- const choices = [
267
- { name: prerender ? 'Pre-render only' : 'Don\'t render universal content', value: 0 },
268
- { name: 'Cloud Functions', value: 1 },
269
- { name: 'Cloud Run', value: 2 },
270
- ];
271
- const { projectType } = yield inquirer.prompt({
262
+ const prerender = utils_1.hasPrerenderOption(project);
263
+ prerenderTarget = prerender && `${name}:prerender:${prerender.defaultConfiguration || 'production'}`;
264
+ const { ssrRegion } = yield inquirer.prompt({
272
265
  type: 'list',
273
- name: 'projectType',
274
- choices,
275
- message: 'How would you like to render server-side content?',
276
- default: 1,
266
+ name: 'ssrRegion',
267
+ choices: ALLOWED_SSR_REGIONS,
268
+ message: 'In which region would you like to host server-side content?',
269
+ default: DEFAULT_REGION,
277
270
  });
278
- if (projectType === 1) {
279
- const { newNodeVersion } = yield inquirer.prompt({
280
- type: 'list',
281
- name: 'newNodeVersion',
282
- choices: ['12', '14', '16'],
283
- message: 'What version of Node.js would you like to use?',
284
- default: parseInt(process.versions.node, 10).toString(),
285
- });
286
- nodeVersion = newNodeVersion;
287
- }
288
- else if (projectType === 2) {
289
- const fetch = require('node-fetch');
290
- const { newNodeVersion } = yield inquirer.prompt({
291
- type: 'input',
292
- name: 'newNodeVersion',
293
- message: 'What version of Node.js would you like to use?',
294
- validate: it => fetch(`https://hub.docker.com/v2/repositories/library/node/tags/${it}-slim`).then(it => it.status === 200 || `Can't find node:${it}-slim docker image.`),
295
- default: parseFloat(process.versions.node).toString(),
296
- });
297
- nodeVersion = newNodeVersion;
298
- }
299
- return { prerender, projectType, nodeVersion, browserTarget, serverTarget, prerenderTarget };
271
+ return { prerender, projectType: 3, ssrRegion, browserTarget, serverTarget, prerenderTarget };
300
272
  }
301
- return { projectType: 0, prerender, nodeVersion, browserTarget, serverTarget, prerenderTarget };
273
+ return { projectType: 3, browserTarget, serverTarget, prerenderTarget };
302
274
  });
303
275
  exports.projectTypePrompt = projectTypePrompt;
@@ -80,39 +80,43 @@ const projectFromRc = (rc, target) => {
80
80
  return [project || defaultProject, site];
81
81
  };
82
82
  function addEnvironmentEntry(host, filePath, data) {
83
- if (!host.exists(filePath)) {
84
- throw new Error(`File ${filePath} does not exist`);
85
- }
86
- const buffer = host.read(filePath);
87
- if (!buffer) {
88
- throw new schematics_1.SchematicsException(`Cannot read ${filePath}`);
89
- }
90
- const sourceFile = typescript_1.default.createSourceFile(filePath, buffer.toString('utf-8'), typescript_1.default.ScriptTarget.Latest, true);
91
- const envIdentifier = ast_utils_1.findNode(sourceFile, typescript_1.default.SyntaxKind.Identifier, 'environment');
92
- if (!envIdentifier || !envIdentifier.parent) {
93
- throw new schematics_1.SchematicsException(`Cannot find 'environment' identifier in ${filePath}`);
94
- }
95
- const envObjectLiteral = envIdentifier.parent.getChildren().find(({ kind }) => kind === typescript_1.default.SyntaxKind.ObjectLiteralExpression);
96
- if (!envObjectLiteral) {
97
- throw new schematics_1.SchematicsException(`${filePath} is not in the expected format`);
98
- }
99
- const firebaseIdentifier = ast_utils_1.findNode(envObjectLiteral, typescript_1.default.SyntaxKind.Identifier, 'firebase');
100
- const recorder = host.beginUpdate(filePath);
101
- if (firebaseIdentifier && firebaseIdentifier.parent) {
102
- const change = new change_1.ReplaceChange(filePath, firebaseIdentifier.parent.pos, firebaseIdentifier.parent.getFullText(), data);
103
- change_1.applyToUpdateRecorder(recorder, [change]);
104
- }
105
- else {
106
- const openBracketToken = envObjectLiteral.getChildren().find(({ kind }) => kind === typescript_1.default.SyntaxKind.OpenBraceToken);
107
- if (openBracketToken) {
108
- const change = new change_1.InsertChange(filePath, openBracketToken.end, `${data},`);
83
+ const fileExists = host.exists(filePath);
84
+ if (fileExists) {
85
+ const buffer = host.read(filePath);
86
+ if (!buffer) {
87
+ throw new schematics_1.SchematicsException(`Cannot read ${filePath}`);
88
+ }
89
+ const sourceFile = typescript_1.default.createSourceFile(filePath, buffer.toString('utf-8'), typescript_1.default.ScriptTarget.Latest, true);
90
+ const envIdentifier = ast_utils_1.findNode(sourceFile, typescript_1.default.SyntaxKind.Identifier, 'environment');
91
+ if (!envIdentifier || !envIdentifier.parent) {
92
+ throw new schematics_1.SchematicsException(`Cannot find 'environment' identifier in ${filePath}`);
93
+ }
94
+ const envObjectLiteral = envIdentifier.parent.getChildren().find(({ kind }) => kind === typescript_1.default.SyntaxKind.ObjectLiteralExpression);
95
+ if (!envObjectLiteral) {
96
+ throw new schematics_1.SchematicsException(`${filePath} is not in the expected format`);
97
+ }
98
+ const firebaseIdentifier = ast_utils_1.findNode(envObjectLiteral, typescript_1.default.SyntaxKind.Identifier, 'firebase');
99
+ const recorder = host.beginUpdate(filePath);
100
+ if (firebaseIdentifier && firebaseIdentifier.parent) {
101
+ const change = new change_1.ReplaceChange(filePath, firebaseIdentifier.parent.pos, firebaseIdentifier.parent.getFullText(), data);
109
102
  change_1.applyToUpdateRecorder(recorder, [change]);
110
103
  }
111
104
  else {
112
- throw new schematics_1.SchematicsException(`${filePath} is not in the expected format`);
105
+ const openBracketToken = envObjectLiteral.getChildren().find(({ kind }) => kind === typescript_1.default.SyntaxKind.OpenBraceToken);
106
+ if (openBracketToken) {
107
+ const change = new change_1.InsertChange(filePath, openBracketToken.end, `${data},`);
108
+ change_1.applyToUpdateRecorder(recorder, [change]);
109
+ }
110
+ else {
111
+ throw new schematics_1.SchematicsException(`${filePath} is not in the expected format`);
112
+ }
113
113
  }
114
+ host.commitUpdate(recorder);
115
+ }
116
+ else {
117
+ host.create(filePath, `export const environment = {${data},
118
+ };`);
114
119
  }
115
- host.commitUpdate(recorder);
116
120
  return host;
117
121
  }
118
122
  exports.addEnvironmentEntry = addEnvironmentEntry;
@@ -1,104 +0,0 @@
1
- # Step 1: install this plugin:
2
- ```
3
- ionic cordova plugin add cordova-universal-links-plugin
4
- ionic cordova plugin add cordova-plugin-buildinfo
5
- ionic cordova plugin add cordova-plugin-browsertab
6
- ionic cordova plugin add cordova-plugin-inappbrowser
7
- (for ios)
8
- ionic cordova plugin add cordova-plugin-customurlscheme
9
- ```
10
-
11
- # Step 2: Add Firebase to your Ionic
12
-
13
- **Install Firebase to Angular project**
14
-
15
- Follow [this tutorial](https://github.com/angular/angularfire2/blob/master/docs/install-and-setup.md) to make a basic setup for your Ionic project.
16
-
17
- **To set up in an Android app**
18
-
19
- Go to [Firebase console](https://console.firebase.google.com/) then click **Add Firebase to your Android app** and follow the setup steps.
20
-
21
-
22
- # Step 3: Set up Firebase Authentication for Cordova
23
-
24
- *This is a summary from the [Firebase instructions](https://firebase.google.com/docs/auth/web/cordova).*
25
-
26
- **Setup Dynamic Link**
27
- In the Firebase console, open the **Dynamic Links** section at bottom left panel, setup by their instruction
28
-
29
- **Add dynamic link**
30
- *Add this to config.xml at root level of project:*
31
- ```xml
32
- <universal-links>
33
- <!-- this is dynamic link created in firebase -->
34
- <host name="zm4e4.app.goo.gl" scheme="https" />
35
- <!-- this is your firebase app link -->
36
- <host name="routing-aadd4.firebaseapp.com" scheme="https">
37
- <path url="/__/auth/callback" />
38
- </host>
39
- </universal-links>
40
- <!-- for android -->
41
- <preference name="AndroidLaunchMode" value="singleTask" />
42
- ```
43
-
44
- *Make sure your `<widget id="com.yourandroid.id" ... >` the same with Android app's id you
45
- added in Firebase.*
46
-
47
- # Step 4: Add login code
48
- In `login.service.ts` add this function:
49
- ```ts
50
-
51
- import { AngularFireAuth } from '@angular/fire/compat/auth';
52
- import firebase from 'firebase/app';
53
- import AuthProvider = firebase.auth.AuthProvider;
54
-
55
- export class AuthService {
56
- private user: firebase.User;
57
- constructor(public afAuth: AngularFireAuth) {
58
- afAuth.authState.subscribe(user => {
59
- this.user = user;
60
- });
61
- }
62
-
63
- signInWithFacebook() {
64
- console.log('Sign in with Facebook');
65
- return this.oauthSignIn(new firebase.auth.FacebookAuthProvider());
66
- }
67
-
68
- signInWithGoogle() {
69
- console.log('Sign in with Google');
70
- return this.oauthSignIn(new firebase.auth.GoogleAuthProvider());
71
- }
72
-
73
- private oauthSignIn(provider: AuthProvider) {
74
- if (!(<any>window).cordova) {
75
- return this.afAuth.auth.signInWithPopup(provider);
76
- } else {
77
- return this.afAuth.auth.signInWithRedirect(provider)
78
- .then(() => {
79
- return this.afAuth.auth.getRedirectResult().then( result => {
80
- // This gives you an Access Token. You can use it to access the associated APIs.
81
- let token = result.credential.accessToken;
82
- // The signed-in user info.
83
- let user = result.user;
84
- console.log(token, user);
85
- }).catch(function(error) {
86
- // Handle Errors here.
87
- alert(error.message);
88
- });
89
- });
90
- }
91
- }
92
- }
93
- ```
94
-
95
- # Common problems
96
-
97
- If you get an error, when you build the code, that looks like this:
98
- ```
99
- UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot read property 'manifest' of undefined
100
- ```
101
-
102
- Please take a look at the fix from [this issue](https://github.com/nordnet/cordova-universal-links-plugin/issues/134):
103
- > Making this change in 'cordova-universal-links-plugin/hooks/lib/android/manifestWriter.js' fixed this issue for me:
104
- > [b2c5784#diff-d5955d9f4d88b42e5efd7a3385be79e9](https://github.com/nordnet/cordova-universal-links-plugin/commit/b2c5784764225319648e26aa5d3f42ede6d1b289#diff-d5955d9f4d88b42e5efd7a3385be79e9)