Last active
March 11, 2022 05:57
-
-
Save NEO97online/92d1582d911a59b46ec0230734ed1fbc to your computer and use it in GitHub Desktop.
Angular Firebase Module boilerplate for AngularFire2 (using Firestore and Storage) NgModule
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { NgModule } from '@angular/core'; | |
import { AngularFireModule } from 'angularfire2'; | |
import { AngularFirestoreModule } from 'angularfire2/firestore'; | |
import { AngularFireAuthModule } from 'angularfire2/auth'; | |
import { AngularFireStorageModule } from 'angularfire2/storage'; | |
import { environment } from '../../environments/environment'; | |
import { FirestoreService } from './firestore.service'; | |
import { StorageService } from './storage.service'; | |
@NgModule({ | |
imports: [ | |
AngularFireModule.initializeApp(environment.firebaseConfig, environment.firebaseId), | |
AngularFirestoreModule, | |
AngularFireAuthModule, | |
AngularFireStorageModule, | |
], | |
exports: [ | |
AngularFireModule, | |
AngularFirestoreModule, | |
AngularFireAuthModule, | |
AngularFireStorageModule, | |
], | |
providers: [ | |
FirestoreService, StorageService | |
] | |
}) | |
export class FirebaseModule { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Injectable } from '@angular/core'; | |
import * as firebase from 'firebase/app'; | |
import { AngularFirestore, AngularFirestoreDocument, AngularFirestoreCollection } from 'angularfire2/firestore'; | |
import { Observable } from 'rxjs/Observable'; | |
import 'rxjs/add/operator/map'; | |
import 'rxjs/add/operator/do'; | |
import 'rxjs/add/operator/take'; | |
import 'rxjs/add/operator/toPromise'; | |
import 'rxjs/add/operator/switchMap'; | |
type CollectionPredicate<T> = string | AngularFirestoreCollection<T>; | |
type DocPredicate<T> = string | AngularFirestoreDocument<T>; | |
@Injectable() | |
export class FirestoreService { | |
constructor(private afs: AngularFirestore) { } | |
/// ************** | |
/// Get a Reference | |
/// ************** | |
public col<T>(ref: CollectionPredicate<T>, queryFn?): AngularFirestoreCollection<T> { | |
return typeof ref === 'string' ? this.afs.collection<T>(ref, queryFn) : ref; | |
} | |
public doc<T>(ref: DocPredicate<T>): AngularFirestoreDocument<T> { | |
return typeof ref === 'string' ? this.afs.doc<T>(ref) : ref; | |
} | |
/// ************** | |
/// Get Data | |
/// ************** | |
public doc$<T>(ref: DocPredicate<T>): Observable<T> { | |
return this.doc(ref).snapshotChanges().map(doc => { | |
return doc.payload.data() as T | |
}) | |
} | |
public col$<T>(ref: CollectionPredicate<T>, queryFn?): Observable<T[]> { | |
return this.col(ref, queryFn).snapshotChanges().map(docs => { | |
return docs.map(a => a.payload.doc.data()) as T[] | |
}); | |
} | |
/// with Ids | |
public colWithIds$<T>(ref: CollectionPredicate<T>, queryFn?): Observable<any[]> { | |
return this.col(ref, queryFn).snapshotChanges().map(actions => { | |
return actions.map(a => { | |
const data = a.payload.doc.data(); | |
const id = a.payload.doc.id; | |
return { id, ...data }; | |
}); | |
}); | |
} | |
/// ************** | |
/// Write Data | |
/// ************** | |
/// Firebase Server Timestamp | |
get timestamp() { | |
return firebase.firestore.FieldValue.serverTimestamp() | |
} | |
set<T>(ref: DocPredicate<T>, data: any) { | |
const timestamp = this.timestamp | |
return this.doc(ref).set({ | |
...data, | |
updatedAt: timestamp, | |
createdAt: timestamp | |
}) | |
} | |
update<T>(ref: DocPredicate<T>, data: any) { | |
return this.doc(ref).update({ | |
...data, | |
updatedAt: this.timestamp | |
}) | |
} | |
delete<T>(ref: DocPredicate<T>) { | |
return this.doc(ref).delete() | |
} | |
public add<T>(ref: CollectionPredicate<T>, data) { | |
const timestamp = this.timestamp | |
return this.col(ref).add({ | |
...data, | |
updatedAt: timestamp, | |
createdAt: timestamp | |
}) | |
} | |
geopoint(lat: number, lng: number) { | |
return new firebase.firestore.GeoPoint(lat, lng) | |
} | |
/// If doc exists update, otherwise set | |
upsert<T>(ref: DocPredicate<T>, data: any) { | |
const doc = this.doc(ref).snapshotChanges().take(1).toPromise() | |
return doc.then(snap => { | |
return snap.payload.exists ? this.update(ref, data) : this.set(ref, data) | |
}) | |
} | |
/// ************** | |
/// Inspect Data | |
/// ************** | |
inspectDoc(ref: DocPredicate<any>): void { | |
const tick = new Date().getTime() | |
this.doc(ref).snapshotChanges() | |
.take(1) | |
.do(d => { | |
const tock = new Date().getTime() - tick | |
console.log(`Loaded Document in ${tock}ms`, d) | |
}) | |
.subscribe() | |
} | |
inspectCol(ref: CollectionPredicate<any>): void { | |
const tick = new Date().getTime() | |
this.col(ref).snapshotChanges() | |
.take(1) | |
.do(c => { | |
const tock = new Date().getTime() - tick | |
console.log(`Loaded Collection in ${tock}ms`, c) | |
}) | |
.subscribe() | |
} | |
/// ************** | |
/// Create and read doc references | |
/// ************** | |
/// create a reference between two documents | |
connect(host: DocPredicate<any>, key: string, doc: DocPredicate<any>) { | |
return this.doc(host).update({ [key]: this.doc(doc).ref }) | |
} | |
/// returns a documents references mapped to AngularFirestoreDocument | |
docWithRefs$<T>(ref: DocPredicate<T>) { | |
return this.doc$(ref).map(doc => { | |
for (const k of Object.keys(doc)) { | |
if (doc[k] instanceof firebase.firestore.DocumentReference) { | |
doc[k] = this.doc(doc[k].path) | |
} | |
} | |
return doc | |
}) | |
} | |
/// ************** | |
/// Atomic batch example | |
/// ************** | |
/// Just an example, you will need to customize this method. | |
atomic() { | |
const batch = firebase.firestore().batch() | |
/// add your operations here | |
const itemDoc = firebase.firestore().doc('items/myCoolItem'); | |
const userDoc = firebase.firestore().doc('users/userId'); | |
const currentTime = this.timestamp | |
batch.update(itemDoc, { timestamp: currentTime }); | |
batch.update(userDoc, { timestamp: currentTime }); | |
/// commit operations | |
return batch.commit() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Injectable } from '@angular/core'; | |
import { AngularFireAuth } from 'angularfire2/auth'; | |
import { AngularFirestore } from 'angularfire2/firestore'; | |
import { AngularFireStorage } from 'angularfire2/storage'; | |
@Injectable() | |
export class StorageService { | |
constructor(public afAuth: AngularFireAuth, public afs: AngularFirestore, public afStore: AngularFireStorage) { } | |
// Uploads a file to the given path. End the path with an asterisk (*) to use the file's name. | |
// eg: uploadFile('myfiles/pictures/*', myFile) | |
uploadFile(path: string, fileObj: File) { | |
path = path && path.length > 0 && !path.endsWith('*') ? path : fileObj.name; | |
return this.afStore.ref(path).put(fileObj); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment