{"version":3,"file":"firestore-extended.mjs","sources":["../../../projects/firestore-extended/src/lib/helpers.ts","../../../projects/firestore-extended/src/lib/drag-utils.ts","../../../projects/firestore-extended/src/lib/firestore-extended.ts","../../../projects/firestore-extended/src/lib/sub-collection-query.ts","../../../projects/firestore-extended/src/lib/rxjs-ops/combine-latest-to-object.ts","../../../projects/firestore-extended/src/lib/firestore-wrapper.ts","../../../projects/firestore-extended/src/lib/firestore-extended.class.ts","../../../projects/firestore-extended/src/lib/ngx/config.ts","../../../projects/firestore-extended/src/lib/ngx/ngx-firebase.module.ts","../../../projects/firestore-extended/src/lib/ngx/ngx-firebase.service.ts","../../../projects/firestore-extended/src/lib/ngx/ngx-firestore-ext.service.ts","../../../projects/firestore-extended/src/public-api.ts","../../../projects/firestore-extended/src/firestore-extended.ts"],"sourcesContent":["import {\r\n  Bytes,\r\n  collection,\r\n  CollectionReference,\r\n  doc,\r\n  DocumentData,\r\n  DocumentReference,\r\n  Firestore,\r\n  GeoPoint,\r\n  Timestamp as FirebaseTimestamp\r\n} from 'firebase/firestore';\r\nimport {ItemWithDates} from './models/fireItem';\r\n\r\n/** Helper method to get reference from path, the path can be either to a Document or Collection */\r\nexport function getRefFromPath<A>(path: string, firestore: Firestore): DocumentReference<A> | CollectionReference<A> {\r\n  const pathSegmentAmount: number = path.split('/').length;\r\n  if (pathSegmentAmount % 2 === 0) { // even number means doc\r\n    return doc(firestore, path) as DocumentReference<A>;\r\n  } else { // odd meaning collection\r\n    return collection(firestore, path) as CollectionReference<A>;\r\n  }\r\n}\r\n\r\nexport function getSubCollection<T extends DocumentData, A extends DocumentData>(docRef: DocumentReference<T>,\r\n                                                                                 collectionName: string): CollectionReference<A> {\r\n  const collectionPath: string = docRef.path.concat('/', collectionName);\r\n  return collection(docRef.firestore, collectionPath) as CollectionReference<A>;\r\n}\r\n\r\nexport function getDocRefWithId<T extends DocumentData>(collectionRef: CollectionReference<T>, id: string): DocumentReference<T> {\r\n  return doc(collectionRef.firestore, collectionRef.path, id) as DocumentReference<T>;\r\n}\r\n\r\n/**\r\n * Add data to object inplace\r\n * @param item item to add to\r\n * @param dataToAdd data to add\r\n * @param inplace if true the data is added inplace, if false a copy is used\r\n */\r\nexport function addDataToItem<A extends { [field: string]: any }>(\r\n  item: A, dataToAdd: { [field: string]: any }, inplace = false): A {\r\n\r\n  if (inplace) {\r\n    Object.entries(dataToAdd).forEach(([k, v]) => {\r\n      (item as { [field: string]: any })[k] = v;\r\n    });\r\n    return item;\r\n  } else {\r\n    return {...item, ...dataToAdd};\r\n  }\r\n}\r\n\r\n/**\r\n * Add createdDate to the object inplace, if createdDate already exists then we do not overwrite it\r\n *\r\n * @param item item where the createdData will be added\r\n * @param createdDate optional, will use new Date() if none given\r\n * @param inplace if true the data is added inplace, if false a copy is used\r\n */\r\nexport function addCreatedDate<A>(item: A, inplace = false, createdDate: Date = new Date()): A {\r\n  // do not overwrite previous createdDate\r\n  if ('createdDate' in item) {\r\n    return item;\r\n  }\r\n\r\n  return addDataToItem(item, {createdDate}, inplace);\r\n}\r\n\r\n/**\r\n * Add modifiedDate to the object\r\n *\r\n * @param item item where the modifiedDate will be added\r\n * @param modifiedDate optional, will use new Date() if none given\r\n * @param inplace if true the data is added inplace, if false a copy is used\r\n */\r\nexport function addModifiedDate<A>(item: A, inplace = false, modifiedDate: Date = new Date()): A {\r\n  return addDataToItem(item, {modifiedDate}, inplace);\r\n}\r\n\r\n/**\r\n * Add createdBy to the object inplace\r\n *\r\n * @param item item to add to\r\n * @param createdBy profile, user or any type of data\r\n * @param inplace if true the data is added inplace, if false a copy is used\r\n */\r\nexport function addCreatedBy<A>(item: A, createdBy: { [field: string]: any }, inplace = false): A {\r\n\r\n  return addDataToItem(item, {createdBy}, inplace);\r\n}\r\n\r\n\r\n/**\r\n * Firestore saves time as timestamps and javascript uses Date objects.\r\n * This functions helps convert the createdDate and modifiedDate from timestamp\r\n * to Date()\r\n *\r\n * inplace\r\n *\r\n * @param item item that contains 'createdDate' and/or 'modifiedDate'\r\n */\r\n\r\nexport function convertTimestampToDate<T extends Partial<ItemWithDates>>(item: T): T {\r\n  if (item.hasOwnProperty('createdDate')) {\r\n    item.createdDate = item.createdDate as FirebaseTimestamp;\r\n    item.createdDate = item.createdDate.toDate();\r\n  }\r\n  if (item.hasOwnProperty('modifiedDate')) {\r\n    item.modifiedDate = item.modifiedDate as FirebaseTimestamp;\r\n    item.modifiedDate = item.modifiedDate.toDate();\r\n  }\r\n\r\n  return item;\r\n}\r\n\r\n\r\n/**\r\n * !!!! Allows for Deep Omit...its basically magic\r\n * Taken from https://stackoverflow.com/questions/55539387/deep-omit-with-typescript\r\n */\r\n\r\n\r\n/** Union of primitives to skip with deep omit utilities. */\r\n// tslint:disable-next-line:ban-types\r\nexport type Primitive = string | Function | number | boolean | Symbol | undefined | null;\r\nexport type FirestoreAllowedPrimitives =\r\n  string\r\n  | number\r\n  | boolean\r\n  | undefined\r\n  | null\r\n  | FirebaseTimestamp\r\n  | Date\r\n  | DocumentReference\r\n  | GeoPoint\r\n  | Bytes;\r\n\r\n/* Allowed Firestore types */\r\nexport type FirestoreAllowedTypes =\r\n  FirestoreAllowedPrimitives\r\n  | Map<FirestoreAllowedPrimitives, FirestoreAllowedPrimitives>\r\n  | Array<FirestoreAllowedPrimitives>;\r\n\r\n/** Deeply omit members of an array of interface or array of type. */\r\nexport type DeepOmitArray<T extends any[], K> = {\r\n  [P in keyof T]: DeepOmit<T[P], K>\r\n};\r\n\r\n\r\nexport type DeepOmit<T, K> = T extends Primitive\r\n  ? T\r\n  : {\r\n    [P in Exclude<keyof T, K>]: T[P] extends infer TP\r\n      ? TP extends Primitive\r\n        ? TP // leave primitives and functions alone\r\n        : TP extends any[]\r\n          ? DeepOmitArray<TP, K> // Array special handling\r\n          : DeepOmit<TP, K>\r\n      : never;\r\n  };\r\n\r\n\r\n/** Deeply omit members of an array of interface or array of type, making all members optional. */\r\nexport type PartialDeepOmitArray<T extends any[], K> = Partial<{\r\n  [P in Partial<keyof T>]: Partial<PartialDeepOmit<T[P], K>>\r\n}>;\r\n\r\n/** Deeply omit members of an interface or type, making all members optional. */\r\nexport type PartialDeepOmit<T, K> = T extends Primitive ? T : Partial<{\r\n  [P in Exclude<keyof T, K>]: // extra level of indirection needed to trigger homomorhic behavior\r\n  T[P] extends infer TP ? // distribute over unions\r\n    TP extends Primitive ? TP : // leave primitives and functions alone\r\n      TP extends any[] ? PartialDeepOmitArray<TP, K> : // Array special handling\r\n        Partial<PartialDeepOmit<TP, K>>\r\n    : never\r\n}>;\r\n","/**\r\n * @license\r\n * Copyright Google LLC All Rights Reserved.\r\n *\r\n * Use of this source code is governed by an MIT-style license that can be\r\n * found in the LICENSE file at https://angular.io/license\r\n */\r\n\r\n/**\r\n * Moves an item one index in an array to another.\r\n * @param array Array in which to move the item.\r\n * @param fromIndex Starting index of the item.\r\n * @param toIndex Index to which the item should be moved.\r\n */\r\nexport function moveItemInArray<T = any>(array: T[], fromIndex: number, toIndex: number): void {\r\n  const from = clamp(fromIndex, array.length - 1);\r\n  const to = clamp(toIndex, array.length - 1);\r\n\r\n  if (from === to) {\r\n    return;\r\n  }\r\n\r\n  const target = array[from];\r\n  const delta = to < from ? -1 : 1;\r\n\r\n  for (let i = from; i !== to; i += delta) {\r\n    array[i] = array[i + delta];\r\n  }\r\n\r\n  array[to] = target;\r\n}\r\n\r\n\r\n/**\r\n * Moves an item from one array to another.\r\n * @param currentArray Array from which to transfer the item.\r\n * @param targetArray Array into which to put the item.\r\n * @param currentIndex Index of the item in its current array.\r\n * @param targetIndex Index at which to insert the item.\r\n */\r\nexport function transferArrayItem<T = any>(currentArray: T[],\r\n                                           targetArray: T[],\r\n                                           currentIndex: number,\r\n                                           targetIndex: number): void {\r\n  const from = clamp(currentIndex, currentArray.length - 1);\r\n  const to = clamp(targetIndex, targetArray.length);\r\n\r\n  if (currentArray.length) {\r\n    targetArray.splice(to, 0, currentArray.splice(from, 1)[0]);\r\n  }\r\n}\r\n\r\n/**\r\n * Copies an item from one array to another, leaving it in its\r\n * original position in current array.\r\n * @param currentArray Array from which to copy the item.\r\n * @param targetArray Array into which is copy the item.\r\n * @param currentIndex Index of the item in its current array.\r\n * @param targetIndex Index at which to insert the item.\r\n *\r\n */\r\nexport function copyArrayItem<T = any>(currentArray: T[],\r\n                                       targetArray: T[],\r\n                                       currentIndex: number,\r\n                                       targetIndex: number): void {\r\n  const to = clamp(targetIndex, targetArray.length);\r\n\r\n  if (currentArray.length) {\r\n    targetArray.splice(to, 0, currentArray[currentIndex]);\r\n  }\r\n}\r\n\r\n/** Clamps a number between zero and a maximum. */\r\nfunction clamp(value: number, max: number): number {\r\n  return Math.max(0, Math.min(max, value));\r\n}\r\n","import {combineLatest, forkJoin, from, Observable, of} from 'rxjs';\r\n\r\nimport {catchError, filter, map, mergeMap, switchMap, take, tap} from 'rxjs/operators';\r\nimport {\r\n  collection,\r\n  CollectionReference,\r\n  DocumentData,\r\n  DocumentReference,\r\n  DocumentSnapshot,\r\n  endAt,\r\n  endBefore,\r\n  FieldPath,\r\n  Firestore,\r\n  getDocs,\r\n  limit,\r\n  limitToLast,\r\n  orderBy,\r\n  OrderByDirection,\r\n  query,\r\n  Query,\r\n  QueryConstraint,\r\n  QuerySnapshot,\r\n  startAfter,\r\n  startAt,\r\n  UpdateData,\r\n  where,\r\n  WhereFilterOp,\r\n  writeBatch,\r\n  WriteBatch\r\n} from 'firebase/firestore';\r\n\r\nimport {\r\n  addCreatedDate,\r\n  addDataToItem,\r\n  addModifiedDate,\r\n  convertTimestampToDate,\r\n  getDocRefWithId,\r\n  getRefFromPath,\r\n  getSubCollection\r\n} from './helpers';\r\nimport {SubCollectionQuery} from './sub-collection-query';\r\nimport {BaseFirestoreWrapper, FirestoreErrorExt} from './interfaces';\r\nimport {FireItem, FirestoreMetadata, ItemWithIndex, ItemWithIndexGroup} from './models/fireItem';\r\nimport {SubCollectionWriter} from './sub-collection-writer';\r\nimport {moveItemInArray, transferArrayItem} from './drag-utils';\r\n\r\n/**\r\n * Action to be taken by listener if the document does not exist.\r\n */\r\nexport enum DocNotExistAction {\r\n  /** returns a null object */\r\n  RETURN_NULL,\r\n\r\n  /** return all the extras such as ref, path and so on but no data, kinda just ignores that the doc isn't there */\r\n  RETURN_ALL_BUT_DATA,\r\n\r\n  /** do not return at all until it does exist */\r\n  FILTER,\r\n\r\n  /** return doc not found error 'doc_not_found' */\r\n  THROW_DOC_NOT_FOUND,\r\n}\r\n\r\n/** Used internally */\r\ninterface CurrentDocSubCollectionSplit {\r\n  /** contains the document that is considered the current */\r\n  currentDoc: FireItem;\r\n  /** sub collections of current document */\r\n  subCollections: { [index: string]: any };\r\n}\r\n\r\n\r\n/**\r\n * Main Class.\r\n *\r\n *\r\n *\r\n */\r\nexport class FirestoreExtended {\r\n\r\n  /**\r\n   * Constructor for AngularFirestoreWrapper\r\n   *\r\n   * @param fs Firestore wrapper Firestore extended can be used by many Firestore implementations\r\n   * @param defaultDocId The default name given to a subCollection document when no name is given\r\n   */\r\n  constructor(private fs: BaseFirestoreWrapper, public defaultDocId: string = 'data') {\r\n  }\r\n\r\n  get firestore(): Firestore {\r\n    return this.fs.firestore;\r\n  }\r\n\r\n  /* ----------  LISTEN -------------- */\r\n\r\n  /**\r\n   *\r\n   * Allows for listening to documents and collections n deep up to the firestore max of 100 levels.\r\n   *\r\n   * Triggers for any change in any document that is listened to.\r\n   *\r\n   *\r\n   * E.x:\r\n   *      const subCollectionQueries: SubCollectionQuery[] = [\r\n   *         { name: 'data' },\r\n   *         { name: 'secure' },\r\n   *         { name: 'variants' },\r\n   *         { name: 'images',\r\n   *           queryFn: ref => ref.orderBy('index'),\r\n   *           collectionWithNames: [\r\n   *             { name: 'secure'}\r\n   *           ]\r\n   *         },\r\n   *     ];\r\n   *\r\n   *     this.listenForDocAndSubCollections<Product>(docFs, collections)\r\n   *\r\n   * Wrapper for listenForDocDeepRecursiveHelper$ so that we can cast the return to the correct type\r\n   * All logic is in listenForDocDeepRecursiveHelper$.\r\n   *\r\n   * @param docRef - a docRef with potential queryFn\r\n   * @param subCollectionQueries - see example\r\n   * @param actionIfNotExist Action to take if document does not exist\r\n   */\r\n  public listenForDoc$<T extends DocumentData>(\r\n    docRef: DocumentReference<T>,\r\n    subCollectionQueries: SubCollectionQuery[] = [],\r\n    actionIfNotExist: DocNotExistAction = DocNotExistAction.RETURN_ALL_BUT_DATA): Observable<FireItem<T>> {\r\n\r\n    return this.listenForDocDeepRecursiveHelper$(docRef, subCollectionQueries, actionIfNotExist).pipe(\r\n      map(data => data as FireItem<T>)\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Same as AngularFirestoreCollection.snapshotChanges but it adds the properties in FirebaseDbItem.\r\n   *\r\n   * Important to understand this is will trigger for every change/update on any of the documents we are listening to.\r\n   * That means that if any document we are listening to is changed the entire object will be triggered containing the updated data.\r\n   *\r\n   *\r\n   *    Example usage.\r\n   *\r\n   *    ngFirestoreDeep: RxFirestoreExtended;  //  RxFirestoreExtended variable\r\n   *    restaurantCollectionFs = this.ngFireStore.collection('restaurants'); // AngularFirestoreCollectionRef to restaurants\r\n   *\r\n   *    constructor(private ngFireStore: AngularFirestore) {\r\n   *        this.ngFirestoreDeep = new RxFirestoreExtended(ngFireStore);  //  initialize AngularFireStoreDeep with AngularFirestore\r\n   *    }\r\n   *\r\n   *    listenForRestaurants$(): Observable<RestaurantItem[]> {\r\n   *        return this.ngFirestoreDeep.listenForCollection$<RestaurantItem>(this.restaurantCollectionFs);\r\n   *    }\r\n   *\r\n   *    If you do not wish to listen for changes and only care about getting the values once\r\n   *\r\n   *    getRestaurants$(): Observable<RestaurantItem[]> {\r\n   *        return this.ngFirestoreDeep.listenForCollection$<RestaurantItem>(this.restaurantCollectionFs).pipe(\r\n   *          take(1)\r\n   *        );\r\n   *    }\r\n   *\r\n   * @param _query the collectionRef which will be listened to\r\n   * @param subCollectionQueries\r\n   * @param documentChangeTypes list of DocumentChangeType that will be listened to, if null listen to all\r\n   */\r\n  public listenForCollection$<T extends DocumentData>(\r\n    _query: Query<T>,\r\n    subCollectionQueries: SubCollectionQuery[] = []): Observable<Array<FireItem<T>>> {\r\n    /**\r\n     * Returns an observable that will emit whenever the ref changes in any way.\r\n     * Also adds the id and ref to the object.\r\n     */\r\n    return this.listenForCollectionSimple$<T>(_query).pipe(\r\n      mergeMap((items: FireItem<T>[]) => {\r\n\r\n        if (items == null || items.length === 0) {\r\n          return of([]);\r\n        }\r\n        if (subCollectionQueries.length <= 0) {\r\n          return of(items);\r\n        }\r\n\r\n        const collectionListeners: Array<Observable<any>> = [];\r\n\r\n        items.forEach((item: FireItem<T>) => {\r\n\r\n          const collectionListener = this.listenForCollectionsDeep<T>(item, subCollectionQueries);\r\n\r\n          collectionListeners.push(collectionListener);\r\n        });\r\n\r\n        /* Finally return the combined collection listeners */\r\n        return combineLatest(collectionListeners);\r\n      })\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Listens for collections inside collections with the same name to an unlimited depth and returns all of it as an array.\r\n   */\r\n  public listenForCollectionRecursively$<T extends DocumentData>(\r\n    collectionPath: string,\r\n    collectionKey: string,\r\n    orderKey?: string): Observable<any> {\r\n\r\n    // const collectionRef = getRefFromPath(collectionPath, this.fs.firestore) as CollectionReference<T>;\r\n    const collectionQuery = new QueryContainer<T>(getRefFromPath(collectionPath, this.fs.firestore) as CollectionReference<T>);\r\n    if (orderKey != null) {\r\n      collectionQuery.orderBy(orderKey);\r\n    }\r\n\r\n    return this.listenForCollectionSimple$<T>(collectionQuery.query).pipe(\r\n      mergeMap((items: FireItem<T>[]) => {\r\n\r\n        if (items.length <= 0) {\r\n          return of([]);\r\n        } // TODO  perhaps make this throw an error so that we can skip it\r\n\r\n        // if (items.length <= 0) { throwError('No more '); }\r\n\r\n        const nextLevelObs: Array<Observable<FireItem<T>>> = [];\r\n\r\n        for (const item of items) {\r\n\r\n          // const nextLevelPath = item.firestoreMetadata.ref.collection(collectionKey).path;  // one level deeper\r\n          const nextLevelPath = item.firestoreMetadata.ref.path.concat('/', collectionKey);  // one level deeper\r\n\r\n          const nextLevelItems$ = this.listenForCollectionRecursively$(nextLevelPath, collectionKey, orderKey).pipe(\r\n            map((nextLevelItems: Array<FireItem<T>>) => {\r\n              if (nextLevelItems.length > 0) {\r\n                return {...item, [collectionKey]: nextLevelItems} as FireItem<T>;\r\n              } else {\r\n                return {...item} as FireItem<T>;\r\n              }  // dont include an empty array\r\n            }),\r\n          );\r\n          nextLevelObs.push(nextLevelItems$);\r\n        }\r\n\r\n        return combineLatest(nextLevelObs).pipe(\r\n          tap(val => console.log(val))\r\n        );\r\n      }),\r\n    );\r\n  }\r\n\r\n  /* ---------- ADD -------------- */\r\n\r\n  /**\r\n   * Add document to firestore and split it up into sub collection.\r\n   *\r\n   * @param data the data to be saved\r\n   * @param collectionRef CollectionReference reference to where on firestore the item should be saved\r\n   * @param subCollectionWriters see documentation for SubCollectionWriter for more details on how these are used\r\n   * @param isAddDates if true 'createdDate' and 'modifiedDate' is added to the data\r\n   * @param docId If a docId is given it will use that specific id when saving the doc, if no docId is given a random id will be used.\r\n   */\r\n  public add$<T extends DocumentData>(\r\n    data: T,\r\n    collectionRef: CollectionReference<T>,\r\n    subCollectionWriters: SubCollectionWriter[] = [],\r\n    // isAddDates: boolean = true,\r\n    docId?: string): Observable<FireItem<T>> {\r\n\r\n    if (Array.isArray(data) && docId && subCollectionWriters.length > 0) {\r\n      const error: FirestoreErrorExt = {\r\n        name: 'firestoreExt/invalid-sub-collection-writers',\r\n        code: 'unknown',\r\n        message: 'Cannot have both docId and subCollectionWriters at the same time when data is an array',\r\n        stack: '',\r\n        data,\r\n        subCollectionWriters,\r\n        docId\r\n      };\r\n\r\n      throw error;\r\n    }\r\n\r\n\r\n    let currentDoc;\r\n    let subCollections: { [index: string]: any; } = {};\r\n\r\n    /* if the data is an array and a docId is given the entire array will be saved in a single document with that docId,\r\n    * Each item in the array will be saved as a map with the key being the array index\r\n    * We still want the return value of this function to be as an array non as a map\r\n    */\r\n    if (Array.isArray(data) && docId) {\r\n      currentDoc = data;\r\n    } else {\r\n      const split = this.splitDataIntoCurrentDocAndSubCollections(data, subCollectionWriters);\r\n      currentDoc = split.currentDoc;\r\n      subCollections = split.subCollections;\r\n    }\r\n\r\n    return this.addSimple$<T>(currentDoc as T, collectionRef, docId).pipe(\r\n      /* Add Sub/sub collections*/\r\n      mergeMap((currentData) => {\r\n\r\n        const subWriters: Array<Observable<any>> = [];\r\n\r\n        for (const [subCollectionKey, subCollectionValue] of Object.entries(subCollections)) {\r\n          let subSubCollectionWriters: SubCollectionWriter[] | undefined; // undefined if no subCollectionWriters\r\n          let subDocId: string | undefined;\r\n\r\n          if (subCollectionWriters) {\r\n            subSubCollectionWriters = subCollectionWriters.find(subColl => subColl.name === subCollectionKey)?.subCollections;\r\n            subDocId = subCollectionWriters.find(subColl => subColl.name === subCollectionKey)?.docId;\r\n          }\r\n\r\n          const subCollectionRef: CollectionReference = getSubCollection(currentData.firestoreMetadata.ref, subCollectionKey);\r\n\r\n          /* Handle array and object differently\r\n          * For example if array and no docId is given it means we should save each entry as a separate doc.\r\n          * If a docId is given we should save it using that docId under a single doc.\r\n          * If not an array it will always be saved as a single doc, using this.defaultDocId as the default docId if none is given */\r\n          if (Array.isArray(subCollectionValue)) {\r\n            if (subDocId !== undefined) { /* not undefined so save it as a single doc under that docId */\r\n\r\n              /* the pipe only matters for the return subCollectionValue not for writing the data */\r\n              const subWriter = this.add$(subCollectionValue, subCollectionRef, subSubCollectionWriters, subDocId).pipe(\r\n                map(item => {\r\n                  // return {[key]: item};\r\n                  return {key: subCollectionKey, value: item}; /* key and subCollectionValue as separate k,v properties */\r\n                })\r\n              );\r\n              subWriters.push(subWriter);\r\n\r\n            } else { /* docId is undefined so we save each object in the array separate */\r\n              subCollectionValue.forEach((arrayValue: T) => {\r\n\r\n                /* the pipe only matters for the return subCollectionValue not for writing the data */\r\n                const subWriter = this.add$(arrayValue, subCollectionRef, subSubCollectionWriters).pipe(\r\n                  map((item) => {\r\n                    // return {[key]: [item]};\r\n                    /* key and subCollectionValue as separate k,v properties -- subCollectionValue in an array */\r\n                    return {key: subCollectionKey, value: [item]};\r\n                  })\r\n                );\r\n\r\n                subWriters.push(subWriter);\r\n              });\r\n            }\r\n          } else { /* Not an array so a single Object*/\r\n            subDocId = subDocId !== undefined ? subDocId : this.defaultDocId;\r\n\r\n            /* the pipe only matters for the return subCollectionValue not for writing the data */\r\n            const subWriter = this.add$(subCollectionValue, subCollectionRef, subSubCollectionWriters, subDocId).pipe(\r\n              map(item => {\r\n                // return {[key]: item};\r\n                return {key: subCollectionKey, value: item}; /* key and subCollectionValue as separate k,v properties */\r\n              })\r\n            );\r\n\r\n            subWriters.push(subWriter);\r\n          }\r\n        } /* end of iteration */\r\n\r\n        if (subWriters.length > 0) { /* if subWriters.length > 0 it means we need to handle the subWriters */\r\n\r\n          /* the pipe only matters for the return value not for writing the data */\r\n          return combineLatest(subWriters).pipe(\r\n            // tap(sub => console.log(sub)),\r\n\r\n            // TODO super duper ugly way of joining the data together but I cannot think of a better way..also it doesnt really matter.\r\n            // TODO The ugliness only relates to how the return object looks after we add, it has no effect on how the object is saved on\r\n            // TODO firestore.\r\n\r\n            map((docDatas: Array<Map<string, []>>) => { /* List of sub docs*/\r\n              const groupedData = {};\r\n\r\n              docDatas.forEach((doc: { [indexKey: string]: any }) => { /* iterate over each doc */\r\n\r\n                // tslint:disable-next-line:no-string-literal\r\n                const key = doc['key'];\r\n                // tslint:disable-next-line:no-string-literal\r\n                const value = doc['value'];\r\n\r\n                /* if groupedData has the key already it means that the several docs have the same key..so an array */\r\n                // @ts-ignore\r\n                if (groupedData.hasOwnProperty(key) && Array.isArray(groupedData[key])) {\r\n                  /* groupedData[key] must be an array since it already exist..add this doc.value to the array */\r\n                  // @ts-ignore\r\n                  (groupedData[key] as Array<any>).push(value[0]);\r\n                } else {\r\n                  // @ts-ignore\r\n                  groupedData[key] = value;\r\n                }\r\n              });\r\n\r\n              return groupedData as T;\r\n            }),\r\n\r\n            // tap(groupedData => console.log(groupedData)),\r\n\r\n            map((groupedData: T) => {\r\n              return {...currentData, ...groupedData} as T;\r\n            }),\r\n            // tap(d => console.log(d)),\r\n          );\r\n        } else {\r\n          return of(currentData);\r\n        }\r\n      })\r\n    ).pipe(\r\n      // @ts-ignore\r\n      take(1)\r\n    );\r\n  }\r\n\r\n  /* ----------  EDIT -------------- */\r\n\r\n  /**\r\n   * Update document and child documents\r\n   *\r\n   * Be careful when updating a document of any kind since we allow partial data there cannot be any type checking prior to update\r\n   * so its possible to introduce spelling mistakes on attributes and so forth\r\n   *\r\n   * @param data the data that is to be added or updated { [field: string]: any }\r\n   * @param docRef DocumentReference to be updated\r\n   * @param subCollectionWriters if the data contains properties that should be placed in child collections and documents specify that here\r\n   * @param isAddModifiedDate if true the modifiedDate property is added/updated on the affected documents\r\n   */\r\n  public update$<T extends DocumentData>(data: UpdateData<Partial<T>>,\r\n                                         docRef: DocumentReference<T>,\r\n                                         subCollectionWriters: SubCollectionWriter[] = [],\r\n                                         isAddModifiedDate: boolean = true): Observable<void> {\r\n\r\n    if (subCollectionWriters == null || subCollectionWriters.length === 0) {\r\n      return this.updateSimple$(data, docRef, isAddModifiedDate); // no subCollectionWriters so just do a simple update\r\n    }\r\n\r\n    const batch = this.updateDeepToBatchHelper(data, docRef, subCollectionWriters, isAddModifiedDate);\r\n    return this.batchCommit$(batch);\r\n  }\r\n\r\n  /**\r\n   * Update/ add data to the firestore documents\r\n   *\r\n   * @param docRefs list of DocumentReference to be have their data updated\r\n   * @param data data to add/update\r\n   * @param isAddModifiedDate if true the modifiedDate is added/updated\r\n   */\r\n  public updateMultiple$<A>(docRefs: DocumentReference[], data: A, isAddModifiedDate: boolean = true): Observable<void> {\r\n    // const batch = this.fs.firebaseApp.firestore().batch();\r\n    const batch: WriteBatch = writeBatch(this.fs.firestore);\r\n\r\n    if (isAddModifiedDate) {\r\n      data = addModifiedDate(data, false);\r\n    }\r\n\r\n    docRefs.forEach((docRef) => {\r\n      batch.update(docRef, data);\r\n    });\r\n\r\n    return this.batchCommit$(batch);\r\n  }\r\n\r\n\r\n  /**\r\n   * Firestore doesn't allow you do change the name or move a doc directly so you will have to create a new doc under the new name\r\n   * and then delete the old doc.\r\n   * returns the new doc once the delete is done.\r\n   *\r\n   * @param docRef DocumentReference to have its id changed\r\n   * @param newId the new id\r\n   * @param subCollectionQueries if the document has child documents the subCollectionQueries are needed to locate them\r\n   * @param subCollectionWriters if the document has child documents the SubCollectionWriters are needed to add them back\r\n   */\r\n  public changeDocId$<T extends DocumentData>(docRef: DocumentReference<T>,\r\n                                              newId: string,\r\n                                              subCollectionQueries: SubCollectionQuery[] = [],\r\n                                              subCollectionWriters?: SubCollectionWriter[]): Observable<FireItem<T>> {\r\n\r\n    if (subCollectionWriters == null) {\r\n      subCollectionWriters = subCollectionQueries as SubCollectionWriter[];\r\n    }\r\n\r\n    const collectionRef: CollectionReference<T> = docRef.parent;\r\n\r\n    return this.listenForDoc$<T>(docRef, subCollectionQueries).pipe(\r\n      // @ts-ignore\r\n      take(1),\r\n      map((oldData: T) => this.cleanExtrasFromData(oldData, subCollectionWriters)),\r\n      switchMap((oldData: T) => {\r\n        return this.add$<T>(oldData, collectionRef, subCollectionWriters, newId).pipe( /* add the data under id*/\r\n          mergeMap(newData => { /* delete the old doc */\r\n            return this.delete$(docRef, subCollectionQueries).pipe(\r\n              map(() => newData) /* keep the new data */\r\n            );\r\n          }),\r\n        );\r\n      }),\r\n      catchError(err => {\r\n        console.log('Failed to Change Doc Id: ' + err);\r\n        throw err;\r\n      }),\r\n      take(1),\r\n    );\r\n\r\n  }\r\n\r\n  /* Move Item in Array */\r\n\r\n\r\n  /**\r\n   * Moved item within the same list so we need to update the index of all items in the list;\r\n   * Use a copy if you dont wish to update the given array, for example when you want to just listen for the change of the db..\r\n   * The reason to not do this is because it takes some time for the db to update and it looks better if the list updates immediately.\r\n   *\r\n   * @param items array of FireItem<A> docs with index variables to be updated\r\n   * @param fromIndex\r\n   * @param toIndex\r\n   * @param useCopy if true the given array will not be updated\r\n   */\r\n  public moveItemInArray$<T extends DocumentData & ItemWithIndex>(items: Array<FireItem<T>>,\r\n                                                                  fromIndex: number,\r\n                                                                  toIndex: number,\r\n                                                                  useCopy = false): Observable<void> {\r\n\r\n    if (fromIndex == null || toIndex == null || fromIndex === toIndex || items.length <= 0) { // we didnt really move anything\r\n      return of();\r\n    }\r\n\r\n    if (items[0]?.firestoreMetadata == null) {\r\n      const error: FirestoreErrorExt = {\r\n        name: 'firestoreExt/unable-to-change-index-of-non-document',\r\n        code: 'not-found',\r\n        message: 'The array does not appear to be a firestore document or FireItem since it lacks firestoreMetadata',\r\n      };\r\n      throw error;\r\n    }\r\n\r\n    const batch = this.getBatchFromMoveItemInIndexedDocs(items, fromIndex, toIndex, useCopy);\r\n\r\n    return this.batchCommit$(batch);\r\n  }\r\n\r\n  /**\r\n   * Does the heavy lifting when it comes to updating multiple docs to change their index.\r\n   * Not called directly.\r\n   *\r\n   * @param items array of FireItem<A> docs with index variables to be updated\r\n   * @param fromIndex\r\n   * @param toIndex\r\n   * @param useCopy if true the given array will not be updated\r\n   * @protected\r\n   */\r\n  protected getBatchFromMoveItemInIndexedDocs<T extends DocumentData & ItemWithIndex>(items: Array<FireItem<T>>,\r\n                                                                                      fromIndex: number,\r\n                                                                                      toIndex: number,\r\n                                                                                      useCopy = false): WriteBatch {\r\n\r\n    const lowestIndex = Math.min(fromIndex, toIndex);\r\n    const batch: WriteBatch = writeBatch(this.fs.firestore);\r\n\r\n    if (fromIndex == null || toIndex == null || fromIndex === toIndex) { // we didnt really move anything\r\n      return batch;\r\n    }\r\n\r\n\r\n    let usedItems: Array<FireItem<T>>;\r\n\r\n    if (useCopy) {\r\n      usedItems = Object.assign([], items);\r\n    } else {\r\n      usedItems = items;\r\n    }\r\n\r\n    moveItemInArray<FireItem<T>>(usedItems, fromIndex, toIndex);\r\n\r\n    const listSliceToUpdate: Array<FireItem<T>> = usedItems.slice(lowestIndex);\r\n\r\n    let i = lowestIndex;\r\n    for (const item of listSliceToUpdate) {\r\n      if (!useCopy) { // this is just so that the given array's index is also updated immediately\r\n        item.index = i;\r\n      }\r\n      const ref = getRefFromPath(item.firestoreMetadata.path, this.fs.firestore) as DocumentReference;\r\n      batch.update(ref, {index: i});\r\n      i++;\r\n    }\r\n\r\n    return batch;\r\n  }\r\n\r\n  /**\r\n   * Use when you wish to delete an indexed document and have the remaining documents update their indices to reflect the change.\r\n   *\r\n   * @param items array of FireItem<A> docs with index variables to be updated\r\n   * @param indexToDelete\r\n   * @param subCollectionQueries\r\n   * @param useCopy\r\n   */\r\n  public deleteIndexedItemInArray$<T extends DocumentData & ItemWithIndex>(items: Array<FireItem<T>>,\r\n                                                                           indexToDelete: number,\r\n                                                                           subCollectionQueries: SubCollectionQuery[] = [],\r\n                                                                           useCopy: boolean = false): Observable<void> {\r\n\r\n    let usedItems: Array<FireItem<T>>;\r\n\r\n    if (useCopy) {\r\n      usedItems = Object.assign([], items);\r\n    } else {\r\n      usedItems = items;\r\n    }\r\n\r\n    const itemToDelete = usedItems[indexToDelete];\r\n\r\n    // get the delete batch that also contains any sub collections of the item\r\n    return this.getDeleteBatch$(itemToDelete.firestoreMetadata.ref, subCollectionQueries).pipe(\r\n      map((batch) => {\r\n        // sort and remove the item from the usedItems and then add the update index to the batch\r\n        usedItems.sort(item => item.index); // make sure array is sorted by index\r\n        usedItems.splice(indexToDelete, 1);\r\n\r\n        this.getBatchFromUpdateIndexFromListOfDocs<T>(usedItems, batch);\r\n\r\n        return batch;\r\n      }),\r\n\r\n      switchMap((batch) => this.batchCommit$(batch))\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Use when you wish to delete several indexed documents and have the remaining documents update their indices to reflect the change.\r\n   *\r\n   * @param items array of FireItem<A> docs with index variables to be updated\r\n   * @param indicesToDelete\r\n   * @param subCollectionQueries\r\n   * @param useCopy\r\n   */\r\n  public deleteIndexedItemsInArray$<T extends DocumentData & ItemWithIndex>(items: Array<FireItem<T>>,\r\n                                                                            indicesToDelete: number[],\r\n                                                                            subCollectionQueries: SubCollectionQuery[] = [],\r\n                                                                            useCopy: boolean = false): Observable<void> {\r\n\r\n    let usedItems: Array<FireItem<T>>;\r\n\r\n    if (useCopy) {\r\n      usedItems = Object.assign([], items);\r\n    } else {\r\n      usedItems = items;\r\n    }\r\n\r\n    usedItems.sort(item => item.index); // make sure array is sorted by index\r\n\r\n    const itemsToDelete = usedItems.filter((item, i) => {\r\n      return indicesToDelete.findIndex(_i => _i === i) !== -1;\r\n    });\r\n\r\n    // iterate in reverse so as to not change the indices,\r\n    // the indices to delete must also be sorted\r\n    indicesToDelete.sort();\r\n    for (let i = indicesToDelete.length - 1; i >= 0; i--) {\r\n      usedItems.splice(indicesToDelete[i], 1);\r\n    }\r\n\r\n    const docRefsObs$: Observable<DocumentReference[]>[] = [];\r\n\r\n    // get the docRefs for items to be deleted including the ones in the subCollections\r\n    itemsToDelete.forEach(itemToDelete => {\r\n\r\n      const obs$ = this.getDocumentReferencesDeep$(itemToDelete.firestoreMetadata.ref, subCollectionQueries).pipe(\r\n        take(1)\r\n      );\r\n      docRefsObs$.push(obs$);\r\n    });\r\n\r\n\r\n    return forkJoin(docRefsObs$).pipe(\r\n      take(1),\r\n      map((listOfDocRefs) => {\r\n        // concat all the separate docRefs lists into one array of docRefs\r\n        let docRefs: DocumentReference[] = [];\r\n\r\n        listOfDocRefs.forEach(refs => {\r\n          docRefs = docRefs.concat(refs);\r\n        });\r\n\r\n        return docRefs;\r\n      }),\r\n      map((docRefs: DocumentReference<DocumentData>[]) => this.getDeleteMultipleSimpleBatch(docRefs)),\r\n      map((batch: WriteBatch) => this.getBatchFromUpdateIndexFromListOfDocs<T>(usedItems, batch)),\r\n      switchMap((batch) => this.batchCommit$(batch))\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Run this on collections with a fixed order using an index: number attribute;\r\n   * This will update that index with the index in the collectionData, so it should be sorted by index first.\r\n   * Basically needs to be run after a delete\r\n   *\r\n   * @param items\r\n   * @param batch\r\n   * @protected\r\n   */\r\n  protected getBatchFromUpdateIndexFromListOfDocs<T extends DocumentData & ItemWithIndex>(\r\n    items: Array<FireItem<T>>,\r\n    batch: WriteBatch = writeBatch(this.fs.firestore)\r\n  ): WriteBatch {\r\n\r\n    items.forEach((item, index) => {\r\n      if (item.index !== index) {\r\n        item.index = index; // this is just so that the given array's index is also updated immediately\r\n        const ref = getRefFromPath(item.firestoreMetadata.path, this.fs.firestore) as DocumentReference;\r\n        batch.update(ref, {index});\r\n      }\r\n    });\r\n\r\n    return batch;\r\n  }\r\n\r\n  public transferItemInIndexedDocs<T extends DocumentData & ItemWithIndexGroup>(\r\n    previousArray: Array<FireItem<T>>,\r\n    currentArray: Array<FireItem<T>>,\r\n    previousIndex: number,\r\n    currentIndex: number,\r\n    currentArrayName: string,\r\n    additionalDataUpdateOnMovedItem?: { [key: string]: any },\r\n    isUpdateModifiedDateOnMovedItem = true,\r\n    useCopy = false): Observable<void> {\r\n\r\n    const batch: WriteBatch = this.getBatchFromTransferItemInIndexedDocs(previousArray,\r\n      currentArray,\r\n      previousIndex,\r\n      currentIndex,\r\n      currentArrayName,\r\n      additionalDataUpdateOnMovedItem,\r\n      isUpdateModifiedDateOnMovedItem,\r\n      useCopy);\r\n\r\n    return this.batchCommit$(batch);\r\n  }\r\n\r\n\r\n  /* ----------  DELETE -------------- */\r\n\r\n  /**\r\n   * Delete Document and child documents.\r\n   * Takes a DocumentReference and an optional list of SubCollectionQuery\r\n   *\r\n   * @param docRef DocumentReference that is to be deleted\r\n   * @param subCollectionQueries if the document has child documents the subCollectionQueries are needed to locate them\r\n   */\r\n  public delete$(docRef: DocumentReference, subCollectionQueries: SubCollectionQuery[] = []): Observable<void> {\r\n\r\n    if (subCollectionQueries == null || subCollectionQueries.length === 0) {\r\n      // not deep so just do a normal doc delete\r\n      return this.fs.delete(docRef);\r\n    }\r\n\r\n    return this.getDocumentReferencesDeep$(docRef, subCollectionQueries).pipe(\r\n      switchMap((docRefList: DocumentReference<DocumentData>[]) => this.deleteMultipleSimple$(docRefList)),\r\n      // catchError((err) => { // TODO super ugly and I dont know why this error is thrown..still works\r\n      //   if (err === 'Document Does not exists') { return of(); }\r\n      //   else { throw err; }\r\n      // }),\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Returns WriteBatch that is set to delete Document and child documents of given docRef\r\n   *\r\n   * @param docRef DocumentReference that is to be deleted\r\n   * @param subCollectionQueries if the document has child documents the subCollectionQueries are needed to locate them\r\n   * @param batch\r\n   */\r\n  public getDeleteBatch$(docRef: DocumentReference,\r\n                         subCollectionQueries: SubCollectionQuery[] = [],\r\n                         batch: WriteBatch = writeBatch(this.fs.firestore)): Observable<WriteBatch> {\r\n\r\n    if (subCollectionQueries == null || subCollectionQueries.length === 0) {\r\n      // not deep so just do a normal doc delete\r\n      batch.delete(docRef);\r\n      return of(batch);\r\n    }\r\n\r\n    return this.getDocumentReferencesDeep$(docRef, subCollectionQueries).pipe(\r\n      map((docRefs: DocumentReference<DocumentData>[]) => this.getDeleteMultipleSimpleBatch(docRefs)),\r\n      take(1)\r\n    );\r\n  }\r\n\r\n  public deleteMultipleByPaths$(docPaths: string[]): Observable<any> {\r\n    const docRefs: DocumentReference[] =\r\n      docPaths.map(path => getRefFromPath(path, this.fs.firestore) as DocumentReference);\r\n\r\n    return this.deleteMultipleSimple$(docRefs);\r\n  }\r\n\r\n  /**\r\n   * Delete Documents and child documents\r\n   *\r\n   * @param docRefs - A list of DocumentReference that are to be deleted\r\n   * @param subCollectionQueries if the document has child documents the subCollectionQueries are needed to locate them\r\n   */\r\n  public deleteMultiple$<T = FireItem>(docRefs: DocumentReference<T>[],\r\n                                       subCollectionQueries: SubCollectionQuery[] = []): Observable<any> {\r\n\r\n    if (subCollectionQueries == null || subCollectionQueries.length === 0) {\r\n      return this.deleteMultipleSimple$(docRefs);\r\n    }\r\n\r\n    const deepDocRefs$: Array<Observable<any>> = [];\r\n\r\n    docRefs.forEach(docRef => {\r\n      const docRefs$ = this.getDocumentReferencesDeep$(docRef, subCollectionQueries);\r\n      deepDocRefs$.push(docRefs$);\r\n    });\r\n\r\n    return combineLatest(deepDocRefs$).pipe(\r\n      // tap(lists => console.log(lists)),\r\n      map((lists: any[]) => {\r\n        let mainDocRefList: DocumentReference[] = [];\r\n        lists.forEach(list => {\r\n          mainDocRefList = mainDocRefList.concat(list);\r\n        });\r\n        return mainDocRefList;\r\n      }),\r\n      // tap(lists => console.log(lists)),\r\n      switchMap((docRefList: DocumentReference[]) => this.deleteMultipleSimple$(docRefList)),\r\n      // catchError((err) => { // TODO super ugly and I dont know why this error is thrown..still works\r\n      //   if (err === 'Document Does not exists') { return of(null); }\r\n      //   else { throw err; }\r\n      // })\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Delete all documents and sub collections as specified in subCollectionQueries.\r\n   * Not very efficient and causes a lot of db reads.\r\n   * If possible use the firebase CLI or the console instead when deleting large collections.\r\n   *\r\n   * @param collectionRef\r\n   * @param subCollectionQueries\r\n   */\r\n  public deleteCollection$<T extends DocumentData>(collectionRef: CollectionReference<T>,\r\n                                                   subCollectionQueries: SubCollectionQuery[] = []): Observable<any> {\r\n    return this.getDocumentReferencesFromCollectionRef$(collectionRef, subCollectionQueries).pipe(\r\n      switchMap((docRefs) => this.deleteMultiple$(docRefs))\r\n    ).pipe(\r\n      take(1)\r\n    );\r\n  }\r\n\r\n\r\n  /**\r\n   * Delete firestore document by path\r\n   * Convenience method in case we do not have direct access to the AngularFirestoreDocument reference\r\n   *\r\n   * @param docPath A string representing the path of the referenced document (relative to the root of the database).\r\n   * @param subCollectionQueries if the document has child documents the subCollectionQueries are needed to locate them\r\n   */\r\n  public deleteDocByPath$(docPath: string, subCollectionQueries: SubCollectionQuery[] = []): Observable<any> {\r\n    const docRef = getRefFromPath(docPath, this.fs.firestore) as DocumentReference;\r\n    return this.delete$(docRef, subCollectionQueries);\r\n  }\r\n\r\n  /**\r\n   * Delete document by FirestoreItem\r\n   *\r\n   * A very convenient method to remove a previously fetched document.\r\n   * Requires that the document/Item is previously fetched since the item needs to be a FireItem, i.e. includes firestoreMetadata.\r\n   *\r\n   * @param item FirestoreItem to be deleted\r\n   * @param subCollectionQueries if the document has child documents the subCollectionQueries are needed to locate them\r\n   */\r\n  public deleteItem$<T extends DocumentData>(item: FireItem<T>, subCollectionQueries: SubCollectionQuery[] = []): Observable<any> {\r\n\r\n    const docRefs = this.getDocumentReferencesFromItem(item, subCollectionQueries);\r\n\r\n    return this.deleteMultipleSimple$(docRefs).pipe(\r\n      // catchError((err) => { // TODO super ugly and I dont know why this error is thrown..still works\r\n      //   if (err === 'Document Does not exists') { return of(null); }\r\n      //   else { throw err; }\r\n      // }),\r\n      take(1)\r\n    );\r\n  }\r\n\r\n\r\n  /* ---- OTHER ---- */\r\n\r\n  /**\r\n   * clean FirestoreBaseItem properties from the data.\r\n   * Usually done if you wish to save the data to firestore, since some FirestoreBaseItem properties are of non allowed types.\r\n   *\r\n   * Goes through each level and removes DbItemExtras\r\n   * In case you wish to save the data\r\n   *\r\n   * @param data data to be cleaned, either single item or an array of items\r\n   * @param subCollectionWriters if the document has child documents the SubCollectionWriters are needed to locate them\r\n   * @param additionalFieldsToRemove\r\n   */\r\n\r\n  cleanExtrasFromData<T>(data: T & DocumentData | FireItem,\r\n                         subCollectionWriters?: SubCollectionWriter[],\r\n                         additionalFieldsToRemove?: string[]): T;\r\n\r\n  cleanExtrasFromData<T>(datas: Array<T & DocumentData | FireItem>,\r\n                         subCollectionWriters?: SubCollectionWriter[],\r\n                         additionalFieldsToRemove?: string[]): Array<T>;\r\n\r\n  public cleanExtrasFromData<T>(data: T & DocumentData | Array<T & DocumentData | FireItem>,\r\n                                subCollectionWriters: SubCollectionWriter[] = [],\r\n                                additionalFieldsToRemove: string[] = []): T | Array<T> {\r\n\r\n    // const dataToBeCleaned = cloneDeep(data); /* clone data so we dont modify the original */\r\n    // const dataToBeCleaned = data;\r\n\r\n    if (Array.isArray(data)) {\r\n\r\n      const cleanDatas: Array<T> = [];\r\n\r\n      data.forEach(d => {\r\n        cleanDatas.push(\r\n          this.removeDataExtrasRecursiveHelper(d, subCollectionWriters, additionalFieldsToRemove) as T\r\n        );\r\n      });\r\n\r\n      return cleanDatas;\r\n\r\n    } else {\r\n      return this.removeDataExtrasRecursiveHelper(data, subCollectionWriters, additionalFieldsToRemove) as T;\r\n    }\r\n  }\r\n\r\n\r\n  /* ----------  PROTECTED METHODS -------------- */\r\n\r\n  /**\r\n   * Same as AngularFirestoreDocument.snapshotChanges but it adds the properties in FirebaseDbItem\r\n   * and also allows for to choose action to take when document does not exist\r\n   *\r\n   * Important to understand this is will trigger for every change/update on the document we are listening to.\r\n   *\r\n   * @param docRef DocumentReference that will be listened to\r\n   * @param actionIfNotExist Action to take if document does not exist\r\n   */\r\n  protected listenForDocSimple$<T extends DocumentData>(docRef: DocumentReference<any>,\r\n                                                        actionIfNotExist: DocNotExistAction = DocNotExistAction.RETURN_ALL_BUT_DATA\r\n  ): Observable<FireItem<T>> {\r\n\r\n    return this.fs.listenForDoc(docRef).pipe(\r\n      tap((documentSnapshot: DocumentSnapshot<T>) => {\r\n        if (!documentSnapshot.exists() && actionIfNotExist === DocNotExistAction.THROW_DOC_NOT_FOUND) {\r\n          const error: FirestoreErrorExt = {\r\n            name: 'FirebaseErrorExt',\r\n            code: 'not-found',\r\n            message: 'Document not found and actionIfNotExist is set to THROW_DOC_NOT_FOUND',\r\n            docRef\r\n          };\r\n          throw error;\r\n        }\r\n      }),\r\n\r\n      filter((documentSnapshot: DocumentSnapshot<T>) => {\r\n        return !(!documentSnapshot.exists() && actionIfNotExist === DocNotExistAction.FILTER);\r\n      }),\r\n      map((documentSnapshot: DocumentSnapshot<T>) => {\r\n\r\n        if (documentSnapshot.exists() || actionIfNotExist === DocNotExistAction.RETURN_ALL_BUT_DATA) {\r\n          const data = documentSnapshot.data() as T;\r\n\r\n          const firestoreMetadata: FirestoreMetadata<T> = {\r\n            id: documentSnapshot.id,\r\n            ref: documentSnapshot.ref as DocumentReference<T>,\r\n            path: docRef.path,\r\n            isExists: documentSnapshot.exists(),\r\n            documentSnapshot\r\n          };\r\n\r\n          return {...data, firestoreMetadata} as FireItem<T>;\r\n\r\n        } else if (actionIfNotExist === DocNotExistAction.RETURN_NULL) { /* doc doesn't exist */\r\n          return null;\r\n        }\r\n        return null;\r\n      }),\r\n      map((data) => {\r\n        if (data != null) {\r\n          return convertTimestampToDate(data as FireItem<T>);\r\n        } else {\r\n          return data;\r\n        }\r\n      }),\r\n    ) as Observable<FireItem<T>>;\r\n  }\r\n\r\n  /**\r\n   * Listens for single collection and returns an array of documents as FireItem<T>[]\r\n   * Used internally, please use listenForCollection$() instead.\r\n   *\r\n   * @param _query the Query which will be listened to\r\n   * @protected\r\n   */\r\n  protected listenForCollectionSimple$<T extends DocumentData>(_query: Query<T>): Observable<Array<FireItem<T>>> {\r\n    /**\r\n     * Returns an observable that will emit whenever the ref changes in any way.\r\n     * Also adds the id and ref to the object.\r\n     */\r\n    return this.fs.listenForCollection(_query).pipe(\r\n      map((querySnapshot: QuerySnapshot<T>) => {\r\n        return querySnapshot.docs.map(documentSnapshot => {\r\n          const data = documentSnapshot.data() as T;\r\n\r\n          const id = documentSnapshot.id;\r\n          const ref = documentSnapshot.ref as DocumentReference<T>;\r\n          const path = ref.path;\r\n\r\n          const firestoreMetadata: FirestoreMetadata<T> = {\r\n            id,\r\n            path,\r\n            ref,\r\n            isExists: true,\r\n            documentSnapshot\r\n          };\r\n\r\n          return {...data, firestoreMetadata} as FireItem<T>;\r\n        });\r\n      }),\r\n      map((datas: Array<FireItem<T>>) => datas.map((data) => {\r\n        return convertTimestampToDate(data as FireItem<T>);\r\n      }))\r\n    ) as Observable<Array<FireItem<T>>>;\r\n  }\r\n\r\n  /**\r\n   * Used internally for both listenForDoc and listenForCollection in order to recursively get collections.\r\n   *\r\n   * Please use listenForDoc or listenForCollection.\r\n   *\r\n   * @param item\r\n   * @param subCollectionQueries\r\n   * @protected\r\n   */\r\n  protected listenForCollectionsDeep<T extends DocumentData>(\r\n    item: FireItem<T>,\r\n    subCollectionQueries: SubCollectionQuery[] = []): Observable<FireItem<T>[]> {\r\n\r\n    if (item == null) {\r\n      return of([item]);\r\n    }\r\n    if (subCollectionQueries.length <= 0) {\r\n      return of([item]);\r\n    }\r\n\r\n    const collectionListeners: Array<Observable<any>> = [];\r\n\r\n    /* Iterate over each sub collection we have given and create collection listeners*/\r\n    subCollectionQueries.forEach(subCollectionQuery => {\r\n\r\n      const queryContainer = new QueryContainer(getSubCollection(item.firestoreMetadata.ref, subCollectionQuery.name));\r\n      if (subCollectionQuery.queryConstraints) {\r\n        queryContainer.queryConstraints = subCollectionQuery.queryConstraints;\r\n        // collectionRef = subCollectionQuery.queryFn(collectionRef) as CollectionReference;\r\n      }\r\n      // if (subCollectionQuery.queryFn) {\r\n      //   collectionRef = subCollectionQuery.queryFn(collectionRef) as CollectionReference;\r\n      // }\r\n\r\n      const collectionListener = this.listenForCollectionSimple$(queryContainer.query).pipe(\r\n        // filter(docs => docs.length > 0), // skip empty collections or if the subCollectionQuery doesnt exist\r\n        /* Uncomment to see data on each update */\r\n        // tap(d => console.log(d)),\r\n        // filter(docs => docs != null),\r\n        /* Listen For and Add any Potential Sub Docs*/\r\n        // @ts-ignore // TODO fix this so that I can remove the ts-ignore\r\n        mergeMap((items: FireItem[]) => {\r\n\r\n          if (!subCollectionQuery.subCollections) {\r\n            return of(items);\r\n          }\r\n\r\n          const docListeners: Array<Observable<any>> = [];\r\n\r\n          items = items.filter(d => d != null); // filter out potential nulls\r\n\r\n          items.forEach((subItem: FireItem) => {\r\n            const subDocAndCollections$ = this.listenForCollectionsDeep(subItem, subCollectionQuery.subCollections);\r\n            docListeners.push(subDocAndCollections$);\r\n          });\r\n\r\n          if (docListeners.length <= 0) {\r\n            return of([]);\r\n          } /* subCollectionQuery is empty or doesnt exist */\r\n\r\n          return combineLatest(docListeners).pipe(\r\n            // tap(val => console.log(val))\r\n          );\r\n        }), /* End of Listening for sub docs */\r\n        /* If docs.length === 1 and the id is defaultDocId or the given docId it means we are in a sub subCollectionQuery\r\n        and we only care about the data. So we remove the array and just make it one object with the\r\n        subCollectionQuery name as key and docs[0] as value */\r\n        map((items: FireItem<T>[]) => {\r\n          const docId = subCollectionQuery.docId !== undefined ? subCollectionQuery.docId : this.defaultDocId;\r\n\r\n          if (items.length === 1 && items[0].firestoreMetadata.id === docId) {\r\n            return {[subCollectionQuery.name]: items[0]};\r\n          } else {\r\n            return {[subCollectionQuery.name]: items};\r\n          }\r\n        }),\r\n        // tap(d => console.log(d)),\r\n      );\r\n\r\n      collectionListeners.push(collectionListener);\r\n    });\r\n\r\n    /* Finally return the combined collection listeners*/\r\n    // @ts-ignore\r\n    return combineLatest(collectionListeners).pipe(\r\n      // map((collectionDatas: { [collectionKeyName: string]: FirestoreItem<FirestoreItem<{}>>[] }[]) => {\r\n      //   map((collectionDatas) => {\r\n      map((collectionDatas: { [collectionKeyName: string]: FireItem[] }[]) => {\r\n        const datasMap: { [field: string]: any } = {};\r\n\r\n        collectionDatas.forEach((collectionData) => {\r\n\r\n          for (const [collectionName, items] of Object.entries(collectionData)) {\r\n            datasMap[collectionName] = items;\r\n          }\r\n        });\r\n        return datasMap;\r\n      }),\r\n\r\n      map((data: DocumentData) => {\r\n        return {...item, ...data} as T;\r\n      }),\r\n    );\r\n  }\r\n\r\n  /**\r\n   * DO NOT CALL THIS METHOD, meant to be used solely by listenForDocAndSubCollections$\r\n   */\r\n  protected listenForDocDeepRecursiveHelper$<T extends DocumentData>(\r\n    docRef: DocumentReference<T>,\r\n    subCollectionQueries: SubCollectionQuery[] = [],\r\n    actionIfNotExist: DocNotExistAction = DocNotExistAction.RETURN_NULL): Observable<any> {\r\n\r\n    /* Listen for the docFs*/\r\n    return this.listenForDocSimple$<T>(docRef, actionIfNotExist).pipe(\r\n      mergeMap((item: FireItem<T>) => {\r\n\r\n        if (item === null) {\r\n          return of(item);\r\n        }\r\n        if (subCollectionQueries.length <= 0) {\r\n          return of(item);\r\n        }\r\n\r\n        return this.listenForCollectionsDeep(item, subCollectionQueries);\r\n      })\r\n    );\r\n  }\r\n\r\n  /**\r\n   * A replacement/extension to the AngularFirestoreCollection.add.\r\n   * Does the same as AngularFirestoreCollection.add but can also add createdDate and modifiedDate and returns\r\n   * the data with the added properties in FirebaseDbItem\r\n   *\r\n   * Used internally\r\n   *\r\n   * @param data the data to be added to the document, cannot contain types firestore won't allow\r\n   * @param collectionRef the CollectionReference where the document should be added\r\n   * @param isAddDates if true adds modifiedDate and createdDate to the data\r\n   * @param id if given the added document will be given this id, otherwise a random unique id will be used.\r\n   */\r\n  // protected addSimple$<T extends DocumentData>(data: T, collectionRef: CollectionReference<T>, isAddDates: boolean = true, id?: string):\r\n  protected addSimple$<T extends DocumentData>(data: T, collectionRef: CollectionReference<T>, id?: string):\r\n    Observable<FireItem<T>> {\r\n\r\n    // let dataToBeSaved: A = Object.assign({}, data);\r\n\r\n    let res$: Observable<any>;\r\n\r\n    // if (isAddDates) {\r\n    const date = new Date();\r\n    data = addCreatedDate(data, false, date);\r\n    data = addModifiedDate(data, false, date);\r\n\r\n\r\n    if (id !== undefined) {\r\n      const docRef: DocumentReference = getDocRefWithId(collectionRef, id);\r\n      res$ = this.fs.set(docRef, data);\r\n    } else {\r\n      res$ = this.fs.add<T>(collectionRef, data);\r\n    }\r\n\r\n    // if (Array.isArray(data) && isAddDates) {\r\n    //   data = data.map(item => {\r\n    //     return {...item, modifiedDate: dataToBeSaved.modifiedDate, createdData: dataToBeSaved.createdData }\r\n    //   })\r\n    // }\r\n\r\n    res$ = res$.pipe(\r\n      // tap(() => this.snackBar.open('Success', 'Added', {duration: 1000})),\r\n      // tap(ref => console.log(ref)),\r\n      // tap(() => console.log(data)),\r\n      map((ref: DocumentReference<T> | undefined) => {\r\n        if (id === undefined && ref) {\r\n\r\n          const path = ref.path;\r\n\r\n          const firestoreMetadata: FirestoreMetadata<T> = {\r\n            id: ref.id,\r\n            path,\r\n            ref,\r\n            isExists: true\r\n          };\r\n\r\n          return {...data, firestoreMetadata} as FireItem<T>;\r\n\r\n        } else { // if id is defined it means we used docRef.set and ref is undefined\r\n          const path = collectionRef.path + '/' + id;\r\n          ref = getRefFromPath(path, this.fs.firestore) as DocumentReference<T>;\r\n\r\n          const firestoreMetadata: FirestoreMetadata<T> = {\r\n            id: id as string,\r\n            ref,\r\n            path,\r\n            isExists: true\r\n          };\r\n\r\n          return {...data, firestoreMetadata} as FireItem<T>;\r\n        }\r\n      }),\r\n    );\r\n\r\n    return res$.pipe(\r\n      take(1)\r\n    );\r\n  }\r\n\r\n  /** Used internally for updates that doesn't affect child documents */\r\n  protected updateSimple$<T>(data: UpdateData<Partial<T>>,\r\n                             docRef: DocumentReference<T>,\r\n                             isAddModifiedDate: boolean = true): Observable<void> {\r\n\r\n    if (isAddModifiedDate) {\r\n      data = addModifiedDate(data, false);\r\n    }\r\n    return this.fs.update<T>(docRef, data);\r\n  }\r\n\r\n  /**\r\n   * DO NOT CALL THIS METHOD, used by update deep\r\n   */\r\n  protected updateDeepToBatchHelper<T extends DocumentData>(data: UpdateData<T>,\r\n                                                            docRef: DocumentReference<T>,\r\n                                                            subCollectionWriters: SubCollectionWriter[] = [],\r\n                                                            isAddModifiedDate: boolean = true,\r\n                                                            batch?: WriteBatch): WriteBatch {\r\n\r\n    if (batch === undefined) {\r\n      batch = writeBatch(this.fs.firestore);\r\n    }\r\n\r\n    if (isAddModifiedDate) {\r\n      data = addModifiedDate(data, false);\r\n    }\r\n\r\n    const split = this.splitDataIntoCurrentDocAndSubCollections(data, subCollectionWriters);\r\n    const currentDoc = split.currentDoc as UpdateData<T>;\r\n    const subCollections = split.subCollections;\r\n\r\n    // console.log(currentDoc, subCollections);\r\n    batch.update(docRef, currentDoc);\r\n\r\n    for (const [subCollectionKey, subDocUpdateValue] of Object.entries(subCollections)) {\r\n\r\n      let subSubCollectionWriters: SubCollectionWriter[] | undefined; // undefined if no subCollectionWriters\r\n      let subDocId: string | undefined;\r\n\r\n      if (subCollectionWriters) {\r\n        subSubCollectionWriters = subCollectionWriters.find(subColl => subColl.name === subCollectionKey)?.subCollections;\r\n        subDocId = subCollectionWriters.find(subColl => subColl.name === subCollectionKey)?.docId;\r\n      }\r\n\r\n      subDocId = subDocId !== undefined ? subDocId : this.defaultDocId; /* Set default if none given */\r\n\r\n      // const subDocFs = docRef.collection(subCollectionKey).doc(subDocId);\r\n      const subCollection = getSubCollection(docRef, subCollectionKey);\r\n      const subDocFs = getDocRefWithId(subCollection, subDocId);\r\n\r\n      batch = this.updateDeepToBatchHelper(subDocUpdateValue, subDocFs, subSubCollectionWriters, isAddModifiedDate, batch);\r\n    }\r\n\r\n    return batch;\r\n  }\r\n\r\n  /**\r\n   * Used mainly for drag and drop scenarios where we drag an item from one list to another and the the docs\r\n   * have an index value and a groupName.\r\n   *\r\n   * @param previousArray\r\n   * @param currentArray\r\n   * @param previousIndex\r\n   * @param currentIndex\r\n   * @param currentArrayName\r\n   * @param additionalDataUpdateOnMovedItem\r\n   * @param isUpdateModifiedDateOnMovedItem\r\n   * @param useCopy\r\n   * @protected\r\n   */\r\n  protected getBatchFromTransferItemInIndexedDocs<T extends DocumentData & ItemWithIndexGroup>(\r\n    previousArray: Array<FireItem<T>>,\r\n    currentArray: Array<FireItem<T>>,\r\n    previousIndex: number,\r\n    currentIndex: number,\r\n    currentArrayName: string,\r\n    additionalDataUpdateOnMovedItem?: { [key: string]: any },\r\n    isUpdateModifiedDateOnMovedItem = true,\r\n    useCopy = false): WriteBatch {\r\n\r\n    let usedPreviousArray: Array<FireItem<T>>;\r\n    let usedCurrentArray: Array<FireItem<T>>;\r\n    if (useCopy) {\r\n      usedPreviousArray = Object.assign([], previousArray);\r\n      usedCurrentArray = Object.assign([], currentArray);\r\n    } else {\r\n      usedPreviousArray = previousArray;\r\n      usedCurrentArray = currentArray;\r\n    }\r\n\r\n    transferArrayItem(usedPreviousArray, usedCurrentArray, previousIndex, currentIndex);\r\n\r\n    const batch: WriteBatch = writeBatch(this.fs.firestore);\r\n\r\n    if (additionalDataUpdateOnMovedItem !== undefined) {\r\n      const movedItem = usedCurrentArray[currentIndex];\r\n      const movedItemRef = movedItem.firestoreMetadata.ref;\r\n\r\n      const data = {...additionalDataUpdateOnMovedItem, groupName: currentArrayName};\r\n\r\n      if (!useCopy) {\r\n        addDataToItem(movedItem, data, true);\r\n      }\r\n\r\n      if (isUpdateModifiedDateOnMovedItem) {\r\n        const date = new Date();\r\n        addModifiedDate(data, true, date);\r\n\r\n        if (!useCopy) {\r\n          addModifiedDate(movedItem, true, date);\r\n        }\r\n      }\r\n      batch.update(movedItemRef, data);\r\n    }\r\n\r\n    const currentArraySliceToUpdate: Array<FireItem<T>> = usedCurrentArray.slice(currentIndex);\r\n    let i = currentIndex;\r\n    for (const item of currentArraySliceToUpdate) {\r\n      // @ts-ignore\r\n      batch.update(item.firestoreMetadata.ref, {index: i});\r\n\r\n      if (!useCopy) {\r\n        item.index = i;\r\n      }\r\n\r\n      i++;\r\n    }\r\n\r\n    const prevArraySliceToUpdate: Array<FireItem<T>> = usedPreviousArray.slice(previousIndex);\r\n    i = previousIndex;\r\n    for (const item of prevArraySliceToUpdate) {\r\n      // @ts-ignore\r\n      batch.update(item.firestoreMetadata.ref, {index: i});\r\n\r\n      if (!useCopy) {\r\n        item.index = i;\r\n      }\r\n\r\n      i++;\r\n    }\r\n\r\n    return batch;\r\n  }\r\n\r\n\r\n  /**\r\n   * Delete Documents\r\n   *\r\n   * @param docRefs - A list of DocumentReference that are to be deleted\r\n   */\r\n  protected deleteMultipleSimple$(docRefs: DocumentReference[]): Observable<void> {\r\n\r\n    const batch = this.getDeleteMultipleSimpleBatch(docRefs);\r\n\r\n    return this.batchCommit$(batch);\r\n  }\r\n\r\n  protected getDeleteMultipleSimpleBatch(docRefs: DocumentReference[], batch: WriteBatch = writeBatch(this.fs.firestore)): WriteBatch {\r\n\r\n    docRefs.forEach((docRef) => {\r\n      batch.delete(docRef);\r\n    });\r\n\r\n    return batch;\r\n  }\r\n\r\n  /**\r\n   * Recursive method to clean FirestoreBaseItem properties from the dbItem\r\n   *\r\n   * @param dbItem the data to be cleaned\r\n   * @param subCollectionWriters list of SubCollectionWriters to handle sub collections\r\n   * @param additionalFieldsToRemove\r\n   */\r\n  protected removeDataExtrasRecursiveHelper<T extends DocumentData>(dbItem: T,\r\n                                                                    subCollectionWriters: SubCollectionWriter[] = [],\r\n                                                                    additionalFieldsToRemove: string[] = []): T {\r\n\r\n    // const extraPropertyNames: string[] = Object.getOwnPropertyNames(new DbItemExtras());\r\n    const extraPropertyNames: string[] = ['firestoreMetadata'].concat(additionalFieldsToRemove);\r\n\r\n    /* Current level delete */\r\n    for (const extraPropertyName of extraPropertyNames) {\r\n      delete dbItem[extraPropertyName];\r\n    }\r\n\r\n    subCollectionWriters.forEach(col => {\r\n      if (Array.isArray(dbItem[col.name])) { /* property is array so will contain multiple docs */\r\n\r\n        const docs: T[] = dbItem[col.name];\r\n        docs.forEach((d, i) => {\r\n\r\n          if (col.subCollections) {\r\n            this.removeDataExtrasRecursiveHelper(d, col.subCollections, additionalFieldsToRemove);\r\n          } else {\r\n            /*  */\r\n            for (const extraPropertyName of extraPropertyNames) {\r\n              delete dbItem[col.name][i][extraPropertyName];\r\n            }\r\n          }\r\n        });\r\n\r\n      } else { /* not an array so a single doc*/\r\n\r\n        if (col.subCollections) {\r\n          this.removeDataExtrasRecursiveHelper(dbItem[col.name], col.subCollections, additionalFieldsToRemove);\r\n        } else {\r\n          for (const extraPropertyName of extraPropertyNames) {\r\n            delete dbItem[col.name][extraPropertyName];\r\n          }\r\n        }\r\n\r\n      }\r\n    });\r\n\r\n    return dbItem;\r\n\r\n  }\r\n\r\n  /**\r\n   * Returns an Observable containing a list of DocumentReference found under the given docRef using the SubCollectionQuery[]\r\n   * Mainly used to delete a docFs and its sub docs\r\n   * @param ref: DocumentReference | CollectionReference\r\n   * @param subCollectionQueries: SubCollectionQuery[]\r\n   */\r\n  protected getDocumentReferencesDeep$(ref: DocumentReference | CollectionReference,\r\n                                       subCollectionQueries: SubCollectionQuery[] = []):\r\n    Observable<DocumentReference[]> {\r\n\r\n    if (ref instanceof DocumentReference) {\r\n      return this.getDocumentReferencesFromDocRef$<FireItem>(ref as DocumentReference<FireItem>, subCollectionQueries);\r\n    } else { // CollectionReference\r\n      return this.getDocumentReferencesFromCollectionRef$(ref as CollectionReference<FireItem>, subCollectionQueries);\r\n    }\r\n  }\r\n\r\n  protected getDocumentReferencesFromDocRef$<T extends FireItem>(docRef: DocumentReference<T>,\r\n                                                                 subCollectionQueries: SubCollectionQuery[] = []):\r\n    Observable<DocumentReference[]> {\r\n\r\n    return this.listenForDoc$<T>(docRef, subCollectionQueries).pipe(\r\n      take(1),\r\n      map((item: FireItem<T>) => this.getPathsFromItemDeepRecursiveHelper(item, subCollectionQueries)),\r\n      // tap(pathList => console.log(pathList)),\r\n      map((pathList: string[]) => {\r\n        return pathList\r\n          .map(path => getRefFromPath(path, this.fs.firestore) as DocumentReference);\r\n      }),\r\n      // tap(item => console.log(item)),\r\n    );\r\n  }\r\n\r\n  protected getDocumentReferencesFromCollectionRef$<T extends DocumentData>(collectionRef: CollectionReference<T>,\r\n                                                                            subCollectionQueries: SubCollectionQuery[] = []):\r\n    Observable<DocumentReference[]> {\r\n\r\n    return this.listenForCollectionSimple$(collectionRef).pipe(\r\n      // @ts-ignore\r\n      take(1),\r\n      mergeMap((items: FireItem[]) => {\r\n        let docListeners: Array<Observable<any>>;\r\n        docListeners = items.map(item => this.listenForDoc$(item.firestoreMetadata.ref, subCollectionQueries));\r\n        return combineLatest(docListeners);\r\n      }),\r\n      map((items: FireItem[]) => {\r\n\r\n        let paths: string[] = [];\r\n\r\n        items.forEach(item => {\r\n          paths = paths.concat(this.getPathsFromItemDeepRecursiveHelper(item, subCollectionQueries));\r\n        });\r\n        return paths;\r\n      }),\r\n      map((pathList: string[]) => {\r\n        return pathList\r\n          .map(path => getRefFromPath(path, this.fs.firestore) as DocumentReference);\r\n      }),\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Used by deleteDeepByItem$ to get all the AngularFirestoreDocuments to be deleted\r\n   * including child documents using SubCollectionQueries\r\n   *\r\n   * Internal use\r\n   * @param item FirestoreItem from where we get the AngularFirestoreDocuments\r\n   * @param subCollectionQueries if the dbItem has child documents the subCollectionQueries are needed to locate them\r\n   */\r\n  protected getDocumentReferencesFromItem<T extends DocumentData>(\r\n    item: FireItem<T>,\r\n    subCollectionQueries: SubCollectionQuery[] = []): DocumentReference[] {\r\n\r\n    const paths = this.getPathsFromItemDeepRecursiveHelper(item, subCollectionQueries);\r\n    return paths.map(path => getRefFromPath(path, this.fs.firestore) as DocumentReference);\r\n  }\r\n\r\n  /**\r\n   * DO NOT CALL THIS METHOD, its meant as a support method for getDocs$\r\n   */\r\n  protected getPathsFromItemDeepRecursiveHelper<T extends FireItem>(item: T,\r\n                                                                    subCollectionQueries: SubCollectionQuery[] = []): string[] {\r\n\r\n    if (subCollectionQueries == null || subCollectionQueries.length === 0) {\r\n      return [item.firestoreMetadata.path];\r\n    }\r\n    let pathList: string[] = [];\r\n    pathList.push(item.firestoreMetadata.path);\r\n\r\n    subCollectionQueries.forEach(col => {\r\n      if (Array.isArray((item as DocumentData)[col.name]) && !col.docId) {\r\n        /* property is array and not using docId so will contain multiple docs */\r\n\r\n        const items: T[] = (item as DocumentData)[col.name];\r\n        items.forEach(subItem => {\r\n\r\n          if (col.subCollections) {\r\n            pathList = pathList.concat(this.getPathsFromItemDeepRecursiveHelper(subItem, col.subCollections));\r\n          } else {\r\n            pathList.push(subItem.firestoreMetadata.path);\r\n          }\r\n        });\r\n\r\n      } else { /* not an array so a single doc*/\r\n\r\n        if (col.subCollections) {\r\n          pathList = pathList.concat(this.getPathsFromItemDeepRecursiveHelper(item, col.subCollections));\r\n        } else {\r\n          const subItem = ((item as DocumentData)[col.name] as FireItem);\r\n          if (subItem != null && 'path' in subItem.firestoreMetadata) {\r\n            pathList.push(subItem.firestoreMetadata.path);\r\n          }\r\n          // const path = (dbItem[col.name] as FirestoreItem).path;\r\n        }\r\n\r\n      }\r\n    });\r\n\r\n    return pathList;\r\n  }\r\n\r\n  /**\r\n   * DO  NOT  CALL THIS METHOD, used in addDeep and updateDeep to split the data into currentDoc and subCollections\r\n   * Only goes one sub level deep;\r\n   */\r\n  protected splitDataIntoCurrentDocAndSubCollections<T>(\r\n    data: T,\r\n    subCollectionWriters: SubCollectionWriter[] = []): CurrentDocSubCollectionSplit {\r\n\r\n    /* Split data into current doc and sub collections */\r\n    let currentDoc: { [index: string]: any; } = {};\r\n    const subCollections: { [index: string]: any; } = {};\r\n\r\n    /* Check if the key is in subCollections, if it is place it in subCollections else place it in currentDoc */\r\n\r\n    // not array so object\r\n    for (const [key, value] of Object.entries(data)) {\r\n      // console.log(key, value);\r\n      if (subCollectionWriters && subCollectionWriters.length > 0) {\r\n        const subCollectionWriter: SubCollectionWriter | undefined = subCollectionWriters.find(subColl => subColl.name === key);\r\n\r\n        if (subCollectionWriter) {\r\n          subCollections[key] = value;\r\n        } else {\r\n          currentDoc[key] = value;\r\n        }\r\n      } else {\r\n        currentDoc = data;\r\n      }\r\n    }\r\n\r\n\r\n    return {\r\n      currentDoc,\r\n      subCollections\r\n    } as CurrentDocSubCollectionSplit;\r\n  }\r\n\r\n  /**\r\n   * Turn a batch into an Observable instead of Promise.\r\n   *\r\n   * For some reason angularfire returns a promise on batch.commit() instead of an observable like for\r\n   * everything else.\r\n   *\r\n   * This method turns it into an observable\r\n   */\r\n  protected batchCommit$(batch: WriteBatch): Observable<void> {\r\n    return from(batch.commit()).pipe(\r\n      take(1)\r\n    );\r\n  }\r\n}\r\n\r\n\r\n/**\r\n * Firebase version 9 changed the query syntax\r\n * The new syntax broken the ability to chain queries like this:\r\n *\r\n * collectionRef.where('foo', '==', 123).limit(10)..returns the collection ref\r\n *\r\n * now instead you must write it like this, query(collectionRef, where('foo', '==', 123), limit(10))...returns a Query\r\n *\r\n * which is ugly and make you loose the information that was present in the collectionRef since a Query is returned instead,\r\n * which holds less information than a CollectionReference.\r\n *\r\n * This Container is meant to allow you to chain queries, like before version 9 and also retain the information in\r\n * the original CollectionReference\r\n */\r\nexport class QueryContainer<T> {\r\n\r\n  public queryConstraints: QueryConstraint[] = [];\r\n\r\n  constructor(public ref: CollectionReference<T>) {\r\n  }\r\n\r\n  /** factory method to create container from path */\r\n  static fromPath<T>(firestore: Firestore, path: string): QueryContainer<T> {\r\n    const ref = collection(firestore, path) as CollectionReference<T>;\r\n    return new this(ref);\r\n  }\r\n\r\n  /** Returns the query with all the query constraints */\r\n  get query(): Query<T> {\r\n    return query(this.ref, ...this.queryConstraints);\r\n  }\r\n\r\n  /** Calls the firebase getDocs() method and listens for the documents in the query. */\r\n  getDocs$(): Observable<QuerySnapshot<T>> {\r\n    return from(getDocs<T>(this.query));\r\n  }\r\n\r\n  where(fieldPath: string | FieldPath, opStr: WhereFilterOp, value: unknown): QueryContainer<T> {\r\n    this.queryConstraints.push(where(fieldPath, opStr, value));\r\n    return this;\r\n  }\r\n\r\n  orderBy(fieldPath: string | FieldPath, directionStr?: OrderByDirection): QueryContainer<T> {\r\n    this.queryConstraints.push(orderBy(fieldPath, directionStr));\r\n    return this;\r\n  }\r\n\r\n  limit(_limit: number): QueryContainer<T> {\r\n    this.queryConstraints.push(limit(_limit));\r\n    return this;\r\n  }\r\n\r\n  limitToLast(_limit: number): QueryContainer<T> {\r\n    this.queryConstraints.push(limitToLast(_limit));\r\n    return this;\r\n  }\r\n\r\n  startAt(...fieldValues: unknown[]): QueryContainer<T>; // definition\r\n  startAt(snapshot?: DocumentSnapshot<unknown>): QueryContainer<T>; // definition\r\n\r\n  startAt(snapshot?: DocumentSnapshot<unknown>, ...fieldValues: unknown[]): QueryContainer<T> { // implementation\r\n    if (snapshot) {\r\n      this.queryConstraints.push(startAt(snapshot));\r\n    } else if (fieldValues) {\r\n      this.queryConstraints.push(startAt(...fieldValues));\r\n    }\r\n    return this;\r\n  }\r\n\r\n  startAfter(...fieldValues: unknown[]): QueryContainer<T>; // definition\r\n  startAfter(snapshot?: DocumentSnapshot<unknown>): QueryContainer<T>; // definition\r\n\r\n  startAfter(snapshot?: DocumentSnapshot<unknown>, ...fieldValues: unknown[]): QueryContainer<T> { // implementation\r\n    if (snapshot) {\r\n      this.queryConstraints.push(startAfter(snapshot));\r\n    } else if (fieldValues) {\r\n      this.queryConstraints.push(startAfter(...fieldValues));\r\n    }\r\n    return this;\r\n  }\r\n\r\n  endAt(...fieldValues: unknown[]): QueryContainer<T>; // definition\r\n  endAt(snapshot?: DocumentSnapshot<unknown>): QueryContainer<T>; // definition\r\n\r\n  endAt(snapshot?: DocumentSnapshot<unknown>, ...fieldValues: unknown[]): QueryContainer<T> { // implementation\r\n    if (snapshot) {\r\n      this.queryConstraints.push(endAt(snapshot));\r\n    } else if (fieldValues) {\r\n      this.queryConstraints.push(endAt(...fieldValues));\r\n    }\r\n    return this;\r\n  }\r\n\r\n  endBefore(...fieldValues: unknown[]): QueryContainer<T>; // definition\r\n  endBefore(snapshot?: DocumentSnapshot<unknown>): QueryContainer<T>; // definition\r\n\r\n  endBefore(snapshot?: DocumentSnapshot<unknown>, ...fieldValues: unknown[]): QueryContainer<T> { // implementation\r\n    if (snapshot) {\r\n      this.queryConstraints.push(endBefore(snapshot));\r\n    } else if (fieldValues) {\r\n      this.queryConstraints.push(endBefore(...fieldValues));\r\n    }\r\n    return this;\r\n  }\r\n\r\n}\r\n","/* For Listening to a Doc and multiple sub collections in that doc */\r\n\r\nimport {QueryConstraint} from 'firebase/firestore';\r\n\r\n/**\r\n * For Listening to a Document and multiple sub Collections in that Document\r\n */\r\n\r\nexport interface SubCollectionQuery {\r\n\r\n  /** the name of the subCollection to be read. */\r\n  name: string;\r\n\r\n  /** Specified Document name if multiple documents in collection is not used */\r\n  docId?: string;\r\n\r\n  /** Any SubCollections to be read in the Collection */\r\n  subCollections?: SubCollectionQuery[];\r\n\r\n  /**\r\n   *\r\n   * The Collection QueryConstraint.\r\n   *\r\n   * In Firebase v.9 the queryFn was replaced with QueryConstraint\r\n   *\r\n   * Firebase v.9 Example:\r\n   * queryConstraints: [\r\n   *    where('type', '==', 'Book'),\r\n   *    where('price', '>' 18.00),\r\n   *    where(price', '<' 100.00),\r\n   *    where('category', '==', 'Fiction'),\r\n   *    where('publisher', '==', 'BigPublisher'),\r\n   *    orderBy('price'),\r\n   * ]\r\n   *\r\n   *\r\n   * Old Example < Firebase v.9 version:\r\n   * queryFn = ref.where('type', '==', 'Book')\r\n   *              .where('price', '>' 18.00)\r\n   *              .where('price', '<' 100.00)\r\n   *              .where('category', '==', 'Fiction')\r\n   *              .where('publisher', '==', 'BigPublisher')\r\n   *\r\n   */\r\n  queryConstraints?: QueryConstraint[];\r\n}\r\n","import { combineLatest, noop, Observable } from 'rxjs';\r\nimport {map, startWith, tap } from 'rxjs/operators';\r\n\r\nexport interface OperatorDict<X> {\r\n  [key: string]: Observable<X> | [Observable<X>, X];\r\n}\r\n\r\n/**\r\n * Extracts the type `T` of an `Observable<T>`\r\n */\r\nexport type ExtractObservableType<A> = A extends Observable<infer B> ? B : never;\r\n\r\n\r\nconst nop = <T>() => tap<T>(noop);\r\n\r\n/**\r\n * Takes a key/value object of observables or tuples:\r\n *\r\n * ```\r\n * {\r\n *  obs1: of(123),\r\n *  obs2: [of(\"value\").pipe(delay(1000)), \"startWith value\"],\r\n * }\r\n * ```\r\n *\r\n * and every time one of the source observables emits, emits an object\r\n * with the latest value from all observables:\r\n *\r\n * ```\r\n * {\r\n *  obs1: 123,\r\n *  obs2: \"startWith value\",\r\n * }\r\n * ```\r\n */\r\nexport const combineLatestToObject = <\r\n  TIn extends OperatorDict<any>, TOut extends { [K in keyof TIn]: ExtractObservableType<TIn[K]> }\r\n  // TOut extends { [K in keyof TIn]: ExtractObservableType<TIn[K] extends Array<any> ? TIn[K][0] : TIn[K]> }\r\n\r\n  >(observables: TIn): Observable<TOut> => {\r\n  const keys = Object.keys(observables);\r\n\r\n  return combineLatest(\r\n    keys.map(k => {\r\n      const obs = observables[k];\r\n\r\n      return Array.isArray(obs)\r\n        ? obs[0].pipe(startWith(obs[1]))\r\n        : obs.pipe( nop());\r\n    }),\r\n  ).pipe(\r\n    map(b => b.reduce((acc, val, i) => ({ ...acc, [keys[i]]: val }), {}))\r\n  );\r\n};\r\n","import {from, Observable} from 'rxjs';\r\nimport {BaseFirestoreWrapper} from './interfaces';\r\nimport {take} from 'rxjs/operators';\r\nimport {FirebaseApp} from 'firebase/app';\r\nimport {\r\n  addDoc,\r\n  CollectionReference,\r\n  deleteDoc,\r\n  DocumentData,\r\n  DocumentReference,\r\n  DocumentSnapshot,\r\n  Firestore,\r\n  FirestoreError,\r\n  getDoc,\r\n  getDocs,\r\n  getFirestore,\r\n  onSnapshot,\r\n  Query,\r\n  QuerySnapshot,\r\n  setDoc,\r\n  SetOptions,\r\n  UpdateData,\r\n  updateDoc,\r\n} from 'firebase/firestore';\r\n\r\n\r\nexport class FirestoreWrapper implements BaseFirestoreWrapper {\r\n  /**\r\n   * Uses firebase/firestore directly\r\n   * Simply makes the returned Promises into Observables\r\n   */\r\n\r\n  constructor(public firebaseApp: FirebaseApp) {\r\n  }\r\n\r\n  get firestore(): Firestore {\r\n    return getFirestore(this.firebaseApp);\r\n  }\r\n\r\n  public getDoc<T = DocumentData>(docRef: DocumentReference<T>): Observable<DocumentSnapshot<T>> {\r\n    return from(getDoc(docRef));\r\n  }\r\n\r\n  public listenForDoc<T = DocumentData>(docRef: DocumentReference<T>): Observable<DocumentSnapshot<T>> {\r\n    return new Observable<DocumentSnapshot<T>>(observer => {\r\n      return onSnapshot(\r\n        docRef,\r\n        (snapshot: DocumentSnapshot<T>) => observer.next(snapshot),\r\n        (error: FirestoreError) => {\r\n          observer.unsubscribe();\r\n          console.log('unsub doc', error);\r\n          return error;\r\n        },\r\n        () => {\r\n          observer.unsubscribe();\r\n          console.log('complete doc');\r\n        });\r\n    });\r\n  }\r\n\r\n  public add<T>(collectionRef: CollectionReference<T>, data: T): Observable<DocumentReference<T>> {\r\n    return from(addDoc(collectionRef, data)).pipe(\r\n      take(1)\r\n    );\r\n  }\r\n\r\n  public set<A>(docRef: DocumentReference<A>, data: A, options?: SetOptions): Observable<void> {\r\n\r\n    if (options) {\r\n      return from(setDoc(docRef, data, options)).pipe(\r\n        take(1)\r\n      );\r\n    } else {\r\n      return from(setDoc(docRef, data)).pipe(\r\n        take(1)\r\n      );\r\n    }\r\n  }\r\n\r\n  delete<T>(docRef: DocumentReference<T>): Observable<void> {\r\n    return from(deleteDoc(docRef)).pipe(\r\n      take(1)\r\n    );\r\n  }\r\n\r\n  update<T>(docRef: DocumentReference<T>, data: UpdateData<Partial<T>>, options?: SetOptions): Observable<void> {\r\n    return from(updateDoc<Partial<T>>(docRef, data)).pipe(\r\n      take(1)\r\n    );\r\n  }\r\n\r\n  public getCollection<T>(q: Query<T>): Observable<QuerySnapshot<T>> {\r\n    return from(getDocs(q));\r\n  }\r\n\r\n  public listenForCollection<T>(q: Query<T>): Observable<QuerySnapshot<T>> {\r\n\r\n    return new Observable<QuerySnapshot<T>>(observer => {\r\n      return onSnapshot(\r\n        q,\r\n        (snapshot: QuerySnapshot<T>) => observer.next(snapshot),\r\n        (error: FirestoreError) => {\r\n          observer.unsubscribe();\r\n          return error;\r\n        },\r\n        () => observer.unsubscribe());\r\n    });\r\n  }\r\n\r\n}\r\n\r\n\r\n\r\n","import {FirebaseApp} from 'firebase/app';\r\nimport {FirestoreWrapper} from './firestore-wrapper';\r\nimport {FirestoreExtended} from './firestore-extended';\r\n\r\n/**\r\n * FirestoreExt Class that uses the FirestoreWrapper\r\n * Simply extend this class and give it an initialized FirebaseApp to use the FireStoreExtended methods.\r\n */\r\nexport class FirestoreExt extends FirestoreExtended {\r\n  constructor(firebaseApp: FirebaseApp, defaultDocId: string = 'data') {\r\n    super(new FirestoreWrapper(firebaseApp), defaultDocId);\r\n  }\r\n}\r\n","// import {InjectionToken} from '@angular/core';\r\n// import {FirebaseApp} from 'firebase/app';\r\n\r\nexport class FirebaseConfig {\r\n  [key: string]: any;\r\n}\r\n\r\nexport interface EmulatorConfig {\r\n  // useEmulator: boolean;\r\n  host: string;\r\n  port: number;\r\n}\r\n\r\n// export const FIREBASE_APP = new InjectionToken<FirebaseApp>('firebase_app.config');\r\n\r\nexport const FIRESTORE_USE_EMULATOR: EmulatorConfig = {\r\n  // useEmulator: false,\r\n  host: 'localhost',\r\n  port: 8080,\r\n};\r\n\r\nexport const FIREBASE_FUNCTIONS_USE_EMULATOR: EmulatorConfig = {\r\n  // useEmulator: false,\r\n  host: 'localhost',\r\n  port: 5001,\r\n};\r\n\r\n// export type FirestoreEmulatorConfig  = {\r\n//   useEmulator: boolean;\r\n//   emulatorHost: string;\r\n//   emulatorPort: 4200\r\n// }\r\n","import {ModuleWithProviders, NgModule, Optional, SkipSelf} from '@angular/core';\r\nimport {CommonModule} from '@angular/common';\r\nimport {FirebaseConfig} from './config';\r\n\r\n\r\n@NgModule({\r\n  declarations: [],\r\n  imports: [\r\n    CommonModule\r\n  ]\r\n})\r\n\r\n\r\nexport class NgxFirebaseModule {\r\n  /**\r\n   * To be used as an Angular Module to inject the FirebaseConfig\r\n   * The FirebaseConfig is then used by NgxFirebaseService to create a Firebase app, this contains the websocket connection to firebase.\r\n   * We can then inject NgxRxFireService in to any service that wishes to use the Firebase app connection without creating\r\n   * additional connections.\r\n   * The purpose is simply to make sure that we only create a single Firebase App and a single connection\r\n   */\r\n  constructor(@Optional() @SkipSelf() parentModule?: NgxFirebaseModule) {\r\n    if (parentModule) {\r\n      throw new Error(\r\n        'NgxFirestoreExtendedModule is already loaded. Import it in the AppModule only');\r\n    }\r\n  }\r\n\r\n  static forRoot(config?: FirebaseConfig): ModuleWithProviders<NgxFirebaseModule> {\r\n    return {\r\n      ngModule: NgxFirebaseModule,\r\n      providers: [\r\n        {provide: FirebaseConfig, useValue: config}\r\n      ]\r\n    };\r\n  }\r\n\r\n}\r\n","import {Inject, Injectable, Optional} from '@angular/core';\r\n\r\nimport {EmulatorConfig, FIREBASE_FUNCTIONS_USE_EMULATOR, FirebaseConfig, FIRESTORE_USE_EMULATOR} from './config';\r\nimport {FirebaseApp, getApps, initializeApp} from 'firebase/app';\r\nimport {connectFirestoreEmulator, Firestore, getFirestore} from 'firebase/firestore';\r\nimport {connectFunctionsEmulator, Functions, getFunctions} from 'firebase/functions';\r\n\r\n@Injectable({\r\n  providedIn: 'root'\r\n})\r\n\r\n/**\r\n * Service that holds the Firebase App\r\n * Inject this service into any other service that requires the Firebase App and FirestoreExt\r\n *\r\n * ex.\r\n * export class SomeService() {\r\n *   construct(ngxFireStoreExtendedService: NgxFireStoreExtendedService) {\r\n *     fireExt = ngxFireStoreExtendedService.fireExt\r\n *   }\r\n * }\r\n *\r\n */\r\nexport class NgxFirebaseService {\r\n\r\n  public firebaseApp: FirebaseApp;\r\n\r\n  constructor(@Optional() config?: FirebaseConfig,\r\n              @Optional() @Inject(FIRESTORE_USE_EMULATOR) public firestoreEmulatorConfig?: EmulatorConfig,\r\n              @Optional() @Inject(FIREBASE_FUNCTIONS_USE_EMULATOR) public functionsEmulatorConfig?: EmulatorConfig) {\r\n\r\n    if (!getApps().length) {\r\n      if (config) {\r\n        this.firebaseApp = initializeApp(config);\r\n      } else {\r\n        throw new Error('No previous Firebase App initialized so please provide a FirebaseConfig');\r\n      }\r\n\r\n    } else {\r\n      this.firebaseApp = getApps()[0]; // if already initialized, use that one\r\n    }\r\n\r\n    if (firestoreEmulatorConfig) {\r\n      connectFirestoreEmulator(getFirestore(this.firebaseApp), firestoreEmulatorConfig.host, firestoreEmulatorConfig.port); // v9\r\n      // getFirestore(this.firebaseApp).useEmulator(emulatorConfig.host, emulatorConfig.port); // v8\r\n    }\r\n    if (functionsEmulatorConfig) {\r\n      connectFunctionsEmulator(getFunctions(this.firebaseApp), functionsEmulatorConfig.host, functionsEmulatorConfig.port); // v9\r\n    }\r\n\r\n    // TODO add emulator support for remaining firebase functionality\r\n\r\n  }\r\n\r\n  get firestore(): Firestore {\r\n    /** Convenience getter */\r\n    return getFirestore(this.firebaseApp);\r\n  }\r\n\r\n  get functions(): Functions {\r\n    /** Convenience getter */\r\n    return getFunctions(this.firebaseApp);\r\n  }\r\n}\r\n","import {Injectable} from '@angular/core';\r\nimport {FirebaseApp} from 'firebase/app';\r\nimport {FirestoreExt} from '../firestore-extended.class';\r\nimport {NgxFirebaseService} from './ngx-firebase.service';\r\nimport {Firestore} from 'firebase/firestore';\r\n\r\n\r\n@Injectable({\r\n  providedIn: 'root'\r\n})\r\n\r\n/**\r\n * Convenience Service meant to be injected\r\n * Inject this service into any other service that requires the Firebase App and FirestoreExt\r\n *\r\n */\r\nexport class NgxFirestoreExtService {\r\n\r\n  public firestoreExt: FirestoreExt;\r\n  public firestore: Firestore;\r\n  public firebaseApp: FirebaseApp;\r\n\r\n  constructor(ngxFirebaseService: NgxFirebaseService) {\r\n    this.firebaseApp = ngxFirebaseService.firebaseApp;\r\n    this.firestore = ngxFirebaseService.firestore;\r\n    this.firestoreExt = new FirestoreExt(this.firebaseApp);\r\n  }\r\n}\r\n","/*\r\n * Public API Surface of firestore-extended.ts\r\n */\r\n/* Base Api exports */\r\nexport * from './lib/models/fireItem';\r\nexport * from './lib/firestore-extended';\r\nexport * from './lib/sub-collection-query';\r\nexport * from './lib/sub-collection-writer';\r\nexport * from './lib/helpers';\r\nexport * from './lib/interfaces';\r\n\r\n/* Helper functions */\r\nexport * from './lib/rxjs-ops/combine-latest-to-object';\r\n\r\n/* Wrappers and Convenience Classes */\r\nexport * from './lib/firestore-extended.class';\r\nexport * from './lib/firestore-wrapper';\r\n\r\n/* Angular Exports */\r\nexport * from './lib/ngx/config';\r\nexport * from './lib/ngx/ngx-firebase.module';\r\nexport * from './lib/ngx/ngx-firebase.service';\r\nexport * from './lib/ngx/ngx-firestore-ext.service';\r\n\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}