Skip to content

Instantly share code, notes, and snippets.

@popocreator
Last active April 26, 2024 02:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save popocreator/e6485356958740c0d8032637104be7e3 to your computer and use it in GitHub Desktop.
Save popocreator/e6485356958740c0d8032637104be7e3 to your computer and use it in GitHub Desktop.
// export default interface Entity {
// fid?: string; // firestoreId
// delYn?: string;
// ...
// }
import Entity from '@/models/Entity';
import {ReactNativeFirebase} from '@react-native-firebase/app';
import firestore, {
FirebaseFirestoreTypes,
} from '@react-native-firebase/firestore';
export default class Repository<T extends Entity> {
database;
path;
validate;
normalize;
constructor({
database = firestore,
path,
validate,
normalize,
}: {
database?: ReactNativeFirebase.FirebaseModuleWithStaticsAndApp<
FirebaseFirestoreTypes.Module,
FirebaseFirestoreTypes.Statics
>;
path: string;
validate: (
data: FirebaseFirestoreTypes.DocumentData,
) => FirebaseFirestoreTypes.DocumentData;
normalize: (
data: FirebaseFirestoreTypes.DocumentData,
) => FirebaseFirestoreTypes.DocumentData;
}) {
this.database = database;
this.path = path;
this.validate = validate;
this.normalize = normalize;
}
// Handler
queryDocumentToEntity({
id: fid,
data,
}: FirebaseFirestoreTypes.QueryDocumentSnapshot<FirebaseFirestoreTypes.DocumentData>) {
return this.makeEntity({fid, ...data()});
}
documentToEntity(doc: FirebaseFirestoreTypes.DocumentData) {
return this.makeEntity(doc);
}
makeEntity(data: FirebaseFirestoreTypes.DocumentData): T {
const validData = this.validate(data);
const normalizeData = this.normalize(validData);
return Object.freeze(normalizeData as T);
}
// return
save(
transactionOrBatch:
| FirebaseFirestoreTypes.Transaction
| FirebaseFirestoreTypes.WriteBatch,
entity: T,
): T {
const db = this.database();
const collection = db.collection(this.path);
if (entity.fid) {
// Update
const ref = collection.doc(entity.fid);
const savedEntity = transactionOrBatch.set(ref, entity);
return this.documentToEntity(savedEntity);
} else {
// Add
const id = collection.doc().id;
const ref = collection.doc(id);
const savedEntity = transactionOrBatch.set(ref, {fid: id, ...entity});
return this.documentToEntity(savedEntity);
}
}
saveAll(
transactionOrBatch:
| FirebaseFirestoreTypes.Transaction
| FirebaseFirestoreTypes.WriteBatch,
entityList: T[],
): T[] {
return entityList.map(entity => {
return this.save(transactionOrBatch, entity);
});
}
async findById(
transaction: FirebaseFirestoreTypes.Transaction,
{fid}: T,
): Promise<T> {
const db = this.database();
const collection = db.collection(this.path);
const ref = collection.doc(fid);
const entity = await transaction.get(ref);
return this.documentToEntity(entity);
}
async getItems({
max = 100,
before,
after,
}: {
max: number;
before?: boolean;
after?: boolean;
}): Promise<T[]> {
const db = this.database();
const collection = db.collection(this.path);
let query = collection.where('delYn', '==', 'N');
if (before) {
query = query
.where('regDate', '<', before)
.orderBy('regDate', 'asc')
.limit(max);
} else if (after) {
query = query
.where('regDate', '>', after)
.orderBy('regDate', 'asc')
.limit(max);
} else {
return [];
}
return (await query.get()).docs.map(doc => this.queryDocumentToEntity(doc));
}
remove(
transactionOrBatch:
| FirebaseFirestoreTypes.Transaction
| FirebaseFirestoreTypes.WriteBatch,
entity: T,
): T {
const db = this.database();
const collection = db.collection(this.path);
const ref = collection.doc(entity.fid);
const deletedEntity = transactionOrBatch.set(ref, {
...entity,
delYn: 'Y',
});
// const deletedEntity = transactionOrBatch.delete(ref); // Delete.
return this.documentToEntity(deletedEntity);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment