Settings & Preferences

The classic SharedPreferences/NSUserDefaults job — theme, locale, feature flags, onboarding state — except typed and observable instead of a flat string-keyed bag.

@Serializable
enum class Theme { SYSTEM, LIGHT, DARK }

@Serializable
data class AppSettings(
    val theme: Theme = Theme.SYSTEM,
    val locale: String = "en-US",
    val hasCompletedOnboarding: Boolean = false,
)

class SettingsRepository {
    private val doc = Documents.document<AppSettings>("app-settings")

    var theme: Theme by doc.field(AppSettings::theme, default = Theme.SYSTEM)
    var locale: String by doc.field(AppSettings::locale, default = "en-US")

    val themeFlow: Flow<Theme> = doc.fieldFlow(AppSettings::theme, default = Theme.SYSTEM)
}

Each setting reads and writes as an ordinary property — flipping theme touches only that field's key, and themeFlow lets a UI layer re-render the instant it changes, with no polling and no re-reading the rest of the settings object. See Field Delegates for the full mechanics of field() and fieldFlow().