How to type-safely interact with Firestore documents

## The problem
When using Typescript and Firestore, we usually have to do a lot of manual casting when working with documents. One such example would be getting the data of a document:
```ts
const thread = threadDocument.data(); // this will be of type any
```
Should we want to interact with the data in a type-safe manner, we'll have to cast it, which can quickly become tedious.
```ts
const thread = <ThreadData>threadDocument.data();
```
Additionally, when we write data to Firestore, there are no restrictions on how the data should look.

## The solution
This is when *Firestore Data Converters* can come in handy. All we have to do is implement two methods - one where we constrain the data that gets written and one where we cast the data coming from Firestore: 

```ts
const converter = {
  toFirestore: (dataToBeWritten: ThreadData) => data,
  fromFirestore: (document: QueryDocumentSnapshot) => <ThreadData>document.data(),
};
```
To take this one step further, we can store the "converted" collection reference so we won't have to apply the converters each time we query the collection:
```ts
const threadCollection = db.collection("threads").withConverter(converter);
```
Now we can safely interact with the collection without having to cast the data:
```ts
const threadDocument = await threadCollection.doc(id).get();
const thread = threadDocument.data(); // this will be of type ThreadData
```

Denisa Halmaghi
03 Oct 2022
« Back to post