2023-02-18

Different Read/Write types for FirestoreDataConverter

Is there a way to use different types for reading and writing data using the FirebaseDataConverter?

The typing of FirebaseDataConverter<T> suggest that there should only be a single type T, which is both what you would get back when querying and what you should provide when writing.

But in the scenario outlined below, I have two types, InsertComment which is what I should provide when creating a new comment, and Comment, which is an enriched object that has the user's current name and the firebase path of the object added to it.

But there is no way to express that I have these two types. Am I missing something?

type Comment = { userId: string, userName: string, comment: string, _firebasePath: string }
type InsertComment = { userId: string, comment: string }
function lookupName(_id: string) { return 'Steve' }

const commentConverter: FirestoreDataConverter<Comment> = {
    fromFirestore(snapshot, options) {
        const { userId, comment } = snapshot.data(options)
        return {
            userId,
            comment,
            name: lookupName(userId),
            _firebasePath: snapshot.ref.path,
        } as any as Comment
    },
    // Here I wish I could write the below, but it gives me a type error
    // toFirestore(modelObject: InsertComment) {
    toFirestore(modelObject) {
        return modelObject
    },
}
const commentCollection = collection(getFirestore(), 'Comments').withConverter(commentConverter)

// This works great and is typesafe
getDocs(commentCollection).then(snaps => {
    snaps.docs.forEach(snap => {
        const { comment, userName, _firebasePath } = snap.data()
        console.info(`${userName} said "${comment}" (path: ${_firebasePath})`)
    })
})

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// This gives me the type-error: that fields "userName, _firebasePath" are missing
addDoc(commentCollection, { comment: 'Hello World', userId: '123' })


No comments:

Post a Comment