Skip to content

Type-safe API + Auto-generated code using @annotations

Warning

Experimental

Dependencies

Add repository URL https://s01.oss.sonatype.org/content/repositories/snapshots/ for SNAPSHOT versions.

plugins {
    id("com.google.devtools.ksp")
    kotlin("plugin.serialization")
}

dependencies {
    implementation("io.firestore4k:typed-api:$latestVersion")
    compileOnly("io.firestore4k:annotations:$latestVersion")
    ksp("io.firestore4k:ksp:$latestVersion")
}

Model

Example

In the sample code below, we will define model for:

/users/{useri-d}/messages/{message-id}

So, we have 2 collections - users and messages, each of the collection have documents under them.

users will be a root collection.
messages will be a sub collection under users.

Entity classes

  • Define Kotlin data classs for the firestore documents.

Important

Annotate them with @kotlinx.serialization.Serializable

@io.firestore4k.typed.Collection("users")
@kotlinx.serialization.Serializable
data class User(
    val name: String,
    val email: String,
)

@io.firestore4k.typed.Collection("messages")
@io.firestore4k.typed.ChildOf("users")
@kotlinx.serialization.Serializable
data class Message(
    val from: String,
    val to: String,
    val subject: String,
    val body: String,
)

Identity classes

Define Kotlin value classs for IDs for type-safety.
This is optional, in which case, you may use String as IDs.

Important

override fun toString() to return the string id value.

@io.firestore4k.typed.IdOf("users")
@JvmInline
value class UserId(private val value: String) {
    override fun toString(): String = value
}

@io.firestore4k.typed.IdOf("messages")
@JvmInline
value class MessageId(private val value: String) {
    override fun toString(): String = value
}

Collections

These are auto-generated using KSP (Kotlin Symbol Processing) with help of annotations and ksp modules.

In typed-api without ksp and annotations, they have to be defined manually as shown here.

firestore path expression

DSL to express Firestore collection & document path.

// /users
users

// /users/user1
users / UserId("user1")

// /users/user1/message
users / UserId("user1") / messages

// /users/user1/message/message1
users / UserId("user1") / messages / MessageId("message1")

CRUD operations

These are same as typed-api without annotations and ksp, and are documented here

Future improvements

  • Option to pass class name in @io.firestore4k.typed.ChildOf
    • Ability to define parent and child Entity classes in different package / module.