@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.
- package/README.md +86 -71
- package/bundles/angular-fire.umd.js +1 -1
- package/bundles/angular-fire.umd.js.map +1 -1
- package/compat/firestore/interfaces.d.ts +4 -4
- package/docs/analytics.md +67 -0
- package/docs/app-check.md +53 -0
- package/docs/auth.md +165 -0
- package/docs/{analytics → compat/analytics}/getting-started.md +2 -0
- package/docs/{auth → compat/auth}/getting-started.md +2 -0
- package/docs/{auth → compat/auth}/router-guards.md +2 -0
- package/docs/{emulators → compat/emulators}/emulators.md +2 -0
- package/docs/{firestore → compat/firestore}/collections.md +2 -0
- package/docs/{firestore → compat/firestore}/documents.md +2 -0
- package/docs/{firestore → compat/firestore}/offline-data.md +2 -0
- package/docs/{firestore → compat/firestore}/querying-collections.md +2 -0
- package/docs/{functions → compat/functions}/functions.md +2 -0
- package/docs/{messaging → compat/messaging}/messaging.md +2 -0
- package/docs/{performance → compat/performance}/getting-started.md +2 -0
- package/docs/{remote-config → compat/remote-config}/getting-started.md +2 -0
- package/docs/{rtdb → compat/rtdb}/lists.md +2 -0
- package/docs/{rtdb → compat/rtdb}/objects.md +2 -0
- package/docs/{rtdb → compat/rtdb}/querying-lists.md +2 -0
- package/docs/{storage → compat/storage}/storage.md +2 -0
- package/docs/compat.md +70 -0
- package/docs/database.md +175 -0
- package/docs/firestore.md +148 -0
- package/docs/functions.md +52 -0
- package/docs/images/analytics-illo_1x.png +0 -0
- package/docs/images/auth-illo_1x.png +0 -0
- package/docs/images/cloud-messaging-illo_1x.png +0 -0
- package/docs/images/database-illo_1x.png +0 -0
- package/docs/images/firestore-illo_1x.png +0 -0
- package/docs/images/functions-illo_1x.png +0 -0
- package/docs/images/hosting-illo_1x.png +0 -0
- package/docs/images/performance-illo_1x.png +0 -0
- package/docs/images/reCAPTCHA-logo@1x.png +0 -0
- package/docs/images/remote-config-illo_1x.png +0 -0
- package/docs/images/storage-illo_1x.png +0 -0
- package/docs/install-and-setup.md +39 -86
- package/docs/messaging.md +25 -0
- package/docs/performance.md +57 -0
- package/docs/remote-config.md +53 -0
- package/docs/storage.md +90 -0
- package/esm2015/compat/firestore/interfaces.js +1 -1
- package/esm2015/core.js +1 -1
- package/fesm2015/angular-fire.js +1 -1
- package/fesm2015/angular-fire.js.map +1 -1
- package/package.json +9 -10
- package/schematics/deploy/actions.js +23 -14
- package/schematics/deploy/builder.js +2 -2
- package/schematics/firebaseTools.js +4 -2
- package/schematics/setup/index.js +58 -29
- package/schematics/setup/prompts.js +18 -46
- package/schematics/utils.js +32 -28
- package/docs/ionic/authentication.md +0 -104
- package/docs/ionic/cli.md +0 -218
- package/docs/ionic/v2.md +0 -531
- package/docs/ionic/v3.md +0 -705
- package/schematics/setup/ssr.js +0 -100
- 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
|
-
|
|
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 (
|
|
323
|
-
|
|
324
|
-
|
|
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 (
|
|
328
|
-
|
|
330
|
+
if (prerenderBuildTarget) {
|
|
331
|
+
const run = yield context.scheduleTarget(architect_1.targetFromTargetString(prerenderBuildTarget.name), prerenderBuildTarget.options);
|
|
332
|
+
yield run.result;
|
|
329
333
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
builders
|
|
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
|
|
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
|
|
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
|
|
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', '
|
|
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:
|
|
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
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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 = {
|
|
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
|
|
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
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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: '
|
|
274
|
-
choices,
|
|
275
|
-
message: '
|
|
276
|
-
default:
|
|
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
|
-
|
|
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:
|
|
273
|
+
return { projectType: 3, browserTarget, serverTarget, prerenderTarget };
|
|
302
274
|
});
|
|
303
275
|
exports.projectTypePrompt = projectTypePrompt;
|
package/schematics/utils.js
CHANGED
|
@@ -80,39 +80,43 @@ const projectFromRc = (rc, target) => {
|
|
|
80
80
|
return [project || defaultProject, site];
|
|
81
81
|
};
|
|
82
82
|
function addEnvironmentEntry(host, filePath, data) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
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)
|