import { Injectable } from '@angular/core' ; import firebase from 'firebase' ; import { BehaviorSubject , Subject } from 'rxjs' ; import { UtilService } from './util.service' ; @ Injectable ( { providedIn : 'root' } ) export class FirestoreService { private resultsSubject = new Subject < any [ ] > ( ) ; private fieldSettings = { } ; constructor ( private util ) { } fetch ( path , filter , limit , sort ? ) { this . resultsSubject = new Subject < any [ ] > ( ) ; const collection = this . getCollection ( path ) ; let query = this . applyFilter ( filter , collection ) ; if ( sort !== undefined ) { query = query . orderBy ( sort . name , sort . direction ) ; } query . limit ( limit ) . get ( ) . then ( snapshot => { const list = this . snapshotToArray ( snapshot ) ; this . resultsSubject . next ( list ) ; } , error => { console . error ( 'ON SNAPSHOT ' + error ) ; this . resultsSubject . error ( error ) ; } ) ; return this . resultsSubject . asObservable ( ) ; } add ( item , path ) { const collection = this . getCollection ( path ) ; return collection . doc ( ) . set ( item ) ; } save ( item , path ) { const collection = this . getCollection ( path ) ; return collection . doc ( item . key ) . set ( item ) ; } delete ( items , path ) { const firestore = firebase . firestore ( ) ; const collection = this . getCollection ( path ) ; const batch = firestore . batch ( ) ; for ( const item of items ) { batch . delete ( collection . doc ( item . item . key ) ) ; } return batch . commit ( ) ; } addAll ( items , path ) { const firestore = firebase . firestore ( ) ; const collection = this . getCollection ( path ) ; const batch = firestore . batch ( ) ; for ( const item of items ) { const doc = collection . doc ( ) ; batch . set ( doc , item ) ; } return batch . commit ( ) . then ( success => { } , error => { console . log ( error ) ; } ) ; } private getCollection ( path ) { const firestore = firebase . firestore ( ) ; return firestore . collection ( path ) ; } private applyFilter ( filter , collection ) { if ( Array . isArray ( filter ) ) { let chain = collection ; for ( const f of filter ) { chain = this . applyFilter ( f , chain ) ; } return chain ; } if ( filter . field !== undefined ) { let filterValue = this . util . getTrueValue ( filter . val ) ; if ( filter . isDate ) { filterValue = new Date ( filterValue ) ; } if ( filter . oper === 'eq' && ! filter . isDate ) { return collection . where ( filter . field , '==' , filterValue ) ; } else if ( filter . oper === 'ne' && ! filter . isDate ) { return collection . where ( filter . field , '!=' , filterValue ) ; } else if ( filter . oper === 'bt' || ( filter . oper === 'eq' && filter . isDate ) ) { let endValue = this . util . getTrueValue ( filter . val2 ) ; if ( filter . isDate ) { endValue = new Date ( endValue ) ; } return collection . where ( filter . field , '>=' , filterValue ) . where ( filter . field , '<=' , endValue ) ; } else if ( filter . oper === 'gt' ) { return collection . where ( filter . field , '>' , filterValue ) ; } else if ( filter . oper === 'lt' ) { return collection . where ( filter . field , '<' , filterValue ) ; } else { const op = filter . oper === '=' ? '==' : filter . oper ; return collection . where ( filter . field , op , filterValue ) ; } } else { return collection ; } } private snapshotToArray ( snapshot ) { const returnArr = [ ] ; snapshot . forEach ( doc => { const item = doc . data ( ) ; item . key = doc . id ; returnArr . push ( item ) ; } ) ; return returnArr ; } getTimestamp ( date ) { return firebase . firestore . Timestamp . fromDate ( date ) ; } }