Supabase Reference (Kotlin) # Kotlin Reference Initializing ### Create Supabase Client Independently of which Supabase module you are using, you will need to initialize the main client first and install the module. To create a new client, you can use the `createSupabaseClient` function. When installing a module, you can pass a block to configure it. ### OAuth and OTP link verification [supabase-kt](https://github.com/supabase-community/supabase-kt) provides several platform implementations for OAuth and OTP link verification. \ **On JVM**, it uses a HTTP Callback Server to receive the session data from a successful OAuth login. *Note: OTP link verification such as sign ups are not supported on JVM. You may have to send a verification token rather than a url in your E-Mail. To send the token, rather than a redirect url, you have to change `{{ .ConfirmationURL }}` in your sign up email to `{{ .Token }}`* **On Android, IOS & macOS**, it uses deeplinks. Refer to the guide below on how to setup deeplinks. Alternatively you could use Native Google Auth or a WebView for OAuth. Refer to our [demo](https://github.com/supabase-community/supabase-kt/tree/master/demos/android-login) to learn more. **On JS**, it uses the website origin as the callback url. Session importing gets handled automatically. **Windows, tvOS, watchOS & Linux** currently have no default implementation. Feel free to create a PR. You always make your own implementation and use `gotrue.parseSessionFromFragment(fragment)` or `gotrue.parseSessionFromUrl(url)` to let [supabase-kt](https://github.com/supabase-community/supabase-kt) handle the parsing after receiving a callback. Then you can simply use `gotrue.importSession(session)`. ### Configure deeplink callbacks for Authentication Deeplinks are supported on Android, IOS and macOS. 1. **Setup a deeplink for you app** \ On Android you may setup a [deeplink](https://developer.android.com/training/app-links/deep-linking) in your Android manifest. \ On IOS & macOS you may setup a [url scheme](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app). 2. **Add your deeplink to the [redirect URLs](https://supabase.com/dashboard/project/_/auth/url-configuration)** \ **Pattern**: scheme://host 3. **Configure the GoTrue plugin** You have to set the `host` and the `scheme` in the GoTrue config: ```kotlin install(GoTrue) { host = "deeplink host" // this can be anything, eg. your package name or app/company url (not your supabase url) scheme = "deeplink scheme" //Android only, you can also change that OAuth/SSO logins open in a custom tab, rather than an external browser: defaultExternalAuthAction = ExternalAuthAction.CUSTOM_TABS //defaults to EXTERNAL_BROWSER } ``` 4. **Call platform specific function on startup** \ On Android: `supabase.handleDeeplinks(intent)` \ On IOS/macOS: `supabase.handleDeeplinks(url)` Then you can just login using OAuth: ```kotlin supabase.gotrue.loginWith(Google) ``` Or open OTP links directly in your app. ### PKCE Authentication flow supabase-kt supports the [PKCE authentication flow](https://supabase.com/blog/supabase-auth-sso-pkce). To use it, you just have to change the `flowType` in the GoTrue configuration: ```kotlin install(GoTrue) { flowType = FlowType.PKCE } ``` That's it! If you already implemented deeplinks to handle OTPs and OAuth you don't have to change anything! ## Examples ### Initialize Client ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "public-anon-key" ) { install(GoTrue) install(Postgrest) //install other modules } ``` ### Configure GoTrue module ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "public-anon-key" ) { install(GoTrue) { alwaysAutoRefresh = false // default: true autoLoadFromStorage = false // default: true //and more... } } ``` ### Configure PostgREST module ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "public-anon-key" ) { install(Postgrest) { defaultSchema = "schema" // default: "public" propertyConversionMethod = PropertyConversionMethod.SERIAL_NAME // default: PropertyConversionMethod.CAMEL_CASE_TO_SNAKE_CASE } } ``` ### Configure Storage module ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "public-anon-key" ) { install(Storage) { transferTimeout = 90.seconds // Default: 120 seconds } } ``` ### Configure Realtime module ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "public-anon-key" ) { install(Realtime) { reconnectDelay = 5.seconds // Default: 7 seconds } } ``` ### Configure Functions plugin ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "public-anon-key" ) { install(Functions) { //no custom settings } } ``` ### Configure GraphQL plugin ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "public-anon-key" ) { install(GraphQL) { apolloConfiguration { //custom configuration } } } ``` # Kotlin Reference Fetch data: select() ## Examples ### Getting your data ```kotlin val city = supabase.postgrest["cities"].select().decodeSingle() ``` ### Selecting specific columns ```kotlin val city = supabase.postgrest["cities"].select(columns = Columns.list("id, name")).decodeSingle() ``` ### Query foreign tables ```kotlin val country = supabase.postgrest["countries"] .select( columns = Columns.raw( """ id, name, cities ( id, name ) """) ) .decodeSingle() ``` ### Query the same foreign table multiple times ```kotlin val message = supabase.postgrest["messages"] .select(columns = Columns.raw( """ content, from: sender_id(name), to: receiver_id(name) """)) .decodeSingle() ``` ### Querying with count option ```kotlin val count = supabase.postgrest["countries"] .select(head = true, count = Count.EXACT) .count()!! ``` ### Querying JSON data ```kotlin val user = supabase.postgrest["users"] .select(columns = Columns.raw( """ id, name address->city """) .decodeSingle() ``` # Kotlin Reference Create data: insert() ## Examples ### Create a record ```kotlin val city = City(name = "The Shire", countryId = 554) supabase.postgrest["cities"].insert(city, returning = Returning.MINIMAL) //returning defaults to Returning.REPRESENTATION ``` ### Bulk create ```kotlin val theShire = City(name = "The Shire", countryId = 554) val rohan = City(name = "Rohan", countryId = 554) supabase.postgrest["cities"].insert(listOf(theShire, rohan), returning = Returning.MINIMAL) //returning defaults to Returning.REPRESENTATION ``` ### Fetch inserted record ```kotlin val theShire = City(name = "The Shire", countryId = 554) val rohan = City(name = "Rohan", countryId = 554) val result = supabase.postgrest["cities"].insert(listOf(theShire, rohan)).decodeList() ``` # Kotlin Reference Modify data: update() ## Examples ### Updating your data ```kotlin supabase.postgrest["characters"].update( { Character::name setTo "Han Solo" //or set("name", "Han Solo") } ) { Character::id eq 1 //or eq("id", 1) } ``` ### Update a record and return it ```kotlin val newCharacter = supabase.postgrest["characters"].update( { Character::name setTo "Han Solo" //or set("name", "Han Solo") } ) { Character::id eq 1 //or eq("id", 1) }.decodeSingle() ``` ### Updating JSON data ```kotlin val address = Address(street = "Melrose Place", postcode = 90210) supabase.postgrest["users"].update( { User::address setTo address } ) { User::id eq 1 //or eq("address->postcode", 90210) }.decodeSingle() ``` # Kotlin Reference Upsert data: upsert() ## Examples ### Upsert your data ```kotlin val toUpsert = Message(id = 3, message = "foo", username = "supabot") supabase.postgrest["messages"].insert(toUpsert, upsert = true) ``` ### Upserting into tables with constraints ```kotlin let toUpsert = User(username = "supabot") supabase.postgrest["users"].insert(toUpsert, upsert = true, onConflict = "username") ``` ### Return the exact number of rows ```kotlin let toUpsert = User(username = "supabot") val count = supabase.postgrest["users"].insert(toUpsert, upsert = true, onConflict = "username", count = Count.EXACT).count() ``` # Kotlin Reference Delete data: delete() ## Examples ### Delete records ```kotlin supabase.postgrest["cities"].delete { City::id eq 666 //or eq("id", 666) } ``` ### Fetch deleted records ```kotlin val deletedCity = supabase.postgrest["cities"].delete { City::id eq 666 //or eq("id", 666) }.decodeSingle() ``` # Kotlin Reference Stored Procedures: rpc() You can call stored procedures as a "Remote Procedure Call". That's a fancy way of saying that you can put some logic into your database then call it from anywhere. It's especially useful when the logic rarely changes - like password resets and updates. - When calling `rpc` with parameters, you have to provide a [serializable value](/docs/reference/kotlin/installing#serialization) in the function parameter. ## Examples ### Call a stored procedure ```kotlin supabase.postgrest.rpc("hello_world") ``` ### With Parameters ```kotlin val rpcParams = City(name = "The Shire") supabase.postgrest.rpc("echo_city", rpcParams) ``` # Kotlin Reference Using Filters Filters allow you to only return rows that match certain conditions. Filters can be used on `select()`, `update()`, and `delete()` queries. You can use two different types for applying filters: ```kotlin eq("country_id", 1) ``` And using a class property: ```kotlin City::countryId eq 1 ``` As you can see on the property syntax: the name of the `countryId` gets converted to `country_id`. By default, this is done by converting camel case to snake case, but you can customize this by changing the `PropertyConversionMethod` in the Postgrest Config If a database function returns a table response, you can also apply filters. ## Examples ### Applying a filter block ```kotlin supabase.postgrest["cities"].select(columns = Columns.list("name", "country_id")) { City::name eq "The Shire" //or eq("name", "The Shire") } ``` ### Multiple filters on one column ```kotlin supabase.postgrest["characters"].select(columns = Columns.list("name, book_id")) { and { //when both are true Character::age gt 10 Character::age lt 150 } or { //when either one of the filters are true Character::name eq "Harry" Character::name eq "Dumbledore" } } ``` ### Filter by values within a JSON column ```kotlin supabase.postgrest["users"].select { eq("address->postcode", 90210) } ``` ### Filter Foreign Tables ```kotlin supabase.postgrest["orchestral_sections"].select( columns = Columns.raw(""" name, instruments!inner ( name ) """) ) { eq("instruments.name", "flute") } ``` # Kotlin Reference eq() Finds all rows whose value on the stated `column` exactly matches the specified `value`. ## Examples ### With `select()` ```kotlin supabase.postgrest["cities"].select(columns = Columns.list("name", "country_id")) { City::name eq "The Shire" //or eq("name", "The Shire") } ``` ### With `update()` ```kotlin val toUpdate = City(name = "Mordor") supabase.postgrest["cities"].update(toUpdate) { City::name eq "The Shire" //or eq("name", "The Shire") } ``` ### With `delete()` ```kotlin supabase.postgrest["cities"].delete { City::name eq "Mordor" //or eq("name", "Mordor") } ``` ### With `rpc()` ```kotlin supabase.postgrest.rpc("function") { City::name eq "Mordor" //or eq("name", "Mordor") } ``` # Kotlin Reference neq() Finds all rows whose value on the stated `column` doesn't match the specified `value`. ## Examples ### With `select()` ```kotlin supabase.postgrest["cities"].select(columns = Columns.list("name", "country_id")) { City::name neq "The Shire" //or neq("name", "The Shire") } ``` ### With `update()` ```kotlin val toUpdate = City(name = "Mordor") supabase.postgrest["cities"].update(toUpdate) { City::name neq "The Shire" //or neq("name", "The Shire") } ``` ### With `delete()` ```kotlin supabase.postgrest["cities"].delete { City::name neq "The Shire" //or neq("name", "The Shire") } ``` ### With `rpc()` ```kotlin supabase.rpc("echo_all_cities") { neq("address->postcode", 90210) } ``` # Kotlin Reference gt() Finds all rows whose value on the stated `column` is greater than the specified `value`. ## Examples ### With `select()` ```kotlin supabase.postgrest["cities"].select(columns = Columns.list("name")) { City::countryId gt 300 //or gt("country_id", 300) } ``` ### With `update()` ```kotlin val toUpdate = City(name = "Mordor") supabase.postgrest["cities"].update(toUpdate) { City::countryId gt 300 //or gt("country_id", 300) } ``` ### With `delete()` ```kotlin supabase.postgrest["cities"].delete { City::countryId gt 300 //or gt("country_id", 300) } ``` ### With `rpc()` ```kotlin supabase.postgrest.rpc("echo_all_cities") { City::countryId gt 250 //or gt("country_id", 300) } ``` # Kotlin Reference gte() Finds all rows whose value on the stated `column` is greater than or equal to the specified `value`. ## Examples ### With `select()` ```kotlin supabase.postgrest["cities"].select(columns = Columns.list("name")) { City::countryId gte 300 //or gte("country_id", 300) } ``` ### With `update()` ```kotlin val toUpdate = City(name = "Mordor") supabase.postgrest["cities"].update(toUpdate) { City::countryId gte 300 //or gte("country_id", 300) } ``` ### With `delete()` ```kotlin supabase.postgrest["cities"].delete { City::countryId gte 300 //or gte("country_id", 300) } ``` ### With `rpc()` ```kotlin supabase.postgrest.rpc("echo_all_cities") { City::countryId gte 250 //or gte("country_id", 300) } ``` # Kotlin Reference lt() Finds all rows whose value on the stated `column` is less than the specified `value`. ## Examples ### With `select()` ```kotlin supabase.postgrest["cities"].select(columns = Columns.list("name")) { City::countryId lt 300 //or lt("country_id", 300) } ``` ### With `update()` ```kotlin val toUpdate = City(name = "Mordor") supabase.postgrest["cities"].update(toUpdate) { City::countryId lt 300 //or lt("country_id", 300) } ``` ### With `delete()` ```kotlin supabase.postgrest["cities"].delete { City::countryId lt 300 //or lt("country_id", 300) } ``` ### With `rpc()` ```kotlin supabase.postgrest.rpc("echo_all_cities") { City::countryId lt 250 //or lt("country_id", 300) } ``` # Kotlin Reference lte() Finds all rows whose value on the stated `column` is less than or equal to the specified `value`. ## Examples ### With `select()` ```kotlin supabase.postgrest["cities"].select(columns = Columns.list("name")) { City::countryId lte 300 //or lte("country_id", 300) } ``` ### With `update()` ```kotlin val toUpdate = City(name = "Mordor") supabase.postgrest["cities"].update(toUpdate) { City::countryId lte 300 //or lte("country_id", 300) } ``` ### With `delete()` ```kotlin supabase.postgrest["cities"].delete { City::countryId lte 300 //or lte("country_id", 300) } ``` ### With `rpc()` ```kotlin supabase.postgrest.rpc("echo_all_cities") { City::countryId lte 250 //or lte("country_id", 300) } ``` # Kotlin Reference like() Finds all rows whose value in the stated `column` matches the supplied `pattern` (case sensitive). ## Examples ### With `select()` ```kotlin supabase.postgrest["cities"].select(columns = Columns.list("name")) { City::name like "%la%" //or like("name", "%la%") } ``` ### With `update()` ```kotlin val toUpdate = City(name = "Mordor") supabase.postgrest["cities"].update(toUpdate) { City::name like "%la%" //or like("name", "%la%") } ``` ### With `delete()` ```kotlin supabase.postgrest["cities"].delete { City::name like "%la%" //or like("name", "%la%") } ``` ### With `rpc()` ```kotlin supabase.postgrest.rpc("echo_all_cities") { City::name like "%la%" //or like("name", "%la%") } ``` # Kotlin Reference ilike() Finds all rows whose value in the stated `column` matches the supplied `pattern` (case insensitive). ## Examples ### With `select()` ```kotlin supabase.postgrest["cities"].select(columns = Columns.list("name")) { City::name ilike "%la%" //or ilike("name", "%la%") } ``` ### With `update()` ```kotlin val toUpdate = City(name = "Mordor") supabase.postgrest["cities"].update(toUpdate) { City::name ilike "%la%" //or ilike("name", "%la%") } ``` ### With `delete()` ```kotlin supabase.postgrest["cities"].delete { City::name ilike "%la%" //or ilike("name", "%la%") } ``` ### With `rpc()` ```kotlin supabase.postgrest.rpc("echo_all_cities") { City::name ilike "%la%" //or ilike("name", "%la%") } ``` # Kotlin Reference is_() A check for exact equality (null, true, false), finds all rows whose value on the stated `column` exactly match the specified `value`. `is_` and `in_` filter methods are suffixed with `_` to avoid collisions with reserved keywords. ## Examples ### With `select()` ```kotlin supabase.postgrest["cities"].select(columns = Columns.list("name")) { City::name isExact null //or exact("name", null) } ``` ### With `update()` ```kotlin val toUpdate = City(name = "Mordor") supabase.postgrest["cities"].update(toUpdate) { City::name isExact null //or exact("name", null) } ``` ### With `delete()` ```kotlin supabase.postgrest["cities"].delete { City::name isExact null //or exact("name", null) } ``` ### With `rpc()` ```kotlin supabase.postgrest.rpc("echo_all_cities") { City::name isExact null //or exact("name", null) } ``` # Kotlin Reference in_() Finds all rows whose value on the stated `column` is found on the specified `values`. ## Examples ### With `select()` ```kotlin supabase.postgrest["cities"].select(columns = Columns.list("name")) { City::name isIn listOf("The Shire", "Mordor") //or isIn("name", listOf("The Shire", "Mordor")) } ``` ### With `update()` ```kotlin val toUpdate = City(name = "Mordor") supabase.postgrest["cities"].update(toUpdate) { City::name isIn listOf("Hobbiton", "Edoras") //or isIn("name", listOf("Hobbiton", "Edoras")) } ``` ### With `delete()` ```kotlin supabase.postgrest["cities"].delete { City::name isIn listOf("Hobbiton", "Edoras") //or isIn("name", listOf("Hobbiton", "Edoras")) } ``` ### With `rpc()` ```kotlin supabase.postgrest.rpc("echo_all_cities") { City::name isIn listOf("Hobbiton", "Edoras") //or isIn("name", listOf("Hobbiton", "Edoras")) } ``` # Kotlin Reference contains() ## Examples ### With `select()` ```kotlin supabase.postgrest["cities"].select(columns = Columns.list("name")) { City::mainExports contains listOf("oil") //or contains("main_exports", listOf("oil")) } ``` ### With `update()` ```kotlin val toUpdate = City(name = "Mordor") supabase.postgrest["cities"].update(toUpdate) { City::mainExports contains listOf("oil") //or contains("main_exports", listOf("oil")) } ``` ### With `delete()` ```kotlin supabase.postgrest["cities"].delete { City::mainExports contains listOf("oil") //or contains("main_exports", listOf("oil")) } ``` ### With `rpc()` ```kotlin supabase.postgrest.rpc("echo_all_cities") { City::mainExports contains listOf("oil") //or contains("main_exports", listOf("oil")) } ``` # Kotlin Reference rangeGt() Only relevant for range columns. Match only rows where every element in column is greater than any element in range. ## Examples ### With `select()` ```kotlin supabase.postgrest["reservations"].select { Reservation::during rangeGt ("2000-01-02 08:30" to "2000-01-02 09:30") //or rangeGt("during", "2000-01-02 08:30" to "2000-01-02 09:30") } ``` # Kotlin Reference rangeGte() Only relevant for range columns. Match only rows where every element in column is either contained in range or greater than any element in range. ## Examples ### With `select()` ```kotlin supabase.postgrest["reservations"].select { Reservation::during rangeGte ("2000-01-02 08:30" to "2000-01-02 09:30") //or rangeGte("during", "2000-01-02 08:30" to "2000-01-02 09:30") } ``` # Kotlin Reference rangeLt() Only relevant for range columns. Match only rows where every element in column is less than any element in range. ## Examples ### With `select()` ```kotlin supabase.postgrest["reservations"].select { Reservation::during rangeLt ("2000-01-02 08:30" to "2000-01-02 09:30") //or rangeLt("during", "2000-01-02 08:30" to "2000-01-02 09:30") } ``` # Kotlin Reference rangeLte() Only relevant for range columns. Match only rows where every element in column is either contained in range or less than any element in range. ## Examples ### With `select()` ```kotlin supabase.postgrest["reservations"].select { Reservation::during rangeLte ("2000-01-02 08:30" to "2000-01-02 09:30") //or rangeLte("during", "2000-01-02 08:30" to "2000-01-02 09:30") } ``` # Kotlin Reference rangeAdjacent() Only relevant for range columns. Match only rows where column is mutually exclusive to range and there can be no element between the two ranges. ## Examples ### With `select()` ```kotlin supabase.postgrest["reservations"].select { Reservation::during adjacent ("2000-01-02 08:30" to "2000-01-02 09:30") //or adjacent("during", "2000-01-02 08:30" to "2000-01-02 09:30") } ``` # Kotlin Reference overlaps() Only relevant for array and range columns. Match only rows where column and value have an element in common. ## Examples ### On array columns ```kotlin supabase.postgrest["issues"].select(columns = Columns.list("title")) { Issue::tags overlaps listOf("is:closed", "severity:high") //or overlaps("tags", listOf("is:closed", "severity:high")) } ``` ### On range columns ```kotlin supabase.postgrest["issues"].select(columns = Columns.list("title")) { Issue::tags overlaps listOf("is:closed", "severity:high") //or overlaps("tags", listOf("is:closed", "severity:high")) } ``` # Kotlin Reference textSearch() Only relevant for text and tsvector columns. Match only rows where `column` matches the query string in `query`. For more information, see [Postgres full text search](https://supabase.com/docs/guides/database/full-text-search). ## Examples ### Text search ```kotlin supabase.postgrest["quotes"].select(columns = Columns.list("catchphrase")) { textSearch(column = "catchphrase", query = "'fat' & 'cat'", config = "english", type = TextSearchType.YOUR_TYPE) } ``` ### Basic normalization ```kotlin supabase.postgrest["quotes"].select(columns = Columns.list("catchphrase")) { textSearch(column = "catchphrase", query = "'fat' & 'cat'", config = "english", type = TextSearchType.PLAINTO) } ``` ### Full normalization ```kotlin supabase.postgrest["quotes"].select(columns = Columns.list("catchphrase")) { textSearch(column = "catchphrase", query = "'fat' & 'cat'", config = "english", type = TextSearchType.PHRASETO) } ``` ### Websearch ```kotlin supabase.postgrest["quotes"].select(columns = Columns.list("catchphrase")) { textSearch(column = "catchphrase", query = "'fat' & 'cat'", config = "english", type = TextSearchType.WEBSEARCH) } ``` # Kotlin Reference filterNot() Finds all rows that don't satisfy the filter. ## Examples ### With `select()` ```kotlin supabase.postgrest["countries"].select { filterNot("name", FilterOperation.IS, "") } ``` # Kotlin Reference or() Finds all rows satisfying at least one of the filters. ## Examples ### With `select()` ```kotlin supabase.postgrest["countries"].select(columns = Columns.list("name")) { or { Country::id eq 2 Country::name eq "Mordor" //or eq("id", 2) eq("name", "Mordor") } } ``` ### Use `or` with `and` ```kotlin supabase.postgrest["countries"].select(columns = Columns.list("name")) { or { Country::id gt 3 and { Country::id eq 1 Country::name eq "Mordor" } } } ``` # Kotlin Reference filter() ## Examples ### With `select()` ```kotlin supabase.postgrest["characters"].select { filter(column = "name", operator = FilterOperator.IN, value = "('Han', 'Katniss')") } ``` ### On a foreign table ```kotlin supabase.postgrest["orchestral_sections"].select( columns = Columns.raw(""" name, instruments!inner ( name ) """) ) { filter(column = "instruments.name", operator = FilterOperator.EQ, value = "flute") } ``` # Kotlin Reference order() Order the query result by column. ## Examples ### With `select()` ```kotlin supabase.postgrest["characters"].select(columns = Columns.list("id", "name")) { order(column = "id", order = Order.DESCENDING) } ``` ### On a foreign table ```kotlin supabase.postgrest["orchestral_sections"].select( columns = Columns.raw( """ name, instruments ( name ) """ ) ) { order(column = "name", order = Order.DESCENDING, foreignTable = "instruments") } ``` # Kotlin Reference limit() Limit the query result by count. ## Examples ### With `select()` ```kotlin supabase.postgrest["characters"].select { limit(count = 1) } ``` ### On a foreign table ```kotlin supabase.postgrest["orchestral_sections"].select( columns = Columns.raw( """ name, instruments ( name ) """ ) ) { limit(count = 1, foreignTable = "instruments") } ``` # Kotlin Reference range() Limit the query result by from and to inclusively. ## Examples ### With `select()` ```kotlin supabase.postgrest["characters"].select { range(1L..5L) } ``` # Kotlin Reference Overview ## Examples ### Create gotrue client ```kotlin val supabase = createSupabaseClient(supabaseURL = "https://xyzcompany.supabase.co'", supabaseKey = "public-anon-key") { ... } val gotrue = supabase.gotrue ``` # Kotlin Reference signUp() ## Examples ### Sign up with email ```kotlin val user = supabase.gotrue.signUpWith(Email) { email = "example@email.com" password = "example-password" } ``` ### Sign up with a phone number ```kotlin val user = supabase.gotrue.signUpWith(Phone) { phoneNumber = "+4912345679" password = "example-password" } ``` ### Sign up with additional user metadata ```kotlin val user = supabase.gotrue.signUpWith(Email) { email = "example@email.com" password = "example-password" data = buildJsonObject { put("first_name", "John") put("age", 24) } } ``` ### Sign up with a redirect URL ```kotlin val user = supabase.gotrue.signUpWith(Email, redirectUrl = "https://example.com") { email = "example@email.com" password = "example-password" } ``` # Kotlin Reference sessionStatus ## Examples ### Listen to auth changes ```kotlin supabase.gotrue.sessionStatus.collect { when(it) { is SessionStatus.Authenticated -> println(it.session.user) SessionStatus.LoadingFromStorage -> println("Loading from storage") SessionStatus.NetworkError -> println("Network error") SessionStatus.NotAuthenticated -> println("Not authenticated") } } ``` # Kotlin Reference loginWith() ## Examples ### Sign in with email and password ```kotlin supabase.gotrue.loginWith(Email) { email = "example@email.com" password = "example-password" } ``` ### Sign in with phone and password ```kotlin supabase.gotrue.loginWith(Phone) { phoneNumber = "+4912345679" password = "example-password" } ``` ### Sign in with id token ```kotlin supabase.gotrue.loginWith(IDToken) { idToken = "token" provider = Google //Also supported: Apple, Azure and Facebook //optional: nonce = "nonce" data = buildJsonObject { //... } } ``` # Kotlin Reference sendOtpTo() ## Examples ### Sign in with email ```kotlin supabase.gotrue.sendOtpTo(Email) { email = "example@email.com" } ``` ### Sign in with SMS OTP ```kotlin supabase.gotrue.sendOtpTo(Phone) { phoneNumber = "+4912345679" } ``` # Kotlin Reference loginWith(OAuthProvider) ## Examples ### Sign in using a third-party provider ```kotlin supabase.gotrue.loginWith(Github) ``` ### Sign in using a third-party provider with scopes ```kotlin supabase.gotrue.loginWith(Github) { scopes.add("email") } ``` ### Create a custom url ```kotlin val url = supabase.gotrue.oAuthUrl(Github, redirectUrl = "https://example.com") ``` ### Create a custom url with scopes ```kotlin val url = supabase.gotrue.oAuthUrl(Github, redirectUrl = "https://example.com") { scopes.add("email") } ``` # Kotlin Reference signInWithSSO() ## Examples ### Sign in with email domain ```kotlin // You can extract the user's email domain and use it to trigger the // authentication flow with the correct identity provider. supabase.gotrue.loginWith(SSO.withDomain("company.com")) //the url was opened automatically, if you don't want that, provide a custom redirect url ``` ### Sign in with provider UUID ```kotlin // Useful when you need to map a user's sign in request according // to different rules that can't use email domains. supabase.gotrue.loginWith(SSO.withProvider("21648a9d-8d5a-4555-a9d1-d6375dc14e92")) //the url was opened automatically, if you don't want that, provide a custom redirect url ``` # Kotlin Reference logout() ## Examples ### Sign out ```kotlin supabase.gotrue.logout() ``` ### Sign out all sessions ```kotlin supabase.gotrue.logout(LogoutScope.GLOBAL) ``` ### Sign out all sessions except the current ```kotlin supabase.gotrue.logout(LogoutScope.OTHERS) ``` # Kotlin Reference Send a password reset request ## Examples ### Send password reset email ```kotlin supabase.gotrue.sendRecoveryEmail(email = "example@email.com") ``` # Kotlin Reference Verify OTPs ## Examples ### Verify an Email OTP ```kotlin supabase.gotrue.verifyEmailOtp(type = OtpType.Email.INVITE, email = "example@email.com", token = "token") ``` ### Verify an Phone OTP ```kotlin supabase.gotrue.verifyPhoneOtp(type = OtpType.Phone.SMS, phoneNumber = "+491234567", token = "token") ``` # Kotlin Reference Get current session ## Examples ### Get the session data ```kotlin val session = supabase.gotrue.currentSessionOrNull() ``` # Kotlin Reference refreshSession() ## Examples ### Refresh current session ```kotlin val session = supabase.gotrue.refreshCurrentSession() ``` ### Refresh session using the refresh token ```kotlin val session = supabase.gotrue.refreshSession(refreshToken = "refreshToken") ``` # Kotlin Reference getUser() - This method gets the user object from the current session. - Fetches the user object from the database instead of local session. - Should be used only when you require the most current user data. For faster results, `getCurrentSessionOrNull()?.user` is recommended. ## Examples ### Get the logged in user with the current session ```kotlin val user = supabase.gotrue.retrieveUserForCurrentSession(updateSession = true) ``` ### Get a user based on their access token ```kotlin val user = supabase.gotrue.retrieveUser("JWT") ``` # Kotlin Reference modifyUser() ## Examples ### Update the email for an authenticated user ```kotlin val user = supabase.gotrue.modifyUser { email = "newEmail@email.com" } ``` ### Update the password for an authenticated user ```kotlin val user = supabase.gotrue.modifyUser { password = "secretPassword" } ``` ### Update the user's metadata ```kotlin val user = supabase.gotrue.modifyUser { data { put("name", "John") } } ``` # Kotlin Reference reauthenticate() ## Examples ### Send reauthentication nonce ```kotlin supabase.gotrue.reauthenticate() ``` # Kotlin Reference resend() ## Examples ### Resend an email signup confirmation ```kotlin supabase.gotrue.resendEmail(OtpType.Email.SIGNUP, "example@email.com") ``` ### Resend a phone signup confirmation ```kotlin supabase.gotrue.resendPhone(OtpType.Phone.SMS, "1234567890") ``` ### Resend email change email ```kotlin supabase.gotrue.resendEmail(OtpType.Email.EMAIL_CHANGE, "example@email.com") ``` ### Resend phone change OTP ```kotlin supabase.gotrue.resendPhone(OtpType.Phone.PHONE_CHANGE, "1234567890") ``` # Kotlin Reference importSession() ## Examples ### Set local session ```kotlin supabase.gotrue.importSession(UserSession(accessToken = "token", refreshToken = "refresh", expiresIn = 2000, tokenType = "Bearer", user = null)) ``` # Kotlin Reference exchangeCodeForSession() ## Examples ### Exchange Auth Code ```kotlin supabase.gotrue.exchangeCodeForSession("34e770dd-9ff9-416c-87fa-43b31d7ef225") ``` # Kotlin Reference Overview ## Examples # Kotlin Reference Enroll a factor ## Examples ### Enroll a time-based, one-time password (TOTP) factor ```kotlin val factor = supabase.gotrue.mfa.enroll(factorType = FactorType.TOTP) // Use the id to create a challenge. // The challenge can be verified by entering the code generated from the authenticator app. // The code will be generated upon scanning the qr_code or entering the secret into the authenticator app. val (id, type, qrCode) = factor.data //qrCode is a svg as a string val (factorId, factorType, _) = factor ``` ### Check the local user for verified factors ```kotlin val verifiedFactors = supabase.gotrue.mfa.verifiedFactors ``` ### Retrieve verified factors ```kotlin val verifiedFactors = supabase.gotrue.mfa.retrieveFactorsForCurrentUser() ``` # Kotlin Reference mfa.challenge() ## Examples ### Create a challenge for a factor ```kotlin val challenge = supabase.gotrue.mfa.createChallenge(factorId = "34e770dd-9ff9-416c-87fa-43b31d7ef225") ``` # Kotlin Reference mfa.verify() ## Examples ### Verify a challenge for a factor ```kotlin supabase.gotrue.mfa.verifyChallenge( factorId = "34e770dd-9ff9-416c-87fa-43b31d7ef225", challengeId = "4034ae6f-a8ce-4fb5-8ee5-69a5863a7c15", code = "123456", saveSession = true // this is set to true by default, but you can set it to false if you want to handle the session yourself ) ``` # Kotlin Reference mfa.challengeAndVerify() ## Examples ### Create and verify a challenge for a factor ```kotlin supabase.gotrue.mfa.createChallengeAndVerify( factorId = "34e770dd-9ff9-416c-87fa-43b31d7ef225", code = "123456", saveSession = true // this is set to true by default, but you can set it to false if you want to handle the session yourself ) ``` # Kotlin Reference mfa.unenroll() ## Examples ### Unenroll a factor ```kotlin supabase.gotrue.mfa.unenroll(factorId = "34e770dd-9ff9-416c-87fa-43b31d7ef225") ``` # Kotlin Reference mfa.getAuthenticatorAssuranceLevel() ## Examples ### Get the AAL details of the current session ```kotlin val (current, next) = supabase.gotrue.mfa.getAuthenticatorAssuranceLevel() ``` ### Check whether the user has at least one verified factor ```kotlin val enabled = supabase.gotrue.mfa.isMfaEnabled //flow variant, automatically emitting new values on session changes val enabledFlow = supabase.gotrue.mfa.isMfaEnabledFlow ``` ### Check whether the user is logged in using AAL2 ```kotlin val loggedInUsingMfa = supabase.gotrue.mfa.loggedInUsingMfa //flow variant, automatically emitting new values on session changes val loggedInUsingMfaFlow = supabase.gotrue.mfa.loggedInUsingMfaFlow ``` # Kotlin Reference Overview ## Examples ### Create server-side auth client ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://id.supabase.co", supabaseKey = "supabaseKey" ) { install(GoTrue) { autoLoadFromStorage = false alwaysAutoRefresh = false } // install other plugins (these will use the service role key) } supabase.gotrue.importAuthToken("service_role") // Access auth admin api val adminGoTrueClient = supabase.gotrue.admin ``` # Kotlin Reference getUserById() ## Examples ### Fetch the user object using the access_token jwt ```kotlin val user = supabase.gotrue.admin.retrieveUserById(uid = "f2a0b0a0-6b1a-4b7a-8f1a-4b7a6b1a8f1a") ``` # Kotlin Reference listUsers() ## Examples ### Get a page of users ```kotlin val users = supabase.gotrue.admin.retrieveUsers() ``` ### Paginated list of users ```kotlin val users = supabase.gotrue.admin.retrieveUsers( page = 1, perPage = 100 ) ``` # Kotlin Reference createUser() ## Examples ### Create user with email ```kotlin val userWithEmail = supabase.gotrue.admin.createUserWithEmail { email = "example@email.com" password = "secretpassword" userMetadata { put("name", "John") } } ``` ### Create user with phone ```kotlin val userWithPhone = supabase.gotrue.admin.createUserWithPhone { phoneNumber = "+49123456789" password = "secretpassword" userMetadata { put("name", "John") } } ``` ### Auto-confirm the user's email ```kotlin val userWithEmail = supabase.gotrue.admin.createUserWithEmail { email = "example@email.com" password = "secretpassword" autoConfirm = true } ``` ### Auto-confirm the user's phone number ```kotlin val userWithPhone = supabase.gotrue.admin.createUserWithPhone { phoneNumber = "+49123456789" password = "secretpassword" autoConfirm = true } ``` # Kotlin Reference deleteUser() ## Examples ### Removes a user ```kotlin supabase.gotrue.admin.deleteUser(uid = "uid") ``` # Kotlin Reference inviteUserByEmail() ## Examples ### Invite a user ```kotlin supabase.gotrue.admin.inviteUserByEmail( email = "example@email.com", //optional: redirectTo = "https://example.com/redirect", data = buildJsonObject { put("custom", "value") } ) ``` # Kotlin Reference generateLink() ## Examples ### Generate a signup link ```kotlin val (url, user) = supabase.gotrue.admin.generateLinkFor(LinkType.Signup) { email = "example@email.com" password = "secretpassword" } ``` ### Generate an invite link ```kotlin val (url, user) = supabase.gotrue.admin.generateLinkFor(LinkType.Invite) { email = "example@email.com" } ``` ### Generate a magic link ```kotlin val (url, user) = supabase.gotrue.admin.generateLinkFor(LinkType.MagicLink) { email = "example@email.com" } ``` ### Generate a recovery link ```kotlin val (url, user) = supabase.gotrue.admin.generateLinkFor(LinkType.Recovery) { email = "example@email.com" } ``` ### Generate links to change current email address ```kotlin // generate an email change link to be sent to the current email address val (url, user) = supabase.gotrue.admin.generateLinkFor(LinkType.EmailChangeCurrent) { email = "example@email.com" newEmail = "newEmail@email.com" } // generate an email change link to be sent to the new email address val (url, user) = supabase.gotrue.admin.generateLinkFor(LinkType.EmailChangeNew) { email = "example@email.com" newEmail = "newEmail@email.com" } ``` # Kotlin Reference updateUserById() ## Examples ### Updates a user's email ```kotlin supabase.gotrue.admin.updateUserById(uid = "id") { email = "example@email.com" } ``` ### Updates a user's password ```js supabase.gotrue.admin.updateUserById(uid = "id") { password = "password" } ``` ### Updates a user's metadata ```kotlin supabase.gotrue.admin.updateUserById(uid = "id") { userMetadata = buildJsonObject { put("key", "value") } } ``` ### Updates a user's app_metadata ```kotlin supabase.gotrue.admin.updateUserById(uid = "id") { appMetadata = buildJsonObject { put("key", "value") } } ``` ### Confirms a user's email address ```kotlin supabase.gotrue.admin.updateUserById(uid = "id") { emailConfirm = true } ``` ### Confirms a user's phone number ```kotlin supabase.gotrue.admin.updateUserById(uid = "id") { phoneConfirm = true } ``` # Kotlin Reference mfa.listFactors() ## Examples ### List all factors for a user ```kotlin const factors = supabase.gotrue.admin.retrieveFactors(uid = "id") ``` # Kotlin Reference mfa.deleteFactor() ## Examples ### Delete a factor for a user ```kotlin supabase.gotrue.admin.deleteFactor(uid = "id", factorId = "factor_id") ``` # Kotlin Reference invoke() Invokes a Supabase Function. See the [guide](/docs/guides/functions) for details on writing Functions. - When invoking a function with parameters, you have to provide a [serializable value](/docs/reference/kotlin/installing#serialization) in the function parameter. ## Examples ### Basic invocation ```kotlin supabase.functions.invoke("function_name") ``` ### Basic invocation with body ```kotlin supabase.functions.invoke( function = "function_name", body = buildJsonObject { put("foo", "bar") }, headers = Headers.build { append(HttpHeaders.ContentType, "application/json") } ) ``` ### Reuse function by saving it to a variable ```kotlin val function = supabase.functions.buildEdgeFunction( function = "function", headers = Headers.build { /*Default headers*/ //when you are sending a body you may want to add this header: append(HttpHeaders.ContentType, "application/json") } ) //invoke it: function() //invoke it with a body: function(body) //invoke it with custom request options: function(body) { header("Header", "Value") parameter("Key", "Value") //url parameter } ``` # Kotlin Reference on().subscribe() Subscribe to realtime changes in your database. ## Examples ### Connect to Realtime ```kotlin supabase.realtime.connect() ``` ### Listen to broadcasts ```kotlin @Serializable data class Message(val content: String, val sender: String) val channel = supabase.realtime.createChannel("channelId") { //optional config } val broadcastFlow = channel.broadcastFlow(event = "message") //in a new coroutine (or use Flow.onEach().launchIn(scope)): broadcastFlow.collect { //it: Message println(it) } supabase.realtime.connect() channel.join(blockUntilJoined = true) channel.broadcast(event = "message", Message("I joined!", "John")) ``` ### Listen to presence updates ```kotlin @Serializable data class PresenceState(val username: String) val connectedUsers = mutableSetOf() val channel = supabase.realtime.createChannel("channelId") { //optional config } val presenceChangeFlow = channel.presenceChangeFlow() //in a new coroutine (or use Flow.onEach().launchIn(scope)): presenceChangeFlow.collect { connectedUsers += it.decodeJoinsAs() connectedUsers -= it.decodeLeavesAs() } supabase.realtime.connect() channel.join(blockUntilJoined = true) //send own state channel.track(PresenceState(username = "John")) ### Listen to all database changes ```kotlin val channel = supabase.realtime.createChannel("channelId") { //optional config } val changeFlow = channel.postgresChangeFlow(schema = "public") //in a new coroutine (or use Flow.onEach().launchIn(scope)): changeFlow.collect { when(it) { is PostgresAction.Delete -> println("Deleted: ${it.oldRecord}") is PostgresAction.Insert -> println("Inserted: ${it.record}") is PostgresAction.Select -> println("Selected: ${it.record}") is PostgresAction.Update -> println("Updated: ${it.oldRecord} with ${it.record}") } } supabase.realtime.connect() channel.join() ``` ### Listen to a specific table ```kotlin val channel = supabase.realtime.createChannel("channelId") { //optional config } val changeFlow = channel.postgresChangeFlow(schema = "public") { table = "users" } //in a new coroutine (or use Flow.onEach().launchIn(scope)): changeFlow.collect { when(it) { is PostgresAction.Delete -> println("Deleted: ${it.oldRecord}") is PostgresAction.Insert -> println("Inserted: ${it.record}") is PostgresAction.Select -> println("Selected: ${it.record}") is PostgresAction.Update -> println("Updated: ${it.oldRecord} with ${it.record}") } } supabase.realtime.connect() channel.join() ``` ### Listen to inserts ```kotlin val channel = supabase.realtime.createChannel("channelId") { //optional config } val changeFlow = channel.postgresChangeFlow(schema = "public") { table = "users" } //in a new coroutine (or use Flow.onEach().launchIn(scope)): changeFlow.collect { println(it.record) } supabase.realtime.connect() channel.join() ``` ### Listen to updates ```kotlin val channel = supabase.realtime.createChannel("channelId") { //optional config } val changeFlow = channel.postgresChangeFlow(schema = "public") { table = "users" } //in a new coroutine (or use Flow.onEach().launchIn(scope)): changeFlow.collect { println(it.record) println(it.oldRecord) } supabase.realtime.connect() channel.join() ``` ### Listen to deletes ```kotlin val channel = supabase.realtime.createChannel("channelId") { //optional config } val changeFlow = channel.postgresChangeFlow(schema = "public") { table = "users" } //in a new coroutine (or use Flow.onEach().launchIn(scope)): changeFlow.collect { println(it.oldRecord) } supabase.realtime.connect() channel.join() ``` ### Listen to row level changes ```kotlin val channel = supabase.realtime.createChannel("channelId") { //optional config } val changeFlow = channel.postgresChangeFlow(schema = "public") { table = "users" filter = "id=eq.1" } //in a new coroutine: changeFlow.collect { println(it.oldRecord) } supabase.realtime.connect() channel.join() ``` # Kotlin Reference removeChannel() Unsubscribes and removes Realtime channel from Realtime client. ## Examples ### Remove a channel ```kotlin val channel = supabase.realtime.createChannel("channelId") { //optional config } //... supabase.realtime.removeChannel(channel) ``` ### Unsubscribe from a channel ```kotlin val channel = supabase.realtime.createChannel("channelId") { //optional config } //... channel.leave() ``` # Kotlin Reference removeAllChannels() ## Examples ### Remove all channels ```kotlin supabase.realtime.removeAllChannels() ``` # Kotlin Reference getChannels() ## Examples ### Get all channels ```kotlin val channels = supabase.realtime.subscriptions.entries ``` # Kotlin Reference createBucket() ## Examples ### Create bucket ```kotlin supabase.storage.createBucket(name = "icons", id = "icons") { public = true fileSizeLimit = 5.megabytes } ``` # Kotlin Reference getBucket() ## Examples ### Get bucket ```kotlin val bucket = supabase.storage.retrieveBucketById(bucketId = "avatars") ``` # Kotlin Reference listBuckets() ## Examples ### List buckets ```kotlin val buckets = supabase.storage.retrieveBuckets() ``` # Kotlin Reference updateBucket() ## Examples ### Update bucket ```kotlin supabase.storage.updateBucket("cards") { public = false fileSizeLimit = 20.megabytes allowedMimeTypes(ContentType.Image.PNG, ContentType.Image.JPEG) } ``` # Kotlin Reference deleteBucket() ## Examples ### Delete bucket ```kotlin supabase.storage.deleteBucket(bucketId = "icons") ``` # Kotlin Reference emptyBucket() ## Examples ### Empty bucket ```kotlin supabase.storage.emptyBucket(bucketId = "icons") ``` # Kotlin Reference from.upload() ## Examples ### Upload file ```kotlin val bucket = supabase.storage["avatars"] bucket.upload("myIcon.png", byteArray, upsert = false) //on JVM you can use java.io.File bucket.upload("myIcon.png", file, upsert = false) ``` ### Upload file with progress ```kotlin val bucket = supabase.storage["avatars"] bucket.uploadAsFlow("test.png", byteArrayOf()).collect { when(it) { is UploadStatus.Progress -> println("Progress: ${it.totalBytesSend.toFloat() / it.contentLength * 100}%") is UploadStatus.Success -> println("Success") } } ``` ### Create resumable upload ```kotlin val bucket = supabase.storage["avatars"] //JVM/Android: val upload = bucket.resumable.createOrContinueUpload("icon.png", File("icon.png")) //Other platforms: val upload = bucket.resumable.createOrContinueUpload(data = byteArray, source = "this is for continuing previous uploads later", path = "icon.png") val upload = bucket.resumable.createOrContinueUpload( //Probably better to write an extension function channel = { offset -> /* create ByteReadChannel and seek to offset */ }, source = "this is for continuing previous uploads later", size = dataSize, path = "icon.png" ) ``` ### Start and resumable upload ```kotlin upload.startOrResumeUploading() ``` ### Pause resumable upload ```kotlin upload.pause() ``` ### Cancel resumable upload ```kotlin upload.cancel() ``` ### Listen to the resumable upload state ```kotlin upload.stateFlow.collect { println("Progress: ${it.progress * 100}%") println("Paused: ${it.paused}") println("Is done: ${it.isDone}") } ``` ### Continue previous uploads ```kotlin val bucket = supabase.storage["avatars"] //only on JVM/Android: bucket.resumable.continuePreviousFileUploads() .map { it.await() } //await all uploads. This just makes sure the uploads have an update-to-date url. You can also do this in parallel .forEach { upload -> upload.startOrResumeUploading() } //on other platforms you may have to continue uploads from the source (Probably better to write an extension function): bucket.resumable.continuePreviousUploads { source, offset -> //create ByteReadChannel from source and seek to offset } .map { it.await() } //await all uploads. This just makes sure the uploads have an update-to-date url. You can also do this in parallel .forEach { upload -> upload.startOrResumeUploading() } ``` # Kotlin Reference from.download() ## Examples ### Download file from non-public bucket ```kotlin val bucket = supabase.storage["avatars"] val bytes = bucket.downloadAuthenticated("test.png") //or on JVM: bucket.downloadAuthenticatedTo("test.png", File("test.png")) ``` ### Download file from public bucket ```kotlin val bucket = supabase.storage["avatars"] val bytes = bucket.downloadPublic("test.png") //or on JVM: bucket.downloadPublicTo("test.png", File("test.png")) ``` ### Download file with transformation ```kotlin val bucket = supabase.storage["avatars"] val bytes = bucket.downloadPublic("test.png") { size(100, 100) fill() quality = 100 } //or on JVM: bucket.downloadPublicTo("test.png", File("test.png")) { size(100, 100) fill() quality = 100 } ``` ### Download file with progress ```kotlin val bucket = supabase.storage["avatars"] bucket.downloadAuthenticatedAsFlow("icon.png").collect { when(it) { is DownloadStatus.ByteData -> println("Downloaded ${it.data.size} bytes") is DownloadStatus.Progress -> println("Downloaded ${it.totalBytesReceived.toFloat() / it.contentLength * 100}%") DownloadStatus.Success -> println("Downloaded successfully") } } //or on JVM: bucket.downloadAuthenticatedToAsFlow("icon.png", File("icon.png")).collect { when(it) { is DownloadStatus.Progress -> println("Downloaded ${it.totalBytesReceived.toFloat() / it.contentLength * 100}%") DownloadStatus.Success -> println("Downloaded successfully") else -> {} //The ByteData status will never occur as we are writing directly to a file } } ``` # Kotlin Reference from.list() ## Examples ### List files in a bucket ```kotlin val bucket = supabase.storage["avatars"] val files = bucket.list() ``` # Kotlin Reference from.update() ## Examples ### Update file ```kotlin val bucket = supabase.storage["avatars"] bucket.update("myIcon.png", byteArray, upsert = false) //on JVM you can use java.io.File bucket.update("myIcon.png", file, upsert = false) ``` # Kotlin Reference from.move() ## Examples ### Move file ```kotlin val bucket = supabase.storage["avatars"] bucket.move("icon1.png", "icon2.png") ``` # Kotlin Reference from.copy() ## Examples ### Copy file ```kotlin supabase.storage["test"].copy(from = "avatar.png", to = "avatar2.png") ``` # Kotlin Reference from.remove() ## Examples ### Delete file ```kotlin val bucket = supabase.storage["avatars"] bucket.delete("test.png", "test2.png") ``` # Kotlin Reference from.createSignedUrl() ## Examples ### Create Signed URL ```kotlin val bucket = supabase.storage["avatars"] val url = bucket.createSignedUrl(path = "icon.png", expiresIn = 3.minutes) ``` ### Create Signed URL with transformation ```kotlin val bucket = supabase.storage["avatars"] val url = bucket.createSignedUrl(path = "icon.png", expiresIn = 3.minutes) { size(100, 100) fill() quality = 80 } ``` # Kotlin Reference from.createSignedUrls() ## Examples ### Create Signed URLs ```kotlin val urls = supabase.storage["avatars"].createSignedUrls(20.minutes, "avata1.jpg", "avatar2.jpg") ``` # Kotlin Reference from.createSignedUploadUrl() ## Examples ### Create Signed Upload URL ```kotlin val url = supabase.storage["avatars"].createSignedUploadUrl("avatar.png") ``` # Kotlin Reference from.uploadToSignedUrl() ## Examples ### Upload to a signed URL ```kotlin supabase.storage["avatars"].uploadToSignedUrl(path = "avatar.jpg", token = "token-from-createSignedUploadUrl", data = bytes) //or on JVM: supabase.storage["avatars"].uploadToSignedUrl(path = "avatar.jpg", token = "token-from-createSignedUploadUrl", file = File("avatar.jpg")) ``` # Kotlin Reference from.getPublicUrl() ## Examples ### Returns the URL for an asset in a public bucket ```kotlin val url = supabase.storage["public-bucket"].publicUrl("folder/avatar1.png") ``` ### Returns the URL for an asset in a public bucket with transformations ```kotlin val url = supabase.storage["public-bucket"].publicRenderUrl("folder/avatar1.png") { size(100, 100) } ```