Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import * as fb from "firebase";
- import { computed, observable, runInAction } from "mobx";
- type Query = fb.firestore.Query;
- type DocumentReference = fb.firestore.DocumentReference;
- type DocumentSnapshot = fb.firestore.DocumentSnapshot;
- type LoadingDocumentSnapshot = DocumentSnapshot | undefined;
- type Dictionary<T> = { [key: string]: T };
- // type QuerySnapshot = fb.firestore.QuerySnapshot;
- // type LoadingCollectionSnapshot = QuerySnapshot | undefined;
- export interface FireResource<T> {
- exists(): boolean;
- loading(): boolean;
- get(): T;
- }
- export class FireDocument<T> implements FireResource<T> {
- private name: string;
- @observable private _snapshot: LoadingDocumentSnapshot = undefined;
- @computed get snapshot() { return this._snapshot; }
- set snapshot(snapshot: LoadingDocumentSnapshot) { this._snapshot = snapshot; }
- constructor(doc: DocumentReference) {
- this.load(doc);
- }
- exists() {
- return this.snapshot !== undefined && this.snapshot.exists;
- }
- loading() {
- return this.snapshot === undefined;
- }
- get(): T {
- if (this.snapshot !== undefined && this.snapshot.exists) {
- return this.snapshot.data() as T;
- } else {
- throw new Error(`Snapshot for ${this.name} doesn't exist`);
- }
- }
- private async load(doc: DocumentReference) {
- this.snapshot = await doc.get();
- }
- }
- export class FireCollection<T, U = Dictionary<T>> implements FireResource<U> {
- private name: string;
- private filter: (doc: DocumentSnapshot) => boolean;
- private transform: (docs: DocumentSnapshot[]) => U;
- @observable private _snapshot: U | undefined = undefined;
- @observable private _exists: boolean = false;
- @computed get snapshot() { return this._snapshot; }
- set snapshot(snapshot: U | undefined) { this._snapshot = snapshot; }
- constructor(col: Query) {
- this.load(col);
- this.transform =
- (docs: DocumentSnapshot[]) =>
- Object.assign({}, ...docs.map(doc => ({ [doc.id]: doc.data() as T })));
- }
- loading() {
- return this.snapshot === undefined;
- }
- exists() {
- return this._exists;
- }
- setFilter(filter: (doc: DocumentSnapshot) => boolean) {
- this.filter = filter;
- }
- setTransform(transform: (docs: DocumentSnapshot[]) => U) {
- this.transform = transform;
- }
- get(): U {
- if (this.snapshot !== undefined && this.exists()) {
- return this.snapshot;
- } else {
- throw new Error(`Snapshot for ${this.name} doesn't exist`);
- }
- }
- private async load(col: Query) {
- const snapshot = await col.get();
- const filtered = snapshot.docs.filter(doc => this.filter ? this.filter(doc) : true);
- runInAction(() => this._exists = filtered.length > 0);
- this.snapshot = this.transform(filtered);
- }
- }
Add Comment
Please, Sign In to add comment