Skip to content

Commit f1df0f4

Browse files
committed
feat: conditional firebase services
1 parent 06a680c commit f1df0f4

File tree

6 files changed

+99
-50
lines changed

6 files changed

+99
-50
lines changed

.gitignore

-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ yarn.auto-install
7474
supabase
7575

7676
# Firebase
77-
src/environments/firebaseConfig.ts
7877
firebase.json
7978
.firebase
8079
.firebaserc

packages/scripts/src/commands/index.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,12 @@ export const parseCommand = async (cmd: string) => {
5050
};
5151

5252
// Additional exports for direct consumption
53-
import { extendDeploymentConfig, generateDeploymentConfig } from "./deployment/common";
54-
export { extendDeploymentConfig, generateDeploymentConfig };
53+
import {
54+
extendDeploymentConfig,
55+
generateDeploymentConfig,
56+
loadEncryptedConfig,
57+
} from "./deployment/common";
58+
export { extendDeploymentConfig, generateDeploymentConfig, loadEncryptedConfig };
5559

5660
// Run the program directly when called via ts-node (e.g. start script)
5761
if (isTsNode) {

src/app/app.component.ts

+22-15
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,8 @@ export class AppComponent {
112112
this.hackSetDeveloperOptions();
113113
const isDeveloperMode = this.templateFieldService.getField("user_mode") === false;
114114
const user = this.userMetaService.userMeta;
115-
// Authentication requires verified domain and app ids populated to firebase console
116-
// Currently only run on native where specified (but can comment out for testing locally)
117-
if (this.appAuthenticationDefaults.enforceLogin && Capacitor.isNativePlatform()) {
118-
await this.ensureUserSignedIn();
119-
}
115+
await this.loadAuthConfig();
116+
120117
if (!user.first_app_open) {
121118
await this.userMetaService.setUserMeta({ first_app_open: new Date().toISOString() });
122119
}
@@ -143,16 +140,26 @@ export class AppComponent {
143140
});
144141
}
145142

146-
private async ensureUserSignedIn() {
147-
const authUser = await this.authService.getCurrentUser();
148-
if (!authUser) {
149-
const templatename = this.appAuthenticationDefaults.signInTemplate;
150-
const { modal } = await this.templateService.runStandaloneTemplate(templatename, {
151-
showCloseButton: false,
152-
waitForDismiss: false,
153-
});
154-
await this.authService.waitForSignInComplete();
155-
await modal.dismiss();
143+
/**
144+
* Authentication requires verified domain and app ids populated to firebase console
145+
* Currently only run on native where specified (but can comment out for testing locally)
146+
*/
147+
private async loadAuthConfig() {
148+
const { firebase } = environment.deploymentConfig;
149+
const { enforceLogin } = this.appAuthenticationDefaults;
150+
const ensureLogin = firebase.config && enforceLogin && Capacitor.isNativePlatform();
151+
if (ensureLogin) {
152+
this.authService.ready();
153+
const authUser = await this.authService.getCurrentUser();
154+
if (!authUser) {
155+
const templatename = this.appAuthenticationDefaults.signInTemplate;
156+
const { modal } = await this.templateService.runStandaloneTemplate(templatename, {
157+
showCloseButton: false,
158+
waitForDismiss: false,
159+
});
160+
await this.authService.waitForSignInComplete();
161+
await modal.dismiss();
162+
}
156163
}
157164
}
158165

src/app/app.module.ts

+55-23
Original file line numberDiff line numberDiff line change
@@ -34,31 +34,34 @@ export function lottiePlayerFactory() {
3434
return player;
3535
}
3636

37+
// Common imports
38+
const imports = [
39+
BrowserModule,
40+
BrowserAnimationsModule,
41+
IonicModule.forRoot(),
42+
AppRoutingModule,
43+
HttpClientModule,
44+
SharedModule,
45+
FormsModule,
46+
LottieModule.forRoot({ player: lottiePlayerFactory }),
47+
// NOTE CC 2021-11-04 not sure if cache causes issues or not https://github.com/ngx-lottie/ngx-lottie/issues/115
48+
// LottieCacheModule.forRoot(),
49+
TemplateComponentsModule,
50+
TourModule,
51+
MatomoModule.forRoot({
52+
siteId: environment.analytics.siteId,
53+
trackerUrl: environment.analytics.endpoint,
54+
}),
55+
MatomoRouterModule,
56+
ContextMenuModule,
57+
];
58+
59+
// Deployment-specific imports
60+
loadFirebaseImports();
61+
3762
@NgModule({
3863
declarations: [AppComponent],
39-
imports: [
40-
BrowserModule,
41-
BrowserAnimationsModule,
42-
IonicModule.forRoot(),
43-
AppRoutingModule,
44-
HttpClientModule,
45-
SharedModule,
46-
// Firebase
47-
provideFirebaseApp(() => initializeApp(environment.firebaseConfig)),
48-
provideAuth(() => getAuth()),
49-
FormsModule,
50-
LottieModule.forRoot({ player: lottiePlayerFactory }),
51-
// NOTE CC 2021-11-04 not sure if cache causes issues or not https://github.com/ngx-lottie/ngx-lottie/issues/115
52-
// LottieCacheModule.forRoot(),
53-
TemplateComponentsModule,
54-
TourModule,
55-
MatomoModule.forRoot({
56-
siteId: environment.analytics.siteId,
57-
trackerUrl: environment.analytics.endpoint,
58-
}),
59-
MatomoRouterModule,
60-
ContextMenuModule,
61-
],
64+
imports,
6265
providers: [
6366
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
6467
HTTP,
@@ -69,3 +72,32 @@ export function lottiePlayerFactory() {
6972
bootstrap: [AppComponent],
7073
})
7174
export class AppModule {}
75+
76+
/**
77+
* Configure app module imports dependent on what firebase features should be enabled
78+
*/
79+
function loadFirebaseImports() {
80+
const { firebase } = environment.deploymentConfig;
81+
82+
// Check if any services are enabled, simply return if not
83+
const enabledServices = Object.entries(firebase)
84+
.filter(([key, v]) => v && v.constructor === {}.constructor && v["enabled"])
85+
.map(([key]) => key);
86+
if (enabledServices.length === 0) return;
87+
88+
// Check config exists if services are enabled
89+
if (!firebase.config) {
90+
console.warn(`[Firebase] config missing, services disabled:\n`, enabledServices.join(", "));
91+
return;
92+
}
93+
94+
// Add main firebase initialisation import
95+
imports.push(
96+
provideFirebaseApp(() => initializeApp(environment.deploymentConfig.firebase.config))
97+
);
98+
99+
// Add feature-dependent imports
100+
if (firebase.auth.enabled) {
101+
imports.push(provideAuth(() => getAuth()));
102+
}
103+
}

src/app/shared/services/auth/auth.service.ts

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Injectable } from "@angular/core";
2-
import { Auth } from "@angular/fire/auth";
32
import { FirebaseAuthentication, User } from "@capacitor-firebase/authentication";
43
import { BehaviorSubject, firstValueFrom } from "rxjs";
54
import { filter } from "rxjs/operators";
5+
import { environment } from "src/environments/environment";
66
import { IAppConfig } from "../../model";
77
import { AppConfigService } from "../app-config/app-config.service";
88
import { SyncServiceBase } from "../syncService.base";
@@ -17,17 +17,23 @@ export class AuthService extends SyncServiceBase {
1717

1818
// include auth import to ensure app registered
1919
constructor(
20-
auth: Auth,
2120
private appConfigService: AppConfigService,
2221
private templateActionRegistry: TemplateActionRegistry
2322
) {
2423
super("Auth");
2524
this.initialise();
2625
}
2726
private initialise() {
28-
this.subscribeToAppConfigChanges();
29-
this.addAuthListeners();
30-
this.registerTemplateActionHandlers();
27+
const { firebase } = environment.deploymentConfig;
28+
if (firebase?.auth?.enabled) {
29+
if (!firebase?.config) {
30+
console.warn("[Auth Service] cannot initialise, firebase config missing");
31+
return;
32+
}
33+
this.subscribeToAppConfigChanges();
34+
this.addAuthListeners();
35+
this.registerTemplateActionHandlers();
36+
}
3137
}
3238

3339
/** Return a promise that resolves after a signed in user defined */

src/app/shared/services/error-handler/error-handler.service.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ export class ErrorHandlerService extends ErrorHandler {
2929
* (although workaround required as cannot extend multiple services)
3030
*/
3131
private async initialise() {
32-
const { production, deploymentConfig, firebaseConfig } = environment;
33-
if (production && deploymentConfig?.error_logging?.dsn) {
32+
const { production, deploymentConfig } = environment;
33+
const { error_logging, firebase } = deploymentConfig;
34+
if (production && error_logging?.dsn) {
3435
await this.initialiseSentry();
3536
this.sentryEnabled = true;
3637
}
37-
if (production && firebaseConfig?.apiKey && Capacitor.isNativePlatform()) {
38+
if (production && firebase?.config?.apiKey && Capacitor.isNativePlatform()) {
3839
// crashlytics initialised in app component so omitted here
39-
this.crashlyticsEnabled = true;
40+
this.crashlyticsEnabled = firebase.crashlytics.enabled;
4041
}
4142
this.initialised = true;
4243
}

0 commit comments

Comments
 (0)