Skip to content

Instantly share code, notes, and snippets.

Last active Aug 9, 2022
What would you like to do?
Using Firestore with Typescript
* This Gist is part of a medium article - read here:
// 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) => 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 } =
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 })
Copy link

MatthewLymer commented Sep 2, 2021

Why do you need to create a convert and call withConverter when you can simply cast the collection? All of the methods off of CollectionReference<T> are already typed (such as .doc, etc.)

const dataPoint = <T>(collectionPath: string) => firestore().collection(collectionPath) as CollectionReference<T>;

FireStore converters are intended to convert between the in-memory type representation and the persisted representation.

Copy link

spencercap commented Sep 24, 2021

🙌 NICE ! thanks @JamieCurnow

Copy link

yurist38 commented Oct 16, 2021

This helped a lot! Thanks @JamieCurnow

Copy link

michaelmok2021 commented Dec 31, 2021

@JamieCurnow can you add to this GIST an example to return all objects in the users collection? Thanks.

Copy link

smikheiev commented Jan 11, 2022

Thanks, @JamieCurnow! Nice stuff!
What about serverTimestamp? With serverTimestamp, toFirestore should have FieldValue type, and fromFirestore should have Timestamp type, but converter accepts only one data type. Is there a way to make it work? 🤔

Copy link

tohagan commented Jan 20, 2022

@smikheiev For your timestamp fields use this typescript type ...

export type Timestamp = admin.firestore.Timestamp | admin.firestore.FieldValue;

... so you can assign a value like ...

  updatedAt: FieldValue.serverTimestamp()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment