Last active
September 30, 2025 14:14
-
-
Save JamieCurnow/cba3968a7f1e335d473632f9fc9f6e8b to your computer and use it in GitHub Desktop.
Using Firestore with Typescript
This file contains hidden or 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
| /** | |
| * This Gist is part of a medium article - read here: | |
| * https://jamiecurnow.medium.com/using-firestore-with-typescript-65bd2a602945 | |
| */ | |
| // import firstore (obviously) | |
| import { firestore } from "firebase-admin" | |
| // Import or define your types | |
| // import { YourType } from '~/@types' | |
| interface YourType { | |
| firstName: string | |
| lastName: string | |
| isGreat: boolean | |
| blackLivesMatter: true | |
| } | |
| interface YourOtherType { | |
| something: boolean | |
| somethingElse: boolean | |
| } | |
| // This helper function pipes your types through a firestore converter | |
| const converter = <T>() => ({ | |
| toFirestore: (data: Partial<T>) => data, | |
| fromFirestore: (snap: FirebaseFirestore.QueryDocumentSnapshot) => snap.data() as T | |
| }) | |
| // This helper function exposes a 'typed' version of firestore().collection(collectionPath) | |
| // Pass it a collectionPath string as the path to the collection in firestore | |
| // Pass it a type argument representing the 'type' (schema) of the docs in the collection | |
| const dataPoint = <T>(collectionPath: string) => firestore().collection(collectionPath).withConverter(converter<T>()) | |
| // Construct a database helper object | |
| const db = { | |
| // list your collections here | |
| users: dataPoint<YourType>('users'), | |
| userPosts: (userId: string) => dataPoint<YourOtherType>(`users/${userId}/posts`) | |
| } | |
| // export your helper | |
| export { db } | |
| export default db | |
| /** | |
| * Some examples of how to use: | |
| */ | |
| const example = async (id: string) => { | |
| // firestore just as you know it, but with types | |
| const userDoc = await db.users.doc(id).get() | |
| const { blackLivesMatter } = userDoc.data() | |
| return blackLivesMatter === true // obviously | |
| } | |
| const createExample = async (userId: string) => { | |
| await db.userPosts(userId).doc().create({ | |
| something: false, | |
| somethingElse: true | |
| }) | |
| } | |
| // Always use set for updates as firestore doesn't type update function correctly yet! | |
| const updateExample = async (id: string) => { | |
| await db.users.doc(id).set({ | |
| firstName: 'Jamie', | |
| blackLivesMatter: true | |
| }, { merge: true }) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@drichar hi, this is very nice function. Actually I have a question about this, if the data class model have a Date type, when get the data from forestore, it should transfer Timestamp type to typescript Date type. Another question is that, how to support FieldValue type for data class model. For example: