DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Proto DataStore: Type-Safe Settings with Protocol Buffers

Proto DataStore provides type-safe, serialized storage using Protocol Buffers. Learn definition, migration, and usage.

Define Proto Schema

Create src/main/proto/preferences.proto:

syntax = "proto3";

message UserPreferences {
    bool dark_mode = 1;
    string language = 2;
    int32 font_size = 3;
    repeated string favorite_topics = 4;
}
Enter fullscreen mode Exit fullscreen mode

Add Plugin Dependencies

plugins {
    id("com.google.protobuf") version "0.9.2"
}

dependencies {
    implementation("com.google.protobuf:protobuf-javalite:3.24.0")
    implementation("androidx.datastore:datastore:1.0.0")
}

protobuf {
    protoc { artifact = "com.google.protobuf:protoc:3.24.0" }
    generateProtoTasks {
        all().forEach { task ->
            task.builtins { remove("java") }
            task.builtins { create("javalite") }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Create DataStore Instance

import androidx.datastore.core.DataStore
import androidx.datastore.core.Serializer
import androidx.datastore.dataStore

private val Context.userPreferencesDataStore: DataStore<UserPreferences> by dataStore(
    fileName = "user_prefs.pb",
    serializer = UserPreferencesSerializer
)

object UserPreferencesSerializer : Serializer<UserPreferences> {
    override val defaultValue: UserPreferences = UserPreferences.getDefaultInstance()

    override suspend fun readFrom(input: InputStream): UserPreferences {
        return try {
            UserPreferences.parseFrom(input)
        } catch (e: InvalidProtocolBufferException) {
            defaultValue
        }
    }

    override suspend fun writeTo(t: UserPreferences, output: OutputStream) {
        t.writeTo(output)
    }
}
Enter fullscreen mode Exit fullscreen mode

Read and Write

// Read
val preferences = context.userPreferencesDataStore.data
    .map { prefs -> prefs.darkMode }
    .stateIn(scope, SharingStarted.Lazily, false)

// Write
viewModelScope.launch {
    context.userPreferencesDataStore.updateData { prefs ->
        prefs.toBuilder().setDarkMode(true).build()
    }
}
Enter fullscreen mode Exit fullscreen mode

Proto DataStore enforces strong typing and binary compatibility. Ideal for large, structured settings. Migration from Preferences DataStore requires manual copy logic.


8 Android app templates (Habit Tracker, Budget Manager, Task Manager, and more) available on Gumroad

Top comments (0)