Skip to content

Commit

Permalink
use firestore offline cache
Browse files Browse the repository at this point in the history
  • Loading branch information
ortwic committed Mar 26, 2024
1 parent 7f63f72 commit 8ed6f37
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 41 deletions.
18 changes: 15 additions & 3 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
"maximumError": "2mb"
},
{
"type": "anyComponentStyle",
Expand All @@ -66,14 +66,26 @@
"development": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true
"sourceMap": true,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.development.ts"
}
]
},
"dev-spa": {
"optimization": false,
"extractLicenses": false,
"sourceMap": true,
"ssr": false,
"prerender": false
"prerender": false,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.dev-spa.ts"
}
]
}
},
"defaultConfiguration": "production"
Expand Down
64 changes: 37 additions & 27 deletions src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,47 @@ import { provideRouter } from '@angular/router';
import { provideClientHydration } from '@angular/platform-browser';
import { provideServiceWorker } from '@angular/service-worker';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { initializeApp, provideFirebaseApp } from '@angular/fire/app';
import { getApp, initializeApp, provideFirebaseApp } from '@angular/fire/app';
import { getAuth, provideAuth } from '@angular/fire/auth';
// import { getAnalytics, provideAnalytics, ScreenTrackingService, UserTrackingService } from '@angular/fire/analytics';
import { getFirestore, provideFirestore } from '@angular/fire/firestore';
import { initializeFirestore, persistentLocalCache, persistentMultipleTabManager, provideFirestore } from '@angular/fire/firestore';
// import { getStorage, provideStorage } from '@angular/fire/storage';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideClientHydration(),
provideServiceWorker('ngsw-worker.js', {
enabled: !isDevMode(),
registrationStrategy: 'registerWhenStable:30000'
}),
provideAnimationsAsync(),
importProvidersFrom(provideFirebaseApp(() => initializeApp({
"projectId": "why-app-8a640",
"appId": "1:421607989972:web:94f09c89b215baaf3f1141",
"storageBucket": "why-app-8a640.appspot.com",
// "locationId":"europe-west",
"apiKey": "AIzaSyC4pJvHQFG4btucEzsw77uVT4HHovK7Nmg",
"authDomain": "why-app-8a640.firebaseapp.com",
"messagingSenderId": "421607989972",
"measurementId": "G-1MPCGHPTJ5"
}))),
importProvidersFrom(provideAuth(() => getAuth())),
// importProvidersFrom(provideAnalytics(() => getAnalytics())),
// ScreenTrackingService,
// UserTrackingService,
importProvidersFrom(provideFirestore(() => getFirestore())),
// importProvidersFrom(provideStorage(() => getStorage())),
]
providers: [
provideRouter(routes),
provideClientHydration(),
provideServiceWorker('ngsw-worker.js', {
enabled: !isDevMode(),
registrationStrategy: 'registerWhenStable:30000',
}),
provideAnimationsAsync(),
importProvidersFrom(
provideFirebaseApp(() =>
initializeApp({
projectId: 'why-app-8a640',
appId: '1:421607989972:web:94f09c89b215baaf3f1141',
storageBucket: 'why-app-8a640.appspot.com',
// "locationId":"europe-west",
apiKey: 'AIzaSyC4pJvHQFG4btucEzsw77uVT4HHovK7Nmg',
authDomain: 'why-app-8a640.firebaseapp.com',
messagingSenderId: '421607989972',
measurementId: 'G-1MPCGHPTJ5',
})
),
provideAuth(() => getAuth()),
// provideAnalytics(() => getAnalytics()),
provideFirestore(() =>
initializeFirestore(getApp(), {
localCache: persistentLocalCache({
tabManager: persistentMultipleTabManager(),
}),
})
)
// provideStorage(() => getStorage()),
),
// ScreenTrackingService,
// UserTrackingService,
],
};
36 changes: 25 additions & 11 deletions src/app/services/firestore.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Injectable, inject } from '@angular/core';
import { Injectable, inject, isDevMode } from '@angular/core';
import {
Firestore,
collection,
Expand All @@ -15,9 +15,11 @@ import {
CollectionReference,
DocumentData,
DocumentReference,
Query,
QueryConstraint,
QueryDocumentSnapshot,
SnapshotOptions,
onSnapshot,
} from '@angular/fire/firestore';
import { startWith } from 'rxjs/operators';
import type { Observable } from 'rxjs';
Expand Down Expand Up @@ -47,28 +49,40 @@ export abstract class FirestoreService {
constructor(private path: string) { }

public getDocumentStream<T extends DocumentData>(...constraints: QueryConstraint[]): Observable<T[]> {
const items = this.getCollection<T>();

const q = query<T, DocumentData>(items, ...constraints);
return collectionData<T>(q, { idField: 'id' }).pipe(startWith([]));
const query = this.createQuery<T>(...constraints);
return collectionData<T>(query, { idField: 'id' }).pipe(startWith([]));
}

public async getDocuments<T extends DocumentData>(...constraints: QueryConstraint[]): Promise<T[]> {
const items = this.getCollection<T>();

const q = query<T, DocumentData>(items, ...constraints);
return getDocs<T, DocumentData>(q).then((snapshot) => {
const query = this.createQuery<T>(...constraints);
return getDocs<T, DocumentData>(query).then((snapshot) => {
const result: T[] = [];
snapshot.forEach((doc) => result.push(doc.data(snapshotOptions)));
return result;
});
}

private getCollection<T extends DocumentData>(): CollectionReference<T, DocumentData> {
return collection(this.store, this.path).withConverter({
private createQuery<T extends DocumentData>(...constraints: QueryConstraint[]): Query<T, DocumentData> {
const items = collection(this.store, this.path).withConverter({
toFirestore: this.toFirestore,
fromFirestore: this.fromFirestore
}) as CollectionReference<T>;

const q = query<T, DocumentData>(items, ...constraints);

if(isDevMode()) {
onSnapshot(q, { includeMetadataChanges: true }, (snapshot) => {
const source = snapshot.metadata.fromCache ? "local cache" : "server";
console.info("Data queried from", source);
console.debug(snapshot.docChanges()
.filter((change) => change.type === "added")
.map((change) => (change.doc.data()))
.map((data) => data['title'] ?? data['id'] ?? data)
);
});
}

return q;
}

protected toFirestore<T>(modelObject: T) {
Expand Down

0 comments on commit 8ed6f37

Please sign in to comment.