Last active
April 26, 2024 02:25
-
-
Save popocreator/e6485356958740c0d8032637104be7e3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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