Skip to content

Commit

Permalink
feat: added create to FirestoreDocumentDataAccessor
Browse files Browse the repository at this point in the history
  • Loading branch information
dereekb committed Jun 16, 2022
1 parent 6be4cd5 commit 9211975
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export class WriteBatchFirestoreDocumentDataAccessor<T> implements FirestoreDocu
return from(this.get()); // todo
}

create(data: WithFieldValue<T>): Promise<void> {
this.batch.create(this.documentRef, data);
return Promise.resolve();
}

exists(): Promise<boolean> {
return this.get().then((x) => x.exists);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export class DefaultFirestoreDocumentDataAccessor<T> implements FirestoreDocumen
return streamFromOnSnapshot(({ next, error }) => this.documentRef.onSnapshot(next, error));
}

create(data: T): Promise<GoogleCloudWriteResult> {
return this.documentRef.create(data);
}

exists(): Promise<boolean> {
return this.get().then((x) => x.exists);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ export class TransactionFirestoreDocumentDataAccessor<T> implements FirestoreDoc
return from(this.get());
}

create(data: WithFieldValue<T>): Promise<void> {
this.transaction.create(this.documentRef, data);
return Promise.resolve();
}

exists(): Promise<boolean> {
return this.get().then((x) => x.exists);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { DocumentReference, DocumentSnapshot, getDoc, WriteBatch as FirebaseFirestoreWriteBatch, UpdateData as FirestoreUpdateData } from '@firebase/firestore';
import { from, Observable } from 'rxjs';
import { FirestoreDocumentContext, UpdateData, WithFieldValue, FirestoreDocumentContextType, FirestoreDocumentDataAccessor, FirestoreDocumentDataAccessorFactory, SetOptions } from '../../common/firestore';
import { createWithAccessor } from './driver.accessor.create';

// MARK: Accessor
/**
Expand All @@ -13,6 +14,10 @@ export class WriteBatchFirestoreDocumentDataAccessor<T> implements FirestoreDocu
return from(this.get());
}

create(data: WithFieldValue<T>): Promise<void> {
return createWithAccessor(this)(data) as Promise<void>;
}

exists(): Promise<boolean> {
return this.get().then((x) => x.exists());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { FirestoreDocumentDataAccessor } from '../../common/firestore/accessor/accessor';
import { WithFieldValue, WriteResult } from '../../common/firestore/types';

export function createWithAccessor<T>(accessor: FirestoreDocumentDataAccessor<T>): (data: WithFieldValue<T>) => Promise<void | WriteResult> {
return (data: WithFieldValue<T>) => {
return accessor.exists().then((exists) => {
if (exists) {
throw new Error('document exists');
} else {
return accessor.set(data);
}
});
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { DocumentReference, DocumentSnapshot, UpdateData, WithFieldValue, getDoc
import { fromRef } from 'rxfire/firestore';
import { Observable } from 'rxjs';
import { FirestoreDocumentContext, FirestoreDocumentContextType, FirestoreDocumentDataAccessor, FirestoreDocumentDataAccessorFactory, SetOptions } from '../../common/firestore';
import { createWithAccessor } from './driver.accessor.create';

// MARK: Accessor
export class DefaultFirestoreDocumentDataAccessor<T> implements FirestoreDocumentDataAccessor<T> {
Expand All @@ -11,6 +12,10 @@ export class DefaultFirestoreDocumentDataAccessor<T> implements FirestoreDocumen
return fromRef(this.documentRef);
}

create(data: WithFieldValue<T>): Promise<void> {
return createWithAccessor(this)(data) as Promise<void>;
}

exists(): Promise<boolean> {
return this.get().then((x) => x.exists());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { DocumentReference, DocumentSnapshot, Transaction as FirebaseFirestoreTransaction, UpdateData, WithFieldValue } from '@firebase/firestore';
import { from, Observable } from 'rxjs';
import { FirestoreDocumentDataAccessor, FirestoreDocumentDataAccessorFactory, FirestoreDocumentContext, FirestoreDocumentContextType, SetOptions } from '../../common/firestore';
import { createWithAccessor } from './driver.accessor.create';

// MARK: Accessor
/**
Expand All @@ -13,6 +14,10 @@ export class TransactionFirestoreDocumentDataAccessor<T> implements FirestoreDoc
return from(this.get());
}

create(data: WithFieldValue<T>): Promise<void> {
return createWithAccessor(this)(data) as Promise<void>;
}

exists(): Promise<boolean> {
return this.get().then((x) => x.exists());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export interface FirestoreDocumentDataAccessor<T, D = DocumentData> extends Docu
* Returns a database stream of DocumentSnapshots.
*/
stream(): Observable<DocumentSnapshot<T>>;
/**
* Creates a document if it does not exist.
*/
create(data: WithFieldValue<T>): Promise<WriteResult | void>;
/**
* Returns the current snapshot.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export abstract class AbstractFirestoreDocumentDataAccessorWrapper<T, D = Docume
return this.accessor.stream();
}

create(data: WithFieldValue<T>): Promise<WriteResult | void> {
return this.accessor.create(data);
}

get(): Promise<DocumentSnapshot<T>> {
return this.accessor.get();
}
Expand Down
30 changes: 30 additions & 0 deletions packages/firebase/test/src/lib/common/test.driver.accessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,36 @@ export function describeAccessorTests<T>(init: () => DescribeAccessorTests<T>) {
});
});

describe('create()', () => {
it('should create the document if it does not exist.', async () => {
const data = await c.accessor.get();

await c.accessor.delete();

let exists = await c.accessor.exists();
expect(exists).toBe(false);

await c.accessor.create(data);

exists = await c.accessor.exists();
expect(exists).toBe(true);
});

it('should throw an exception if the document exists.', async () => {
const data = await c.accessor.get();

const exists = await c.accessor.exists();
expect(exists).toBe(true);

try {
await c.accessor.create(data);
fail();
} catch (e) {
expect(e).toBeDefined();
}
});
});

describe('get()', () => {
it('should return a snapshot', async () => {
const result = await c.accessor.get();
Expand Down

0 comments on commit 9211975

Please sign in to comment.