openref: 0.1 info: id: reference/supabase-kotlin title: Supabase Kotlin Client description: | Supabase Kotlin. specUrl: https://github.com/supabase/supabase/edit/master/apps/docs/spec/supabase_kt_v3.yml slugPrefix: '/' libraries: - name: 'Kotlin' id: 'kt' version: '0.0.1' functions: - id: initializing title: 'Initializing' description: | ### 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. OAuth sign-ins can be triggered via `supabase.auth.signInWith(Provider)` and the callback has to be handled differently on each Kotlin target. OTP link verification stands for opening your app, and directly signing-in via the clicked link. This is only supported on Mobile devices & Web targets. The following will explain how each target handles OAuth and OTP link verification, if supported. **On Desktop platforms (JVM, MacOS\*, Linux, Windows)**, it uses a HTTP Callback Server to receive the session data from a successful OAuth sign-in. The success page can be customized via `AuthConfig#httpCallbackConfig` \ \* If no deeplinks are being used. This works as-is, by default. *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 email. To send the token, rather than a redirect url, change `{{ .ConfirmationURL }}` in your sign up email to `{{ .Token }}`* **On Android, iOS & MacOS**, OAuth and OTP verification use deeplinks. Refer to the guide below on how to setup deeplinks. Alternatively you can use [Native Google Auth](/docs/guides/auth/social-login/auth-google?platform=android). \ **On JS**, it uses the website origin as the callback url. Session importing gets handled automatically. \ **tvOS & watchOS** currently have no default implementation. Feel free to create a PR. You always make your own implementation and use `auth.parseSessionFromFragment(fragment)` or `auth.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 `auth.importSession(session)`. ### Configure deeplink callbacks for Authentication Deeplinks are supported on Android, iOS and MacOS. 1. **Set up a deeplink** \ On Android, set up a [deeplink](https://developer.android.com/training/app-links/deep-linking) in your Android manifest. \ On iOS and MacOS, set up 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 Auth plugin** Set the `host` and `scheme` in the Auth config: ```kotlin install(Auth) { host = "deeplink host" // this can be anything, eg. your package name or app/company url (not your Supabase url) scheme = "deeplink scheme" // On Android only, you can set OAuth and SSO logins to open in a custom tab, rather than an external browser: defaultExternalAuthAction = ExternalAuthAction.CustomTabs() //defaults to ExternalAuthAction.ExternalBrowser } ``` 4. **Call platform specific function on startup** \ On Android: `supabase.handleDeeplinks(intent)` \ If you don't want a separate activity, just call this function at the top of your `onCreate` function in your MainActivity. \ On iOS/MacOS: `supabase.handleDeeplinks(url)` Then you can sign in using OAuth: ```kotlin supabase.auth.signInWith(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, change the `flowType` in the Auth configuration: ```kotlin install(Auth) { flowType = FlowType.PKCE } ``` That's it! If you already implemented deeplinks to handle OTPs and OAuth you don't have to change anything! params: - name: supabaseUrl isOptional: false type: String description: The unique Supabase URL which is supplied when you create a new project in your project dashboard. - name: supabaseKey isOptional: false type: String description: The unique Supabase Key which is supplied when you create a new project in your project dashboard. - name: builder isOptional: true type: SupabaseClientBuilder.() -> Unit description: Apply additional configuration and install plugins. subContent: - name: useHTTPS isOptional: true type: Boolean description: Whether to use HTTPS for network requests. Will be set automatically depending on your Supabase url, but can be changed manually. - name: httpEngine isOptional: true type: HttpClientEngine? description: Custom Ktor Client engine. Shouldn't be set manually as Ktor uses an engine from your dependencies, but can be set to a MockEngine for tests. - name: ignoreModulesInUrl isOptional: true type: Boolean description: Whether to ignore if [supabaseUrl] contains modules like 'realtime' or 'auth'. If false, an exception will be thrown. Defaults to false. - name: requestTimeout isOptional: true type: Duration description: Timeout after network requests throw a `HttpRequestTimeoutException`. Defaults to 10 seconds. - name: defaultLogLevel isOptional: true type: LogLevel description: The default log level used for plugins. Can be overridden per plugin. Defaults to `LogLevel.INFO`. - name: defaultSerializer isOptional: true type: SupabaseSerializer description: The default serializer used to serialize and deserialize custom data types. Defaults to `KotlinXSerializer`. examples: - id: initialize-client name: Initialize Client code: | ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "your-publishable-key" ) { install(Auth) install(Postgrest) //install other modules } ``` - id: configure-auth name: Configure Auth module code: | ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "your-publishable-key" ) { install(Auth) { alwaysAutoRefresh = false // default: true autoLoadFromStorage = false // default: true //and more... } } ``` description: | **Common:** `alwaysAutoRefresh` - whether the Auth plugin should always auto refresh expired sessions automatically. Default: `true` `autoLoadFromStorage` - whether the Auth plugin should automatically load the session from the session manager. Default: `true` `autoSaveToStorage` - whether the Auth plugin should automatically save the session to the session manager. Default: `true` `flowType` - Which authentication flow to use. Currently available: FlowType.PKCE and FlowType.IMPLICIT. Default: `FlowType.IMPLICIT` `codeVerifierCache` - Interface for saving and loading codes for the PKCE authentication flow. Default: `SettingsCodeVerifierCache` `customUrl` - Custom url for the Auth API. Can be safely ignored when using Supabase. Default: `null` `jwtToken` - Plugin specific JWT Token. Can be ignored when using the Auth plugin. Default: `null` `retryDelay` - Duration after which the Auth plugin should retry a failed session refresh. Default: `10.seconds` `sessionManager` - Interface for saving and loading the user session. Default: `SettingsSessionManager` **Android & iOS:** `scheme` - The scheme for the redirect url, when using deep linking. Default: `supabase` `host` - The host for the redirect url, when using deep linking. Default: `login` **Android:** `enableLifecycleCallbacks` - Whether to stop auto-refresh on focus loss, and resume it on focus again. Default: `true` **Desktop:** `httpPort`: The port the web server is running on, when signing in with OAuth. Default: `0` (random port). `timeout`: The timeout for the web server, when signing in with OAuth. Default: `1.minutes`. `htmlTitle`: The title of the redirect page, when signing in with OAuth. Default: `"Supabase Auth"`. `htmlText`: The text of the redirect page, when signing in with OAuth. Default: `"Logged in. You may continue in your app."`. `htmlIconUrl`: The icon of the redirect page, when signing in with OAuth. Default: `"https://supabase.com/brand-assets/supabase-logo-icon.png"`. - id: configure-postgrest name: Configure PostgREST module code: | ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "your-publishable-key" ) { install(Postgrest) { defaultSchema = "schema" // default: "public" propertyConversionMethod = PropertyConversionMethod.SERIAL_NAME // default: PropertyConversionMethod.CAMEL_CASE_TO_SNAKE_CASE } } ``` description: | `propertyConversionMethod` - The method to use to convert the property names to the column names when applying filters and using the update method. Default: `PropertyConversionMethod.CAMEL_CASE_TO_SNAKE_CASE` `defaultSchema` - The default schema to use for database requests. Default: `public` `customUrl` - Custom url for the PostgREST API. Can be safely ignored when using Supabase. Default: `null` `jwtToken` - Plugin specific JWT Token. Can be ignored when using the Auth plugin. Default: `null` `urlLengthLimit` - The maximum URL length for requests. When exceeded, the request is automatically sent as POST with query parameters in the body. Default: `null` (unlimited) `timeout` - The timeout for PostgREST requests. Default: `30.seconds` - id: configure-storage name: Configure Storage module code: | ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "your-publishable-key" ) { install(Storage) { transferTimeout = 90.seconds // Default: 120 seconds } } ``` description: | `transferTimeout` - the timeout for uploading and downloading files. Default: `120.seconds` `resumable.cache` - Interface for storing resumable upload urls. Default: `SettingsResumableCache` `resumable.defaultChunkSize` - The default chunk size for resumable uploads. Supabase currently only supports a chunk size of 6MB, so be careful when changing this value. Default: `6MB` `resumable.retryTimeout` - the timeout for retrying resumable uploads when uploading a chunk fails. Default: `5.seconds` `resumable.onlyUpdateStateAfterChunk` - whether the upload state should only be updated after a chunk was uploaded successfully or also when the chunk is currently being uploaded. Default: `false` `customUrl` - Custom url for the Storage API. Can be safely ignored when using Supabase. Default: `null` `jwtToken` - Plugin specific JWT Token. Can be ignored when using the Auth plugin. Default: `null` - id: configure-realtime name: Configure Realtime module code: | ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "your-publishable-key" ) { install(Realtime) { reconnectDelay = 5.seconds // Default: 7 seconds } } ``` description: | `reconnectDelay` - The delay between reconnect attempts. Default: `7.seconds` `heartbeatInterval` - The interval between heartbeat messages. Default: `15.seconds` `disconnectOnSessionLoss` - Whether to disconnect from the websocket when the session is lost. Default: `true` `secure` - Whether to use wss or ws. Defaults to [SupabaseClient.useHTTPS] when null `websocketConfig` - Custom Ktor websocket config `customUrl` - Custom url for the Realtime websocket. Can be safely ignored when using Supabase. Default: `null` `jwtToken` - Plugin specific JWT Token. Can be ignored when using the Auth plugin. Default: `null` - id: configure-functions name: Configure Functions plugin code: | ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "your-publishable-key" ) { install(Functions) { //no custom settings } } ``` description: | `customUrl` - Custom url for the Functions API. Can be safely ignored when using Supabase. Default: `null` `jwtToken` - Plugin specific JWT Token. Can be ignored when using the Auth plugin. Default: `null` - id: configure-graphql name: Configure GraphQL plugin code: | ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "your-publishable-key" ) { install(GraphQL) { apolloConfiguration { //custom configuration } } } ``` description: | `apolloConfiguration` - Custom configuration for the ApolloClient `customUrl` - Custom url for the GraphQL API. Can be safely ignored when using Supabase. Default: `null` `jwtToken` - Plugin specific JWT Token. Can be ignored when using the Auth plugin. Default: `null` **You can access the created ApolloClient via `supabase.graphql.apolloClient`, which automatically adds the required headers depending on your session.** - id: select title: 'Fetch data: select()' notes: | Perform a SELECT query on the table or view. - When calling a `decode` method, you have to provide a [serializable class](/docs/reference/kotlin/installing#serialization) as the type parameter. - You can provide a `Columns` object to select specific columns. - You can provide a [filter](/docs/reference/kotlin/using-filters) block to filter the results params: - name: columns isOptional: true type: Columns description: The columns to retrieve, defaults to `Columns.ALL`. You can also use `Columns.list`, `Columns.type` or `Columns.raw` to specify the columns. - name: head isOptional: true type: Boolean description: If true, select will delete the selected data. - name: request isOptional: true type: PostgrestRequestBuilder.() -> Unit description: Additional configuration & filtering for the request. examples: - id: getting-your-data name: Getting your data isSpotlight: true code: | ```kotlin val city = supabase.from("cities").select().decodeSingle() ``` - id: selecting-specific-columns name: Selecting specific columns description: You can select specific fields from your tables. code: | ```kotlin val city = supabase.from("cities").select(columns = Columns.list("id, name")).decodeSingle() ``` - id: query-foreign-tables name: Query foreign tables description: If your database has foreign key relationships, you can query related tables too. code: | ```kotlin val columns = Columns.raw(""" id, name, cities ( id, name ) """.trimIndent()) val country = supabase.from("countries") .select( columns = columns ) .decodeSingle() ``` note: | What about join tables If your tables are **NOT** directly related, but instead are joined by a _join table_, you can still use the `select()` method to query the related data. The PostgREST engine detects the relationship automatically. For more details, [follow the link](https://postgrest.org/en/latest/api.html#embedding-through-join-tables). - id: query-the-same-foreign-table-multiple-times name: Query the same foreign table multiple times description: | Sometimes you will need to query the same foreign table twice. In this case, you can use the name of the joined column to identify which join you intend to use. For convenience, you can also give an alias for each column. code: | ```kotlin val columns = Columns.raw(""" content, from: sender_id(name), to: receiver_id(name) """.trimIndent()) val message = supabase.from("messages") .select(columns = columns) .decodeSingle() ``` - id: querying-with-count-option name: Querying with count option description: | You can get the number of rows by using the count option. Allowed values for count option are [Count.EXACT](https://postgrest.org/en/stable/api.html#exact-count), [Count.PLANNED](https://postgrest.org/en/stable/api.html#planned-count) and [Count.ESTIMATED](https://postgrest.org/en/stable/api.html#estimated-count). code: | ```kotlin val count = supabase.from("countries") .select { count(Count.EXACT) } .countOrNull() ?: 0 ``` - id: querying-json-data name: Querying JSON data description: | If you have data inside of a JSONB column, you can apply select and query filters to the data values. Postgres offers a [number of operators](https://www.postgresql.org/docs/current/functions-json.html) for querying JSON data. Also see [PostgREST docs](http://postgrest.org/en/v7.0.0/api.html#json-columns) for more details. code: | ```kotlin val columns = Columns.raw(""" id, name address->city """.trimIndent()) val user = supabase.from("users") .select(columns = columns) .decodeSingle() ``` - id: insert title: 'Create data: insert()' $ref: '@supabase/postgrest-js."lib/PostgrestQueryBuilder".PostgrestQueryBuilder.insert' notes: | Perform an INSERT into the table or view. - When calling an `insert` method, you have to provide a [serializable value](/docs/reference/kotlin/installing#serialization). - By default, `insert` will not return the inserted data. If you want to return the inserted data, you can use the `select()` method inside the request. params: - name: value # This function has two signatures: "value: T" and "values: List" isOptional: false type: T or List description: The value(s) you want to insert. `T` can be any serializable type. - name: request isOptional: true type: PostgrestRequestBuilder.() -> Unit description: Additional configuration & filtering for the request. examples: - id: create-a-record name: Create a record isSpotlight: true code: | ```kotlin val city = City(name = "The Shire", countryId = 554) supabase.from("cities").insert(city) ``` - id: create-a-record-and-return name: Create a record and return it isSpotlight: true code: | ```kotlin val city = City(name = "The Shire", countryId = 554) val result = supabase.from("cities").insert(city) { select() }.decodeSingle() ``` - id: bulk-create name: Bulk create description: | When running a bulk create, the operation is handled in a single transaction. If any of the inserts fail, all other operations are rolled back. code: | ```kotlin val theShire = City(name = "The Shire", countryId = 554) val rohan = City(name = "Rohan", countryId = 554) supabase.from("cities").insert(listOf(theShire, rohan)) ``` - id: update title: 'Modify data: update()' notes: | Perform an UPDATE on the table or view. - `update()` should always be combined with a [filter](/docs/reference/kotlin/using-filters) block to avoid updating all records. - When calling `insert` or `update`, you have to provide a [serializable value](/docs/reference/kotlin/installing#serialization) in the function parameter. - By default, `update` will not return the inserted data. If you want to return the inserted data, you can use the `select()` method inside the request. params: - name: value type: T or PostgrestUpdate.() -> Unit = {} isOptional: false description: The new value, can be either a serializable value or PostgrestUpdate DSL where you can set new values per column. - name: request isOptional: true type: PostgrestRequestBuilder.() -> Unit description: Additional configuration & filtering for the request. examples: - id: updating-your-data name: Updating your data isSpotlight: true code: | ```kotlin supabase.from("characters").update( { Country::name setTo "Han Solo" //or set("name", "Han Solo") } ) { filter { Character::id eq 1 //or eq("id", 1) } } ``` - id: update-a-record-and-return-it name: Update a record and return it code: | ```kotlin val newCharacter = supabase.from("characters").update( { Character::name setTo "Han Solo" //or set("name", "Han Solo") } ) { select() filter { Character::id eq 1 //or eq("id", 1) } }.decodeSingle() ``` data: sql: | ```sql create table characters (id int8 primary key, name text); insert into characters (id, name) values (1, 'Han'); ``` response: | ```json { "data": [ { "id": 1, "name": "Han Solo" } ], "status": 200, "statusText": "OK" } ``` hideCodeBlock: true - id: updating-json-data name: Updating JSON data description: | Postgres offers a [number of operators](https://www.postgresql.org/docs/current/functions-json.html) for working with JSON data. Right now it is only possible to update an entire JSON document, but we are [working on ideas](https://github.com/PostgREST/postgrest/issues/465) for updating individual keys. code: | ```kotlin val address = Address(street = "Melrose Place", postcode = 90210) supabase.from("users").update( { User::address setTo address } ) { filter { eq("address->postcode", 90210) } } ``` - id: upsert title: 'Upsert data: upsert()' $ref: '@supabase/postgrest-js."lib/PostgrestQueryBuilder".PostgrestQueryBuilder.upsert' notes: | Perform an UPSERT on the table or view. Depending on the column(s) passed to `onConflict`, `.upsert()` allows you to perform the equivalent of `.insert()` if a row with the corresponding `onConflict` columns doesn't exist, or if it does exist, perform an alternative action depending on `ignoreDuplicates`. - Primary keys should be included in the data payload in order for an update to work correctly. - Primary keys must be natural, not surrogate. There are however, [workarounds](https://github.com/PostgREST/postgrest/issues/1118) for surrogate primary keys. - If you need to insert new data and update existing data at the same time, use [Postgres triggers](https://github.com/supabase/postgrest-js/issues/173#issuecomment-825124550). - When calling `insert` or `update`, you have to provide a [serializable value](/docs/reference/kotlin/installing#serialization) in the function parameter. - By default, `upsert` will not return the inserted data. If you want to return the inserted data, you can use the `select()` method inside the request. params: - name: value # This function has two signatures: "value: T" and "values: List" isOptional: false type: T or List description: The value(s) you want to insert. `T` can be any serializable type. - name: request isOptional: true type: PostgrestRequestBuilder.() -> Unit description: Additional configuration & filtering for the request. subParams: - name: onConflict isOptional: true type: String? description: Comma-separated UNIQUE column(s) to specify how duplicate rows are determined. Two rows are duplicates if all the `onConflict` columns are equal. - name: defaultToNull isOptional: true type: Boolean description: Make missing fields default to `null`. Otherwise, use the default value for the column. This only applies when inserting new rows, not when merging with existing rows under - name: ignoreDuplicates isOptional: true type: Boolean description: If `true`, duplicate rows are ignored. If `false`, duplicate rows are merged with existing rows. examples: - id: upsert-your-data name: Upsert your data isSpotlight: true code: | ```kotlin val toUpsert = Message(id = 3, message = "foo", username = "supabot") supabase.from("messages").upsert(toUpsert) ``` - id: upsert-your-data-and-return name: Upsert your data and return it isSpotlight: true code: | ```kotlin val toUpsert = Message(id = 3, message = "foo", username = "supabot") val message = supabase.from("messages").upsert(toUpsert) { select() }.decodeSingle() ``` - id: upserting-into-tables-with-constraints name: Upserting into tables with constraints description: | Running the following will cause Supabase to upsert data into the `users` table. If the username 'supabot' already exists, the `onConflict` argument tells Supabase to overwrite that row based on the column passed into `onConflict`. isSpotlight: true code: | ```kotlin val toUpsert = User(username = "supabot") supabase.from("users").upsert(toUpsert) { onConflict = "username" } ``` - id: upsert-return-row-count name: Return the exact number of rows isSpotlight: true code: | ```kotlin val toUpsert = User(username = "supabot") val count = supabase.from("users").upsert(toUpsert) { count(Count.EXACT) onConflict = "username" }.countOrNull() ?: 0 ``` - id: delete title: 'Delete data: delete()' $ref: '@supabase/postgrest-js."lib/PostgrestQueryBuilder".PostgrestQueryBuilder.delete' notes: | Perform a DELETE on the table or view. - `delete()` should always be combined with a [filter](/docs/reference/kotlin/using-filters) block to target the item(s) you wish to delete. - If you use `delete()` with filters and you have [RLS](/docs/learn/auth-deep-dive/auth-row-level-security) enabled, only rows visible through `SELECT` policies are deleted. Note that by default no rows are visible, so you need at least one `SELECT`/`ALL` policy that makes the rows visible. - By default, `delete` will not return the deleted data. If you want to return the deleted data, you can use the `select()` method inside the request. params: - name: request isOptional: true type: PostgrestRequestBuilder.() -> Unit description: Additional configuration & filtering for the request. examples: - id: delete-records name: Delete records isSpotlight: true code: | ```kotlin supabase.from("cities").delete { filter { City::id eq 666 //or eq("id", 666) } } ``` - id: fetch-delete-records name: Fetch deleted records code: | ```kotlin val deletedCity = supabase.from("cities").delete { select() filter { City::id eq 666 //or eq("id", 666) } }.decodeSingle() ``` - id: rpc title: 'Database Functions: rpc()' description: | You can call functions 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. params: - name: function isOptional: false type: String description: The name of the function - name: parameters isOptional: true # Not directly `optional`, as there are two overloads one with and one without `parameters`. type: T description: Parameters to pass to the function. T can be any serializable type. - name: request isOptional: true type: PostgrestRequestBuilder.() -> Unit description: Additional configuration & filtering for the request. subParams: - name: method isOptional: true type: RpcMethod description: The HTTP method to use. Defaults to `RpcMethod.POST` - name: schema isOptional: true type: String description: The schema to use for the function. Defaults to `public` examples: - id: call-a-database-function name: Call a database function isSpotlight: true description: This is an example invoking a database function. code: | ```kotlin supabase.postgrest.rpc("hello_world") ``` - id: with-parameters name: With Parameters code: | ```kotlin val rpcParams = City(name = "The Shire") supabase.postgrest.rpc("echo_city", rpcParams) ``` - id: using-filters title: Using Filters description: | 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: - id: applying-filters name: Applying a filter block description: | Filters can be applied on any of these functions: `select()`, `update()`, `upsert()`, `delete()`, and `rpc()` code: | ```kotlin supabase.from("cities").select(columns = Columns.list("name", "country_id")) { filter { City::name eq "The Shire" //or eq("name", "The Shire") } } ``` - id: multiple-filters name: Multiple filters on one column description: | Filters can be applied on any of these functions: `select()`, `update()`, `upsert()`, `delete()`, and `rpc()` code: | ```kotlin supabase.from("cities").select(columns = Columns.list("name, country_id")) { filter { and { //when both are true City::population gt 40000 City::population lt 700000 } or { //when either one of the filters are true City::name eq "Hobbiton" City::name eq "Edoras" } } } ``` - id: filter-by-value-within-json-column name: Filter by values within a JSON column description: | Filters can be built up one step at a time and then executed. For example: data: sql: | ```sql create table users ( id int8 primary key, name text, address jsonb ); insert into users (id, name, address) values (1, 'Michael', '{ "postcode": 90210 }'), (2, 'Jane', null); ``` response: | ```json { "data": [ { "id": 1, "name": "Michael", "address": { "postcode": 90210 } } ], "status": 200, "statusText": "OK" } ``` code: | ```kotlin supabase.from("users").select { filter { eq("address->postcode", 90210) } } ``` - id: filter-foreign-tables name: Filter Foreign Tables code: | ```kotlin val columns = Columns.raw(""" name, instruments!inner ( name ) """.trimIndent()) supabase.from("orchestral_sections").select( columns = columns ) { filter { eq("instruments.name", "flute") } } ``` data: sql: | ```sql create table orchestral_sections (id int8 primary key, name text); create table instruments ( id int8 primary key, section_id int8 not null references orchestral_sections, name text ); insert into orchestral_sections (id, name) values (1, 'strings'), (2, 'woodwinds'); insert into instruments (id, section_id, name) values (1, 2, 'flute'), (2, 1, 'violin'); ``` response: | ```json { "data": [ { "name": "strings", "instruments": [ { "name": "flute" } ] } ], "status": 200, "statusText": "OK" } ``` - id: or title: or() description: | Finds all rows satisfying at least one of the filters. params: - name: negate isOptional: true type: Boolean description: If true, negate the entire block. - name: block isOptional: false type: PostgrestFilterBuilder.() -> Unit description: The block to apply the `or` filter to. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("countries").select(columns = Columns.list("name")) { filter { or { Country::id eq 2 Country::name eq "Mordor" //or eq("id", 2) eq("name", "Mordor") } } } ``` - id: use-or-with-and name: Use `or` with `and` code: | ```kotlin supabase.from("countries").select(columns = Columns.list("name")) { filter { or { Country::id gt 3 and { Country::id eq 1 Country::name eq "Mordor" } } } } ``` - id: not title: filterNot() description: | Finds all rows that don't satisfy the filter. notes: | - `.filterNot()` expects you to use the raw [PostgREST syntax](https://postgrest.org/en/stable/api.html#horizontal-filtering-rows) for the filter names and values. params: - name: column isOptional: false type: String description: The column to filter on. - name: operator isOptional: false type: FilterOperator description: The operator to use for the filter. - name: value isOptional: false type: Any description: The value to filter with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("countries").select { filter { filterNot("name", FilterOperator.IS, "") } } ``` - id: eq title: eq() description: | Finds all rows whose value on the stated `column` exactly matches the specified `value`. params: - name: column isOptional: false type: String description: The column to filter on. - name: value isOptional: false type: Any description: The value to filter with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("cities").select(columns = Columns.list("name", "country_id")) { filter { City::name eq "The Shire" //or eq("name", "The Shire") } } ``` - id: with-update name: With `update()` code: | ```kotlin val toUpdate = City(name = "Mordor") supabase.from("cities").update(toUpdate) { filter { City::name eq "Hobbiton" //or eq("name", "Hobbiton") } } ``` - id: with-delete name: With `delete()` code: | ```kotlin supabase.from("cities").delete { filter { City::name eq "Mordor" //or eq("name", "Mordor") } } ``` - id: with-rpc name: With `rpc()` code: | ```kotlin supabase.postgrest.rpc("function") { filter { City::name eq "Mordor" //or eq("name", "Mordor") } } ``` - id: neq title: neq() description: | Finds all rows whose value on the stated `column` doesn't match the specified `value`. params: - name: column isOptional: false type: String description: The column to filter on. - name: value isOptional: false type: Any description: The value to filter with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("cities").select(columns = Columns.list("name", "country_id")) { filter { City::name neq "The Shire" //or neq("name", "The Shire") } } ``` - id: with-update name: With `update()` code: | ```kotlin val toUpdate = City(name = "Mordor") supabase.from("cities").update(toUpdate) { filter { City::name neq "The Shire" //or neq("name", "The Shire") } } ``` - id: with-delete name: With `delete()` code: | ```kotlin supabase.from("cities").delete { filter { City::name neq "The Shire" //or neq("name", "The Shire") } } ``` - id: with-rpc name: With `rpc()` code: | ```kotlin supabase.rpc("echo_all_cities") { filter { neq("address->postcode", 90210) } } ``` - id: gt title: gt() description: | Finds all rows whose value on the stated `column` is greater than the specified `value`. params: - name: column isOptional: false type: String description: The column to filter on. - name: value isOptional: false type: Any description: The value to filter with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("cities").select(columns = Columns.list("name")) { filter { City::countryId gt 300 //or gt("country_id", 300) } } ``` - id: with-update name: With `update()` code: | ```kotlin val toUpdate = City(name = "Mordor") supabase.from("cities").update(toUpdate) { filter { City::countryId gt 300 //or gt("country_id", 300) } } ``` - id: with-delete name: With `delete()` code: | ```kotlin supabase.from("cities").delete { filter { City::countryId gt 300 //or gt("country_id", 300) } } ``` - id: with-rpc name: With `rpc()` code: | ```kotlin supabase.postgrest.rpc("echo_all_cities") { filter { City::countryId gt 300 //or gt("country_id", 300) } } ``` - id: gte title: gte() description: | Finds all rows whose value on the stated `column` is greater than or equal to the specified `value`. params: - name: column isOptional: false type: String description: The column to filter on. - name: value isOptional: false type: Any description: The value to filter with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("cities").select(columns = Columns.list("name")) { filter { City::countryId gte 300 //or gte("country_id", 300) } } ``` - id: with-update name: With `update()` code: | ```kotlin val toUpdate = City(name = "Mordor") supabase.from("cities").update(toUpdate) { filter { City::countryId gte 300 //or gte("country_id", 300) } } ``` - id: with-delete name: With `delete()` code: | ```kotlin supabase.from("cities").delete { filter { City::countryId gte 300 //or gte("country_id", 300) } } ``` - id: with-rpc name: With `rpc()` code: | ```kotlin supabase.postgrest.rpc("echo_all_cities") { filter { City::countryId gte 300 //or gte("country_id", 300) } } ``` - id: lt title: lt() description: | Finds all rows whose value on the stated `column` is less than the specified `value`. params: - name: column isOptional: false type: String description: The column to filter on. - name: value isOptional: false type: Any description: The value to filter with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("cities").select(columns = Columns.list("name")) { filter { City::countryId lt 300 //or lt("country_id", 300) } } ``` - id: with-update name: With `update()` code: | ```kotlin val toUpdate = City(name = "Mordor") supabase.from("cities").update(toUpdate) { filter { City::countryId lt 300 //or lt("country_id", 300) } } ``` - id: with-delete name: With `delete()` code: | ```kotlin supabase.from("cities").delete { filter { City::countryId lt 300 //or lt("country_id", 300) } } ``` - id: with-rpc name: With `rpc()` code: | ```kotlin supabase.postgrest.rpc("echo_all_cities") { filter { City::countryId lt 300 //or lt("country_id", 300) } } ``` - id: lte title: lte() description: | Finds all rows whose value on the stated `column` is less than or equal to the specified `value`. params: - name: column isOptional: false type: String description: The column to filter on. - name: value isOptional: false type: Any description: The value to filter with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("cities").select(columns = Columns.list("name")) { filter { City::countryId lte 300 //or lte("country_id", 300) } } ``` - id: with-update name: With `update()` code: | ```kotlin val toUpdate = City(name = "Mordor") supabase.from("cities").update(toUpdate) { filter { City::countryId lte 300 //or lte("country_id", 300) } } ``` - id: with-delete name: With `delete()` code: | ```kotlin supabase.from("cities").delete { filter { City::countryId lte 300 //or lte("country_id", 300) } } ``` - id: with-rpc name: With `rpc()` code: | ```kotlin supabase.postgrest.rpc("echo_all_cities") { filter { City::countryId lte 300 //or lte("country_id", 300) } } ``` - id: like title: like() description: | Finds all rows whose value in the stated `column` matches the supplied `pattern` (case sensitive). params: - name: column isOptional: false type: String description: The column to filter on. - name: pattern isOptional: false type: String description: The pattern to match with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("cities").select(columns = Columns.list("name")) { filter { City::name like "%la%" //or like("name", "%la%") } } ``` - id: with-update name: With `update()` code: | ```kotlin val toUpdate = City(name = "Mordor") supabase.from("cities").update(toUpdate) { filter { City::name like "%la%" //or like("name", "%la%") } } ``` - id: with-delete name: With `delete()` code: | ```kotlin supabase.from("cities").delete { filter { City::name like "%la%" //or like("name", "%la%") } } ``` - id: with-rpc name: With `rpc()` code: | ```kotlin supabase.postgrest.rpc("echo_all_cities") { filter { City::name like "%la%" //or like("name", "%la%") } } ``` - id: ilike title: ilike() description: | Finds all rows whose value in the stated `column` matches the supplied `pattern` (case insensitive). params: - name: column isOptional: false type: String description: The column to filter on. - name: pattern isOptional: false type: String description: The pattern to match with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("cities").select(columns = Columns.list("name")) { filter { City::name ilike "%la%" //or ilike("name", "%la%") } } ``` - id: with-update name: With `update()` code: | ```kotlin val toUpdate = City(name = "Mordor") supabase.from("cities").update(toUpdate) { filter { City::name ilike "%la%" //or ilike("name", "%la%") } } ``` - id: with-delete name: With `delete()` code: | ```kotlin supabase.from("cities").delete { filter { City::name ilike "%la%" //or ilike("name", "%la%") } } ``` - id: with-rpc name: With `rpc()` code: | ```kotlin supabase.postgrest.rpc("echo_all_cities") { filter { City::name ilike "%la%" //or ilike("name", "%la%") } } ``` - id: is title: is_() description: | 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. params: - name: column isOptional: false type: String description: The column to filter on. - name: value isOptional: false type: Boolean? description: The value to filter with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("cities").select(columns = Columns.list("name")) { filter { City::name isExact null //or exact("name", null) } } ``` - id: with-update name: With `update()` code: | ```kotlin val toUpdate = City(name = "Mordor") supabase.from("cities").update(toUpdate) { filter { City::name isExact null //or exact("name", null) } } ``` - id: with-delete name: With `delete()` code: | ```kotlin supabase.from("cities").delete { filter { City::name isExact null //or exact("name", null) } } ``` - id: with-rpc name: With `rpc()` code: | ```kotlin supabase.postgrest.rpc("echo_all_cities") { filter { City::name isExact null //or exact("name", null) } } ``` - id: in title: in_() description: | Finds all rows whose value on the stated `column` is found on the specified `values`. params: - name: column isOptional: false type: String description: The column to filter on. - name: values isOptional: false type: List description: The values to filter with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("cities").select(columns = Columns.list("name")) { filter { City::name isIn listOf("Hobbiton", "Edoras") //or isIn("name", listOf("Hobbiton", "Edoras")) } } ``` - id: with-update name: With `update()` code: | ```kotlin val toUpdate = City(name = "Mordor") supabase.from("cities").update(toUpdate) { filter { City::name isIn listOf("Hobbiton", "Edoras") //or isIn("name", listOf("Hobbiton", "Edoras")) } } ``` - id: with-delete name: With `delete()` code: | ```kotlin supabase.from("cities").delete { filter { City::name isIn listOf("Hobbiton", "Edoras") //or isIn("name", listOf("Hobbiton", "Edoras")) } } ``` - id: with-rpc name: With `rpc()` code: | ```kotlin supabase.postgrest.rpc("echo_all_cities") { filter { City::name isIn listOf("Hobbiton", "Edoras") //or isIn("name", listOf("Hobbiton", "Edoras")) } } ``` - id: notin title: notIn() description: | Finds all rows whose value on the stated `column` is not found on the specified `values`. The negation of `in_()`. params: - name: column isOptional: false type: String description: The column to filter on. - name: values isOptional: false type: List description: The values to exclude. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("cities").select(columns = Columns.list("name")) { filter { City::name notIn listOf("Hobbiton", "Edoras") //or notIn("name", listOf("Hobbiton", "Edoras")) } } ``` - id: contains title: contains() description: | Only relevant for jsonb, array, and range columns. Match only rows where `column` contains every element appearing in `value`. params: - name: column isOptional: false type: String description: The jsonb, array, or range column to filter on - name: value isOptional: false type: List description: The jsonb, array, or range value to filter with examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("cities").select(columns = Columns.list("name")) { filter { City::mainExports contains listOf("oil") //or contains("main_exports", listOf("oil")) } } ``` - id: with-update name: With `update()` code: | ```kotlin val toUpdate = City(name = "Mordor") supabase.from("cities").update(toUpdate) { filter { City::mainExports contains listOf("oil") //or contains("main_exports", listOf("oil")) } } ``` - id: with-delete name: With `delete()` code: | ```kotlin supabase.from("cities").delete { filter { City::mainExports contains listOf("oil") //or contains("main_exports", listOf("oil")) } } ``` - id: with-rpc name: With `rpc()` code: | ```kotlin supabase.postgrest.rpc("echo_all_cities") { filter { City::mainExports contains listOf("oil") //or contains("main_exports", listOf("oil")) } } ``` - id: range-lt title: rangeLt() description: | Only relevant for range columns. Match only rows where every element in column is less than any element in range. params: - name: column isOptional: false type: String description: The column to filter on. - name: values isOptional: false type: Pair description: The values to filter with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("reservations").select { filter { 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") } } ``` data: sql: | ```sql create table reservations ( id int8 primary key, room_name text, during tsrange ); insert into reservations (id, room_name, during) values (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'), (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)'); ``` response: | ```json { "data": [ { "id": 1, "room_name": "Emerald", "during": "[\"2000-01-01 13:00:00\",\"2000-01-01 15:00:00\")" } ], "status": 200, "statusText": "OK" } ``` description: | Postgres supports a number of [range types](https://www.postgresql.org/docs/current/rangetypes.html). You can filter on range columns using the string representation of range values. hideCodeBlock: true - id: range-gt title: rangeGt() description: | Only relevant for range columns. Match only rows where every element in column is greater than any element in range. params: - name: column isOptional: false type: String description: The column to filter on. - name: values isOptional: false type: Pair description: The values to filter with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("reservations").select { filter { 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") } } ``` data: sql: | ```sql create table reservations ( id int8 primary key, room_name text, during tsrange ); insert into reservations (id, room_name, during) values (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'), (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)'); ``` response: | ```json { "data": [ { "id": 2, "room_name": "Topaz", "during": "[\"2000-01-02 09:00:00\",\"2000-01-02 10:00:00\")" } ], "status": 200, "statusText": "OK" } ``` description: | Postgres supports a number of [range types](https://www.postgresql.org/docs/current/rangetypes.html). You can filter on range columns using the string representation of range values. hideCodeBlock: true - id: range-gte title: rangeGte() description: | 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. params: - name: column isOptional: false type: String description: The column to filter on. - name: values isOptional: false type: Pair description: The values to filter with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("reservations").select { filter { 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") } } ``` data: sql: | ```sql create table reservations ( id int8 primary key, room_name text, during tsrange ); insert into reservations (id, room_name, during) values (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'), (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)'); ``` response: | ```json { "data": [ { "id": 2, "room_name": "Topaz", "during": "[\"2000-01-02 09:00:00\",\"2000-01-02 10:00:00\")" } ], "status": 200, "statusText": "OK" } ``` description: | Postgres supports a number of [range types](https://www.postgresql.org/docs/current/rangetypes.html). You can filter on range columns using the string representation of range values. hideCodeBlock: true - id: range-lte title: rangeLte() description: | 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. params: - name: column isOptional: false type: String description: The column to filter on. - name: values isOptional: false type: Pair description: The values to filter with. $ref: '@supabase/postgrest-js.PostgrestFilterBuilder.rangeLte' examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("reservations").select { filter { 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") } } ``` data: sql: | ```sql create table reservations ( id int8 primary key, room_name text, during tsrange ); insert into reservations (id, room_name, during) values (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'), (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)'); ``` response: | ```json { "data": [ { "id": 1, "room_name": "Emerald", "during": "[\"2000-01-01 13:00:00\",\"2000-01-01 15:00:00\")" } ], "status": 200, "statusText": "OK" } ``` description: | Postgres supports a number of [range types](https://www.postgresql.org/docs/current/rangetypes.html). You can filter on range columns using the string representation of range values. hideCodeBlock: true - id: range-adjacent title: rangeAdjacent() description: | 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. params: - name: column isOptional: false type: String description: The column to filter on. - name: values isOptional: false type: Pair description: The values to filter with. examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin supabase.from("reservations").select { filter { 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") } } ``` data: sql: | ```sql create table reservations ( id int8 primary key, room_name text, during tsrange ); insert into reservations (id, room_name, during) values (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'), (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)'); ``` response: | ```json { "data": [ { "id": 1, "room_name": "Emerald", "during": "[\"2000-01-01 13:00:00\",\"2000-01-01 15:00:00\")" } ], "status": 200, "statusText": "OK" } ``` hideCodeBlock: true - id: overlaps title: overlaps() $ref: '@supabase/postgrest-js.PostgrestFilterBuilder.overlaps' description: | Only relevant for array and range columns. Match only rows where column and value have an element in common. params: - name: column isOptional: false type: String description: The column to filter on. - name: values isOptional: false type: List description: The values to filter with. examples: - id: on-array-columns name: On array columns code: | ```kotlin supabase.from("issues").select(columns = Columns.list("title")) { filter { Issue::tags overlaps listOf("is:closed", "severity:high") //or overlaps("tags", listOf("is:closed", "severity:high")) } } ``` data: sql: | ```sql create table issues ( id int8 primary key, title text, tags text[] ); insert into issues (id, title, tags) values (1, 'Cache invalidation is not working', array['is:open', 'severity:high', 'priority:low']), (2, 'Use better names', array['is:open', 'severity:low', 'priority:medium']); ``` response: | ```json { "data": [ { "title": "Cache invalidation is not working" } ], "status": 200, "statusText": "OK" } ``` hideCodeBlock: true isSpotlight: true - id: on-range-columns name: On range columns code: | ```kotlin supabase.from("issues").select(columns = Columns.list("title")) { filter { Issue::during overlaps listOf("2000-01-01 12:45", "2000-01-01 13:15") //or overlaps("during", listOf("2000-01-01 12:45", "2000-01-01 13:15")) } } ``` data: sql: | ```sql create table reservations ( id int8 primary key, room_name text, during tsrange ); insert into reservations (id, room_name, during) values (1, 'Emerald', '[2000-01-01 13:00, 2000-01-01 15:00)'), (2, 'Topaz', '[2000-01-02 09:00, 2000-01-02 10:00)'); ``` response: | ```json { "data": [ { "id": 1, "room_name": "Emerald", "during": "[\"2000-01-01 13:00:00\",\"2000-01-01 15:00:00\")" } ], "status": 200, "statusText": "OK" } ``` description: | Postgres supports a number of [range types](https://www.postgresql.org/docs/current/rangetypes.html). You can filter on range columns using the string representation of range values. hideCodeBlock: true - id: text-search title: textSearch() description: | 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). params: - name: column isOptional: false type: String description: The text or tsvector column to filter on - name: query isOptional: false type: String description: The query text to match with - name: textSearchType isOptional: true type: TextSearchType description: The type of text search to use. Defaults to `TextSearchType.NONE`. - name: config isOptional: true type: String description: The text search configuration to use. examples: - id: text-search name: Text search code: | ```kotlin supabase.from("quotes").select(columns = Columns.list("catchphrase")) { filter { textSearch(column = "catchphrase", query = "'fat' & 'cat'", config = "english", type = TextSearchType.YOUR_TYPE) } } ``` - id: search-multiple-columns name: Search multiple columns code: | ```kotlin supabase.from("quotes").select(columns = Columns.list("catchphrase")) { filter { or { textSearch(column = "catchphrase", query = "'fat' & 'cat'", config = "english", type = TextSearchType.YOUR_TYPE) textSearch(column = "author", query = "'fat' & 'cat'", config = "english", type = TextSearchType.YOUR_TYPE) } } } ``` - id: basic-normalization name: Basic normalization description: Uses PostgreSQL's `plainto_tsquery` function. code: | ```kotlin supabase.from("quotes").select(columns = Columns.list("catchphrase")) { filter { textSearch(column = "catchphrase", query = "'fat' & 'cat'", config = "english", type = TextSearchType.PLAINTO) } } ``` - id: full-normalization name: Full normalization description: Uses PostgreSQL's `phraseto_tsquery` function. code: | ```kotlin supabase.from("quotes").select(columns = Columns.list("catchphrase")) { filter { textSearch(column = "catchphrase", query = "'fat' & 'cat'", config = "english", type = TextSearchType.PHRASETO) } } ``` - id: web-search name: Websearch description: | Uses PostgreSQL's `websearch_to_tsquery` function. This function will never raise syntax errors, which makes it possible to use raw user-supplied input for search, and can be used with advanced operators. - `unquoted text`: text not inside quote marks will be converted to terms separated by & operators, as if processed by plainto_tsquery. - `"quoted text"`: text inside quote marks will be converted to terms separated by `<->` operators, as if processed by phraseto_tsquery. - `OR`: the word “or” will be converted to the | operator. - `-`: a dash will be converted to the ! operator. code: | ```kotlin supabase.from("quotes").select(columns = Columns.list("catchphrase")) { filter { textSearch(column = "catchphrase", query = "'fat' & 'cat'", config = "english", type = TextSearchType.WEBSEARCH) } } ``` - id: filter title: filter() $ref: '@supabase/postgrest-js.PostgrestFilterBuilder.filter' notes: | filter() expects you to use the raw PostgREST syntax for the filter values. params: - name: column isOptional: false type: String description: The column to filter on. - name: operator isOptional: false type: FilterOperator description: The operator to use for the filter. - name: value isOptional: false type: Any description: The value to filter with. examples: - id: with-select name: With `select()` code: | ```kotlin supabase.from("characters").select { filter { filter(column = "name", operator = FilterOperator.IN, value = "('Han', 'Katniss')") } } ``` data: sql: | ```sql create table characters (id int8 primary key, name text); insert into characters (id, name) values (1, 'Luke'), (2, 'Leia'), (3, 'Han'); ``` response: | ```json { "data": [ { "id": 3, "name": "Han" } ], "status": 200, "statusText": "OK" } ``` hideCodeBlock: true isSpotlight: true - id: on-a-foreign-table name: On a foreign table code: | ```kotlin val columns = Columns.raw(""" name, instruments!inner ( name ) """.trimIndent()) supabase.from("orchestral_sections").select( columns = columns ) { filter { filter(column = "instruments.name", operator = FilterOperator.EQ, value = "flute") } } ``` data: sql: | ```sql create table orchestral_sections (id int8 primary key, name text); create table instruments ( id int8 primary key, section_id int8 not null references orchestral_sections, name text ); insert into orchestral_sections (id, name) values (1, 'flute'), (2, 'violin'); insert into instruments (id, section_id, name) values (1, 1, 'violin'), (2, 2, 'flute'); ``` response: | ```json { "data": [ { "name": "woodwinds", "instruments": [ { "name": "flute" } ] } ], "status": 200, "statusText": "OK" } ``` hideCodeBlock: true - id: using-modifiers title: Using Modifiers description: | Filters work on the row level—they allow you to return rows that only match certain conditions without changing the shape of the rows. Modifiers are everything that don't fit that definition—allowing you to change the format of the response (e.g., returning a CSV string). Modifiers are be specified next to the filter block. Some modifiers only apply for queries that return rows (e.g., `select()` or `rpc()` on a function that returns a table response). - id: db-modifiers-select title: select() $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.select' params: - name: columns isOptional: true type: Columns description: The columns to select. examples: - id: with-upsert name: With `upsert()` code: | ```kotlin val toUpsert = Country(id = 2, name = "Mordor") val count = supabase.from("countries").upsert(toUpsert) { select() }.decodeSingle() ``` data: sql: | ```sql create table countries (id int8 primary key, name text); insert into countries (id, name) values (1, 'The Shire'); ``` response: | ```json { "data": [ { "id": 2, "name": "Mordor" } ], "status": 201, "statusText": "Created" } ``` hideCodeBlock: true isSpotlight: true - id: order title: order() description: | Order the query result by column. $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.order' params: - name: column isOptional: false type: String description: The column to order by. - name: order isOptional: false type: Order description: The order to use. - name: nullsFirst isOptional: true type: Boolean description: Whether to order nulls first. - name: referencedTable isOptional: true type: String description: The foreign table to order by. examples: - id: with-select name: With `select()` code: | ```kotlin supabase.from("characters").select(columns = Columns.list("id", "name")) { order(column = "id", order = Order.DESCENDING) } ``` data: sql: | ```sql create table characters (id int8 primary key, name text); insert into characters (id, name) values (1, 'Luke'), (2, 'Leia'), (3, 'Han'); ``` response: | ```json { "data": [ { "id": 3, "name": "Han" }, { "id": 2, "name": "Leia" }, { "id": 1, "name": "Luke" } ], "status": 200, "statusText": "OK" } ``` hideCodeBlock: true isSpotlight: true - id: on-a-foreign-table name: On a foreign table code: | ```kotlin val columns = Columns.raw(""" name, instruments ( name ) """.trimIndent()) supabase.from("orchestral_sections").select( columns = columns ) { order(column = "id", order = Order.DESCENDING, referencedTable = "instruments") } ``` data: sql: | ```sql create table orchestral_sections (id int8 primary key, name text); create table instruments ( id int8 primary key, section_id int8 not null references orchestral_sections, name text ); insert into orchestral_sections (id, name) values (1, 'strings'), (2, 'woodwinds'); insert into instruments (id, section_id, name) values (1, 1, 'harp'), (2, 1, 'violin'); ``` response: | ```json { "data": [ { "name": "strings", "instruments": [ { "name": "violin" }, { "name": "harp" } ] }, { "name": "woodwinds", "instruments": [] } ], "status": 200, "statusText": "OK" } ``` description: | Ordering on foreign tables doesn't affect the ordering of the parent table. hideCodeBlock: true - id: order-parent-table-by-a-referenced-table name: Order parent table by a referenced table code: | ```kotlin val columns = Columns.raw(""" name, section:orchestral_sections(name) """.trimIndent()) supabase.from("instruments").select( columns = columns ) { order(column = "orchestral_sections(name)", order = Order.ASCENDING) } ``` data: sql: | ```sql create table orchestral_sections (id int8 primary key, name text); create table instruments ( id int8 primary key, section_id int8 not null references orchestral_sections, name text ); insert into orchestral_sections (id, name) values (1, 'strings'), (2, 'woodwinds'); insert into instruments (id, section_id, name) values (1, 2, 'flute'), (2, 1, 'violin'); ``` response: | ```json { "data": [ { "name": "violin", "section": { "name": "strings" } }, { "name": "flute", "section": { "name": "woodwinds" } } ], "status": 200, "statusText": "OK" } ``` description: | Ordering with `referenced_table(col)` affects the ordering of the parent table. hideCodeBlock: true - id: limit title: limit() description: | Limit the query result by count. $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.limit' params: - name: count isOptional: false type: Long description: The number of rows to limit the result to. - name: referencedTable isOptional: true type: String description: The foreign table to limit by. examples: - id: with-select name: With `select()` code: | ```kotlin supabase.from("characters").select { limit(count = 1) } ``` data: sql: | ```sql create table characters (id int8 primary key, name text); insert into characters (id, name) values (1, 'Luke'), (2, 'Leia'), (3, 'Han'); ``` response: | ```json { "data": [ { "name": "Luke" } ], "status": 200, "statusText": "OK" } ``` hideCodeBlock: true isSpotlight: true - id: on-a-foreign-table name: On a foreign table code: | ```kotlin val columns = Columns.raw(""" name, instruments ( name ) """) supabase.from("orchestral_sections").select( columns = columns ) { limit(count = 1, referencedTable = "instruments") } ``` data: sql: | ```sql create table orchestral_sections (id int8 primary key, name text); create table instruments ( id int8 primary key, section_id int8 not null references orchestral_sections, name text ); insert into orchestral_sections (id, name) values (1, 'strings'); insert into instruments (id, section_id, name) values (1, 1, 'harp'), (2, 1, 'violin'); ``` response: | ```json { "data": [ { "name": "strings", "instruments": [ { "name": "harp" } ] } ], "status": 200, "statusText": "OK" } ``` hideCodeBlock: true - id: range title: range() description: | Limit the query result by from and to inclusively. params: - name: from isOptional: false type: Long description: The start of the range. - name: to isOptional: false type: Long description: The end of the range. - name: referencedTable isOptional: true type: String description: The foreign table to limit by. examples: - id: with-select name: With `select()` code: | ```kotlin supabase.from("characters").select { range(1L..5L) } ``` data: sql: | ```sql create table characters (id int8 primary key, name text); insert into characters (id, name) values (1, 'Luke'), (2, 'Leia'), (3, 'Han'); ``` response: | ```json { "data": [ { "name": "Luke" }, { "name": "Leia" } ], "status": 200, "statusText": "OK" } ``` hideCodeBlock: true isSpotlight: true - id: single title: single() $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.single' examples: - id: with-select name: With `select()` code: | ```kotlin val result = supabase.from("characters").select(Columns.list("name")) { limit(1) single() } ``` data: sql: | ```sql create table characters (id int8 primary key, name text); insert into characters (id, name) values (1, 'Luke'), (2, 'Leia'), (3, 'Han'); ``` response: | ```json { "data": { "name": "Luke" }, "status": 200, "statusText": "OK" } ``` hideCodeBlock: true isSpotlight: true - id: maybe-single title: maybeSingle() $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.maybeSingle' examples: - id: with-select name: With `select()` isSpotlight: true code: | ```kotlin val result = supabase.from("characters").select(Columns.list("name")) { limit(1) maybeSingle() } ``` data: sql: | ```sql create table characters (id int8 primary key, name text); insert into characters (id, name) values (1, 'Luke'), (2, 'Leia'), (3, 'Han'); ``` response: | ```json { "data": { "name": "Luke" }, "status": 200, "statusText": "OK" } ``` hideCodeBlock: true - id: dry-run title: dryRun() description: | Executes the mutation but rolls back the transaction instead of committing it, so no changes are persisted. notes: | - The mutation runs and its result (including side effects such as triggers) is returned in the response, but the transaction is rolled back afterward. - Useful for testing mutations without touching real data. - Requires PostgREST's `db-tx-end` setting to allow client-controlled transaction rollback. examples: - id: with-update name: With `update()` isSpotlight: true code: | ```kotlin val toUpdate = City(name = "Mordor") supabase.from("cities").update(toUpdate) { filter { City::name eq "Gondor" } dryRun() } // Row is not actually updated in the database. ``` - id: csv $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.csv' title: csv() examples: - id: return-data-as-csv name: Return data as CSV code: | ```kotlin val (csvData, _) = supabase.from("characters").select { csv() } ``` data: sql: | ```sql create table characters (id int8 primary key, name text); insert into characters (id, name) values (1, 'Luke'), (2, 'Leia'), (3, 'Han'); ``` response: | ```json { "data": "id,name\n1,Luke\n2,Leia\n3,Han", "status": 200, "statusText": "OK" } ``` description: | By default, the data is returned in JSON format, but can also be returned as Comma Separated Values. hideCodeBlock: true isSpotlight: true - id: strip-nulls title: stripNulls() description: | Strip null values from the response. notes: | - Requires PostgREST 11.2.0 or later. examples: - id: strip-nulls name: Strip null values isSpotlight: true code: | ```kotlin val data = supabase .from("characters") .select { stripNulls() } ``` - id: explain $ref: '@supabase/postgrest-js.PostgrestTransformBuilder.explain' title: Using Explain description: | For debugging slow queries, you can get the [Postgres `EXPLAIN` execution plan](https://www.postgresql.org/docs/current/sql-explain.html) of a query using the `explain()` method. This works on any query, even for `rpc()` or writes. Explain is not enabled by default as it can reveal sensitive information about your database. It's best to only enable this for testing environments but if you wish to enable it for production you can provide additional protection by using a `pre-request` function. Follow the [Performance Debugging Guide](/docs/guides/database/debugging-performance) to enable the functionality on your project. params: - name: analyze isOptional: true type: Boolean description: If `true`, the query will be executed and the actual run time will be returned - name: verbose isOptional: true type: Boolean description: If `true`, the query identifier will be returned and `data` will include the output columns of the query - name: settings isOptional: true type: Boolean description: If `true`, include information on configuration parameters that affect query planning - name: buffers isOptional: true type: Boolean description: If `true`, include information on buffer usage - name: wal isOptional: true type: Boolean description: If `true`, include information on WAL record generation - name: format isOptional: true type: String description: The format of the output, can be `"text"` (default) or `"json"` examples: - id: get-execution-plan name: Get the execution plan code: | ```kotlin val result = supabase.from("characters").select { explain() } ``` data: sql: | ```sql create table characters (id int8 primary key, name text); insert into characters (id, name) values (1, 'Luke'), (2, 'Leia'), (3, 'Han'); ``` response: | ``` Aggregate (cost=33.34..33.36 rows=1 width=112) -> Limit (cost=0.00..18.33 rows=1000 width=40) -> Seq Scan on characters (cost=0.00..22.00 rows=1200 width=40) ``` description: | By default, the data is returned in TEXT format, but can also be returned as JSON by using the `format` parameter. hideCodeBlock: true isSpotlight: true - id: auth-api title: 'Overview' notes: | - The auth methods can be accessed via the Supabase Auth client. examples: - id: create-auth-client name: Create auth client isSpotlight: true code: | ```kotlin val supabase = createSupabaseClient(supabaseUrl = "https://xyzcompany.supabase.co", supabaseKey = "your-publishable-key") { ... } val auth = supabase.auth ``` - id: sign-up title: 'signUp()' $ref: '@supabase/gotrue-js.GoTrueClient.signUp' notes: | Creates a new user. - By default, the user needs to verify their email address before signing in. To turn this off, disable **Confirm email** in [your project](https://supabase.com/dashboard/project/_/auth/providers). - **Confirm email** determines if users need to confirm their email address after signing up. - If **Confirm email** is enabled, the return value is the user and you won't be signed in automatically. - If **Confirm email** is disabled, the return value is null and you will be signed in instead. - When the user confirms their email address, they are redirected to the [`SITE_URL`](https://supabase.com/docs/guides/auth/redirect-urls) by default. You can modify your `SITE_URL` or add additional redirect URLs in [your project](https://supabase.com/dashboard/project/_/auth/url-configuration). - To learn how to handle OTP links & OAuth refer to [initializing](/docs/reference/kotlin/initializing) - If signUpWith() is called for an existing confirmed user: - When both **Confirm email** and **Confirm phone** (even when phone provider is disabled) are enabled in [your project](/dashboard/project/_/auth/providers), an obfuscated/fake user object is returned. - When either **Confirm email** or **Confirm phone** (even when phone provider is disabled) is disabled, the error message, `User already registered` is returned. params: - name: provider isOptional: false type: Email or Phone description: The provider to use for the user's authentication. In this case `Email` or `Phone`. - name: redirectUrl isOptional: true type: String? description: The redirect url to use. If you don't specify this, the platform specific will be used, like deeplinks on android. - name: config isOptional: true type: Email.Config.() -> Unit or Phone.Config.() -> Unit description: The configuration for signing in with `Email` or `Phone`. subContent: - name: password isOptional: false type: String description: The user's password - name: email/phone isOptional: false type: String description: The user's email or phone. - name: captchaToken isOptional: true type: String? description: The captcha token when having captcha enabled. - name: data isOptional: true type: JsonObject? description: Extra user data to pass in. examples: - id: sign-up-email name: Sign up with email isSpotlight: true code: | ```kotlin val user = supabase.auth.signUpWith(Email) { email = "example@email.com" password = "example-password" } ``` - id: sign-up-phone-whatsapp name: Sign up with a phone number and password (whatsapp) isSpotlight: true code: | ```kotlin val user = supabase.auth.signUpWith(Phone) { phone = "+4912345679" password = "example-password" channel = Phone.Channel.WHATSAPP } ``` - id: sign-up-phone-sms name: Sign up with a phone number and password (sms) isSpotlight: true code: | ```kotlin val user = supabase.auth.signUpWith(Phone) { phone = "+4912345679" password = "example-password" } ``` - id: sign-up-with-additional-user-metadata name: Sign up with additional user metadata isSpotlight: false code: | ```kotlin val user = supabase.auth.signUpWith(Email) { email = "example@email.com" password = "example-password" data = buildJsonObject { put("first_name", "John") put("age", 24) } } ``` - id: sign-up-with-redirect name: Sign up with a redirect URL description: | - See [redirect URLs and wildcards](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls) to add additional redirect URLs to your project. code: | ```kotlin val user = supabase.auth.signUpWith(Email, redirectUrl = "https://example.com") { email = "example@email.com" password = "example-password" } ``` - id: sign-in-anonymously title: 'signInAnonymously()' notes: | - Creates an anonymous user. - The user can be retrieved by calling `supabase.auth.currentUserOrNull()`. - It is recommended to set up captcha for anonymous sign-ins to prevent abuse. You can pass in the captcha token in the `options` param. params: - name: captchaToken isOptional: true type: String? description: The captcha token when having captcha enabled. - name: data isOptional: true type: JsonObject? or T description: Extra user data to pass in. examples: - id: sign-in-anonymously name: Create an anonymous user isSpotlight: true code: | ```kotlin supabase.auth.signInAnonymously(captchaToken = "token") ``` - id: sign-in-anonymously-with-user-metadata name: Create an anonymous user with custom user metadata isSpotlight: false code: | ```kotlin supabase.auth.signInAnonymously(data = customUserData) ``` - id: sign-in-with-password title: 'signInWith()' $ref: '@supabase/gotrue-js.GoTrueClient.signInWithPassword' notes: | Logs in an existing user. - Requires either an email and password or a phone number and password. params: - name: provider isOptional: false type: Email or Phone description: The provider to use for the user's authentication, in this case `Email` or `Phone`. - name: redirectUrl isOptional: true type: String? description: The redirect url to use. If you don't specify this, the platform specific will be used, like deeplinks on android. - name: config isOptional: true type: Email.Config.() -> Unit or Phone.Config.() -> Unit description: The configuration for signing in with `Email` or `Phone`. subContent: - name: password isOptional: false type: String description: The user's password - name: email/phone isOptional: false type: String description: The user's email or phone. - name: captchaToken isOptional: true type: String? description: The captcha token when having captcha enabled. examples: - id: sign-in-with-email-and-password name: Sign in with email and password isSpotlight: true code: | ```kotlin supabase.auth.signInWith(Email) { email = "example@email.com" password = "example-password" } ``` - id: sign-in-with-phone-and-password name: Sign in with phone and password isSpotlight: false code: | ```kotlin supabase.auth.signInWith(Phone) { phone = "+4912345679" password = "example-password" } ``` - id: sign-in-with-id-token title: 'signInWithIdToken' params: - name: provider isOptional: false type: IDToken description: The provider to use for the user's authentication. For this method it will be `IDToken`. - name: redirectUrl isOptional: true type: String? description: The redirect url to use. If you don't specify this, the platform specific will be used, like deeplinks on android. - name: config isOptional: true type: IDToken.Config.() -> Unit description: The configuration for signing in with an id token. subContent: - name: idToken isOptional: false type: String description: OIDC ID token issued by the specified provider. The `iss` claim in the ID token must match the supplied provider. Some ID tokens contain an `at_hash` which require that you provide an `access_token` value to be accepted properly. If the token contains a `nonce` claim you must supply the nonce used to obtain the ID token. - name: provider isOptional: false type: IDTokenProvider description: The provider of the id token. Only `Apple`, `Google`, `Facebook` and `Azure` are supported. - name: accessToken isOptional: true type: String? description: If the ID token contains an `at_hash` claim, then the hash of this value is compared to the value in the ID token. - name: nonce isOptional: true type: String? description: If the ID token contains a `nonce` claim, then the hash of this value is compared to the value in the ID token. - name: captchaToken isOptional: true type: String? description: The captcha token when having captcha enabled. - name: data isOptional: true type: JsonObject? description: '**Deprecated** — use `extraData` or user metadata on the sign-up flow instead. Will be removed in a future release.' examples: - id: sign-in-with-id-token name: 'Sign In using ID Token' code: | ```kotlin supabase.auth.signInWith(IDToken) { idToken = "token" provider = Google //Also supported: Apple, Azure and Facebook //optional: nonce = "nonce" } ``` - id: sign-in-with-otp title: 'signInWith(OTP)' $ref: '@supabase/gotrue-js.GoTrueClient.signInWithOtp' notes: | Sends a OTP to the user's email or phone number. - Requires either an email or phone number. - This method is used for passwordless sign-ins where a OTP is sent to the user's email or phone number. - If the user doesn't exist, `signInWith(OTP)` will signup the user instead. To restrict this behavior, you can set `createUser` to `false`. - The method `signUpWith(OTP)` does the exact same thing as `signInWith(OTP)`, so it doesn't matter which one you use. - If you're using an email, you can configure whether you want the user to receive a magiclink or a OTP. - If you're using phone, you can configure whether you want the user to receive a OTP. - The magic link's destination URL is determined by the [`SITE_URL`](/docs/guides/auth/redirect-urls). - See [redirect URLs and wildcards](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls) to add additional redirect URLs to your project. - To learn how to handle OTP links & OAuth refer to [initializing](/docs/reference/kotlin/initializing) - Magic links and OTPs share the same implementation. To send users a one-time code instead of a magic link, [modify the magic link email template](https://supabase.com/dashboard/project/_/auth/templates) to include `{{ .Token }}` instead of `{{ .ConfirmationURL }}`. params: - name: provider isOptional: false type: OTP description: The provider to use for the user's authentication, in this case `OTP`. - name: redirectUrl isOptional: true type: String? description: The redirect url to use. If you don't specify this, the platform specific will be used, like deeplinks on android. - name: config isOptional: true type: OTP.Config.() -> Unit description: The configuration for signing in with `OTP`. subContent: - name: email/phone isOptional: false type: String description: The user's email or phone. - name: captchaToken isOptional: true type: String? description: The captcha token when having captcha enabled. - name: channel isOptional: true type: Phone.Channel? description: The channel to send the OTP to when using phone sign-in. Defaults to SMS. Set to `Phone.Channel.WHATSAPP` for WhatsApp delivery. examples: - id: sign-in-with-email name: Sign in with email isSpotlight: true description: The user will be sent an email which contains either a magiclink or a OTP or both. By default, a given user can only request a OTP once every 60 seconds. code: | ```kotlin supabase.auth.signInWith(OTP) { email = "example@email.com" } ``` - id: sign-in-with-sms-otp name: Sign in with SMS OTP isSpotlight: false description: The user will be sent a SMS which contains a OTP. By default, a given user can only request a OTP once every 60 seconds. code: | ```kotlin supabase.auth.signInWith(OTP) { phone = "+4912345679" } ``` - id: sign-in-with-whatsapp-otp name: Sign in with WhatsApp OTP isSpotlight: false description: The user will be sent a WhatsApp message which contains an OTP. Requires a Twilio or Twilio Verify provider to be configured. code: | ```kotlin supabase.auth.signInWith(OTP) { phone = "+4912345679" channel = Phone.Channel.WHATSAPP } ``` - id: sign-in-with-oauth title: 'signInWith(OAuthProvider)' $ref: '@supabase/gotrue-js.GoTrueClient.signInWithOAuth' notes: | - This method is used for signing in using a third-party provider. - Supabase supports many different [third-party providers](https://supabase.com/docs/guides/auth#providers). - To learn how to handle OTP links & OAuth refer to [initializing](/docs/reference/kotlin/initializing) - The `signInWith(Provider)` method can be called anywhere, you can treat it like any other suspending function. - This method will not wait for the OAuth response and will return after the corresponding platform implementation was called, which is by default opening the system browser. - The callback will happen differently on the targets. On Mobile devices it will be handled via `handleDeeplinks()`, if set up. On Desktop and JS devices it will be automatically handled. params: - name: provider isOptional: false type: OAuthProvider description: The OAuth provider to use for the user's authentication, for example `Google` or `GitHub`. - name: redirectUrl isOptional: true type: String? description: The redirect url to use. If you don't specify this, the platform specific will be used, like deeplinks on android. - name: config isOptional: true type: ExternalAuthConfig.() -> Unit description: The configuration for signing in with an OAuth provider. subContent: - name: scopes isOptional: true type: MutableList description: The scopes to request from the OAuth provider. - name: queryParams isOptional: true type: MutableMap description: Additional query parameters to use. examples: - id: sign-in-using-a-third-party-provider name: Sign in using a third-party provider isSpotlight: true code: | ```kotlin supabase.auth.signInWith(Github) ``` - id: sign-in-using-a-third-party-provider with scopes name: Sign in using a third-party provider with scopes isSpotlight: true code: | ```kotlin supabase.auth.signInWith(Github) { scopes.add("email") } ``` - id: sign-in-using-a-third-party-provider-with-redirect name: Create a custom url isSpotlight: false description: | - When the third-party provider successfully authenticates the user, the provider redirects the user to the URL specified in the `redirectUrl` parameter. This parameter defaults to the [`SITE_URL`](/docs/guides/auth/redirect-urls). It does not redirect the user immediately after invoking this method. - See [redirect URLs and wildcards](/docs/guides/auth/redirect-urls#use-wildcards-in-redirect-urls) to add additional redirect URLs to your project. - getOAuthUrl() provides the URL which needs to be opened in a browser. - The redirectTo URL needs to be setup correctly in your project under Authentication -> URL Configuration -> Redirect URLs. - To see how you can use a custom in-app browser on Android, check our [demo](https://github.com/supabase-community/supabase-kt/tree/development/demos/android-login) on GitHub. code: | ```kotlin val url = supabase.auth.getOAuthUrl(Github, redirectUrl = "https://example.com") ``` - id: sign-in-with-scopes name: Create a custom url with scopes isSpotlight: false description: | If you need additional data from an OAuth provider, you can include a space-separated list of scopes in your request to get back an OAuth provider token. You may also need to specify the scopes in the provider's OAuth app settings, depending on the provider. The list of scopes will be documented by the third-party provider you are using and specifying scopes will enable you to use the OAuth provider token to call additional APIs supported by the third-party provider to get more information. code: | ```kotlin val url = supabase.auth.getOAuthUrl(Github, redirectUrl = "https://example.com") { scopes.add("email") } ``` - id: sign-in-with-sso title: 'signInWithSSO()' $ref: '@supabase/gotrue-js.GoTrueClient.signInWithSSO' notes: | - Before you can call this method you need to [establish a connection](/docs/guides/auth/enterprise-sso/auth-sso-saml#managing-saml-20-connections) to an identity provider. Use the [CLI commands](/docs/reference/cli/supabase-sso) to do this. - If you've associated an email domain to the identity provider, you can change the `domain` property in the `signInWith(SSO)` method to start a sign-in flow. - In case you need to use a different way to start the authentication flow with an identity provider, you can change the `providerId` property. For example: - Mapping specific user email addresses with an identity provider. - Using different hints to identity the identity provider to be used by the user, like a company-specific page, IP address or other tracking information. - To learn how to handle OTP links & OAuth refer to [initializing](/docs/reference/kotlin/initializing) params: - name: provider isOptional: false type: SSO description: The OAuth provider to use for the user's authentication, in this case `SSO`. - name: redirectUrl isOptional: true type: String? description: The redirect url to use. If you don't specify this, the platform specific will be used, like deeplinks on android. - name: config isOptional: true type: ExternalAuthConfig.() -> Unit description: The configuration for signing in with an OAuth provider. subContent: - name: providerId/domain isOptional: false type: String description: The providerId or domain. - name: captchaToken isOptional: true type: String? description: The captcha token when having captcha enabled. examples: - id: sign-in-with-domain name: Sign in with email domain isSpotlight: true code: | ```kotlin // You can extract the user's email domain and use it to trigger the // authentication flow with the correct identity provider. supabase.auth.signInWith(SSO) { domain = "company.com" } //the url was opened automatically, if you don't want that, provide a custom redirect url ``` - id: sign-in-with-provider-uuid name: Sign in with provider UUID isSpotlight: true code: | ```kotlin // Useful when you need to map a user's sign in request according // to different rules that can't use email domains. supabase.auth.signInWith(SSO) { providerId = "21648a9d-8d5a-4555-a9d1-d6375dc14e92" } //the url was opened automatically, if you don't want that, provide a custom redirect url ``` - id: sign-out title: 'signOut()' $ref: '@supabase/gotrue-js.GoTrueClient.signOut' notes: | Logs out the current user. - In order to use the `signOut()` method, the user needs to be signed in first. params: - name: scope isOptional: true type: SignOutScope description: The scope of the sign-out. examples: - id: sign-out name: Sign out isSpotlight: true code: | ```kotlin supabase.auth.signOut() ``` - id: sign-out-all-sessions name: Sign out all sessions isSpotlight: true code: | ```kotlin supabase.auth.signOut(SignOutScope.GLOBAL) ``` - id: sign-out-others name: Sign out all sessions except the current isSpotlight: true code: | ```kotlin supabase.auth.signOut(SignOutScope.OTHERS) ``` - id: verify-otp title: 'Verify OTPs' $ref: '@supabase/gotrue-js.GoTrueClient.verifyOtp' notes: | - Verifying an OTP is done through either `verifyPhoneOtp` or `verifyEmailOtp`. - The verification type used should be determined based on the corresponding auth method called before using `verifyPhoneOtp`/`verifyEmailOtp` to sign up / sign-in a user. params: - name: type isOptional: false type: OtpType.Email or OtpType.Phone description: The OTP type. Depending on the type, an email or phone has to be specified as parameter. - name: email/phone isOptional: false type: String description: The email or phone number, depending on which type you specified. - name: token isOptional: false type: String description: The token to verify. - name: captchaToken isOptional: true type: String? description: The captcha token when having captcha enabled. examples: - id: verify-email-otp(otp) name: Verify an Email OTP isSpotlight: true code: | ```kotlin supabase.auth.verifyEmailOtp(type = OtpType.Email.EMAIL, email = "example@email.com", token = "token") ``` description: | Available types are: - `OtpType.Email.MAGIC_LINK` (deprecated) - `OtpType.Email.SIGNUP` (deprecated) - `OtpType.Email.INVITE` - `OtpType.Email.RECOVERY` - `OtpType.Email.EMAIL_CHANGE` - `OtpType.Email.EMAIL` - id: verify-phone-otp(otp) name: Verify an Phone OTP isSpotlight: false code: | ```kotlin supabase.auth.verifyPhoneOtp(type = OtpType.Phone.SMS, phone = "+491234567", token = "token") ``` description: | Available types are: - `OtpType.Phone.SMS` - `OtpType.Phone.PHONE_CHANGE` - id: send-password-reauthentication title: 'reauthenticate()' $ref: '@supabase/gotrue-js.GoTrueClient.reauthenticate' notes: | - This method is used together with `updateUser()` when a user's password needs to be updated. - This method will send a nonce to the user's email. If the user doesn't have a confirmed email address, the method will send the nonce to the user's confirmed phone number instead. examples: - id: send-reauthentication-nonce name: Send reauthentication nonce description: Sends a reauthentication nonce to the user's email or phone number. isSpotlight: true code: | ```kotlin supabase.auth.reauthenticate() ``` - id: resend-email-or-phone-otps title: 'resend()' $ref: '@supabase/gotrue-js.GoTrueClient.resend' notes: | - Resends a signup confirmation, email change or phone change email to the user. - Passwordless sign-ins can be resent by calling the `signInWith(OTP)` method again. - Password recovery emails can be resent by calling the `resetPasswordForEmail()` method again. - This method will only resend an email or phone OTP to the user if there was an initial signup, email change or phone change request being made. params: - name: type isOptional: false type: OtpType.Email or OtpType.Phone description: The OTP type. Depending on the type, an email or phone has to be specified as parameter. - name: email/phone isOptional: false type: String description: The email or phone number, depending on which type you specified. - name: captchaToken isOptional: true type: String? description: The captcha token when having captcha enabled. examples: - id: resend-email-signup-confirmation name: Resend an email signup confirmation description: Resends the email signup confirmation to the user isSpotlight: true code: | ```kotlin supabase.auth.resendEmail(OtpType.Email.SIGNUP, "example@email.com") ``` - id: resend-phone-signup-confirmation name: Resend a phone signup confirmation description: Resends the phone signup confirmation email to the user code: | ```kotlin supabase.auth.resendPhone(OtpType.Phone.SMS, "1234567890") ``` - id: resend-email-change-email name: Resend email change email description: Resends the email change email to the user code: | ```kotlin supabase.auth.resendEmail(OtpType.Email.EMAIL_CHANGE, "example@email.com") ``` - id: resend-phone-change name: Resend phone change OTP description: Resends the phone change OTP to the user code: | ```kotlin supabase.auth.resendPhone(OtpType.Phone.PHONE_CHANGE, "1234567890") ``` - id: get-session title: 'Get current session' $ref: '@supabase/gotrue-js.GoTrueClient.getSession' notes: | Returns the current session, or `null` if there is none. examples: - id: get-the-session-data name: Get the session data isSpotlight: true code: | ```kotlin val session = supabase.auth.currentSessionOrNull() ``` - id: get-user title: 'getUser()' $ref: '@supabase/gotrue-js.GoTrueClient.getUser' description: | - 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. params: - name: jwt isOptional: false type: String description: The JWT token. examples: - id: get-the-logged-in-user-with-the-current-existing-session name: Get the signed-in user with the current session isSpotlight: true code: | ```kotlin val user = supabase.auth.retrieveUserForCurrentSession(updateSession = true) ``` description: | `updateSession` updates the local session with the new user - id: get-different-user name: Get a user based on their access token isSpotlight: true code: | ```kotlin val user = supabase.auth.retrieveUser("JWT") ``` - id: update-user title: 'updateUser()' $ref: '@supabase/gotrue-js.GoTrueClient.updateUser' notes: | Modifies the user data. - In order to use the `updateUser()` method, the user needs to be signed in first. - By default, email updates sends a confirmation link to both the user's current and new email. To only send a confirmation link to the user's new email, disable **Secure email change** in your project's [email auth provider settings](https://supabase.com/dashboard/project/_/auth/providers). params: - name: updateCurrentUser isOptional: true type: Boolean description: Whether to update the local session with the new user. Defaults to `true`. - name: redirectUrl isOptional: true type: String? description: The redirect url to use. If you don't specify this, the platform specific will be used, like deeplinks on android. - name: config isOptional: false type: UserUpdateBuilder.() -> Unit subContent: - name: email isOptional: true type: String? description: The new email. - name: password isOptional: true type: String? description: The new password. - name: phone isOptional: true type: String? description: The new phone number. - name: nonce isOptional: true type: String? description: The nonce sent for reauthentication if the user's password is to be updated. - name: data isOptional: true type: JsonObject description: The new user data. - name: currentPassword isOptional: true type: String? description: The current password. Required when reauthentication is needed to change the password. examples: - id: update-the-email-for-an-authenticated-user name: Update the email for an authenticated user description: Sends a "Confirm Email Change" email to the new email address. isSpotlight: false code: | ```kotlin val user = supabase.auth.updateUser { email = "newEmail@email.com" } ``` - id: update-the-password-for-an-authenticated-user name: Update the password for an authenticated user isSpotlight: false code: | ```kotlin val user = supabase.auth.updateUser { password = "secretPassword" } ``` - id: update-the-users-metadata name: Update the user's metadata isSpotlight: true code: | ```kotlin val user = supabase.auth.updateUser { data { put("name", "John") } } ``` - id: get-user-identities title: 'currentIdentitiesOrNull()' $ref: '@supabase/gotrue-js.GoTrueClient.getUserIdentities' notes: | - The user needs to be signed in to call `currentIdentitiesOrNull()`. examples: - id: get-user-identities name: Returns a list of identities linked to the user isSpotlight: true code: | ```kotlin //get the identities from the current user val identities = supabase.auth.currentIdentitiesOrNull() //Or retrieve them val identities = supabase.auth.retrieveUserForCurrentSession().identities ``` - id: link-identity title: 'linkIdentity()' $ref: '@supabase/gotrue-js.GoTrueClient.linkIdentity' notes: | - The **Enable Manual Linking** option must be enabled from your [project's authentication settings](/dashboard/project/_/auth/providers). - The user needs to be signed in to call `linkIdentity()`. - If the candidate identity is already linked to the existing user or another user, `linkIdentity()` will fail. - This method works similarly to `signInWith()` using an OAuthProvider. To learn how to handle OTP links & OAuth refer to [initializing](/docs/reference/kotlin/initializing) params: - name: provider isOptional: false type: OAuthProvider description: The OAuth provider you want to link the user with. - name: redirectUrl isOptional: true type: String? description: The redirect url to use. If you don't specify this, the platform specific will be used, like deeplinks on android. - name: config isOptional: true type: ExternalAuthConfigDefaults.() -> Unit description: Extra configuration. subContent: - name: scopes isOptional: true type: MutableList description: The scopes to request from the OAuth provider. - name: queryParams isOptional: true type: MutableMap description: Additional query parameters to use. examples: - id: link-identity name: Link an identity to a user isSpotlight: true code: | ```kotlin supabase.auth.linkIdentity(OAuthProvider) //Example: supabase.auth.linkIdentity(Google) ``` - id: link-identity-idtoken name: Link an identity to a user via an id token isSpotlight: true code: | ```kotlin supabase.auth.linkIdentityWithIdToken(Google, idToken = "receivedToken") ``` - id: unlink-identity title: 'unlinkIdentity()' $ref: '@supabase/gotrue-js.GoTrueClient.unlinkIdentity' notes: | - The **Enable Manual Linking** option must be enabled from your [project's authentication settings](/dashboard/project/_/auth/providers). - The user needs to be signed in to call `unlinkIdentity()`. - The user must have at least 2 identities in order to unlink an identity. - The identity to be unlinked must belong to the user. params: - name: identityId isOptional: false type: String description: The id of the OAuth identity - name: updateLocalUser isOptional: true type: Boolean description: Whether to delete the identity from the local user or not. Defaults to `true`. examples: - id: unlink-identity name: Unlink an identity isSpotlight: true code: | ```kotlin //get all identities linked to a user val identities = supabase.auth.currentIdentitiesOrNull() ?: emptyList() //find the google identity linked to the user val googleIdentity = identities.first { it.provider == "google" } //unlink the google identity from the user supabase.auth.unlinkIdentity(googleIdentity.identityId!!) ``` - id: set-session title: 'importSession()' $ref: '@supabase/gotrue-js.GoTrueClient.setSession' notes: | Changes the local session. - `importSession()` takes in a UserSession. - [Refresh token rotation](/docs/reference/auth/config#refresh_token_rotation_enabled) is enabled by default on all projects to guard against replay attacks. - You can configure the [`REFRESH_TOKEN_REUSE_INTERVAL`](https://supabase.com/docs/reference/auth/config#refresh_token_reuse_interval) which provides a short window in which the same refresh token can be used multiple times in the event of concurrency or offline issues. params: - name: session isOptional: false type: UserSession description: The session to set. examples: - id: refresh-the-session name: Set local session description: Sets the local session from refresh_token and returns current session or an error if the refresh_token is invalid. isSpotlight: true code: | ```kotlin supabase.auth.importSession(UserSession(accessToken = "token", refreshToken = "refresh", expiresIn = 2000, tokenType = "Bearer", user = null)) ``` - id: refresh-session title: 'refreshSession()' $ref: '@supabase/gotrue-js.GoTrueClient.refreshSession' notes: | This method will refresh the session whether the current one is expired or not. - This is done automatically, but can be disabled in the Auth config. params: - name: refreshToken isOptional: false type: String description: The refresh token to use. examples: - id: refresh-current-session name: Refresh current session isSpotlight: true code: | ```kotlin val session = supabase.auth.refreshCurrentSession() ``` - id: refresh-session-using-the-current-session name: Refresh session using the refresh token isSpotlight: true code: | ```kotlin val session = supabase.auth.refreshSession(refreshToken = "refreshToken") ``` - id: on-auth-state-change title: 'sessionStatus' $ref: '@supabase/gotrue-js.GoTrueClient.onAuthStateChange' notes: | Listen to session changes. - `sessionStatus` is a `Flow` that emits the current session status. Everything related to the session is handled by this flow. - `events` is a `Flow` that emits auth events. This flow is used to listen to auth events that are independent of the current session, like OTP errors, refresh failures, etc. Experimental. examples: - id: listen-to-auth-changes name: Listen to session status changes isSpotlight: true code: | ```kotlin supabase.auth.sessionStatus.collect { when(it) { is SessionStatus.Authenticated -> { println("Received new authenticated session.") when(it.source) { //Check the source of the session SessionSource.External -> TODO() is SessionSource.Refresh -> TODO() is SessionSource.SignIn -> TODO() is SessionSource.SignUp -> TODO() SessionSource.Storage -> TODO() SessionSource.Unknown -> TODO() is SessionSource.UserChanged -> TODO() is SessionSource.UserIdentitiesChanged -> TODO() } } SessionStatus.Initializing -> println("Initializing") is SessionStatus.RefreshFailure -> { println("Session expired and could not be refreshed") } is SessionStatus.NotAuthenticated -> { if(it.isSignOut) { println("User signed out") } else { println("User not signed in") } } } } ``` description: | Types of statuses: - `NotAuthenticated(isSignOut)`, - `Initializing`, - `RefreshFailure(cause)`, - `Authenticated(session, source)` - id: listen-to-events name: Listen to auth events isSpotlight: false code: | ```kotlin supabase.auth.events.collect { when(it) { is AuthEvent.OtpError -> println("Found error in current URL / deeplink during the OAuth flow: ${it.error}") is AuthEvent.RefreshFailure -> println("Failed to refresh session: ${it.error}") } } ``` - id: reset-password-for-email title: 'Send a password reset request' notes: | Sends a password reset request to the given email address. - The password reset flow consists of 2 broad steps: (i) Allow the user to sign in via the password reset link; (ii) Update the user's password. - The `resetPasswordForEmail()` only sends a password reset link to the user's email. To update the user's password, see [`updateUser()`](/docs/reference/kotlin/auth-updateuser). - The user gets redirected back to your app, assuming you setup [OTP handling](/docs/reference/kotlin/initializing) - After the user has been redirected successfully, prompt them for a new password and call `updateUser()`: ```kotlin supabase.auth.updateUser { password = "1234567" } ``` params: - name: email isOptional: false type: String description: The email to send the password reset email to. - name: redirectUrl isOptional: true type: String? description: The redirect url to use. If you don't specify this, the platform specific will be used, like deeplinks on android. - name: captchaToken isOptional: true type: String? description: The captcha token when having captcha enabled. examples: - id: send-password-reset-email name: Send password reset email isSpotlight: true code: | ```kotlin supabase.auth.resetPasswordForEmail(email = "example@email.com") ``` - id: exchange-code-for-session title: 'exchangeCodeForSession()' $ref: '@supabase/gotrue-js.GoTrueClient.exchangeCodeForSession' notes: | - Used when `flowType` is set to `FlowType.PKCE` in the Auth configuration. params: - name: code isOptional: false type: String description: The code to exchange. - name: saveSession isOptional: true type: Boolean description: Whether to save the session. Defaults to true. examples: - id: exchange-auth-code name: Exchange Auth Code isSpotlight: true code: | ```kotlin supabase.auth.exchangeCodeForSession("34e770dd-9ff9-416c-87fa-43b31d7ef225") ``` - id: auth-mfa-api title: 'Overview' notes: | This section contains methods commonly used for Multi-Factor Authentication (MFA) and are invoked behind the `supabase.auth.mfa` namespace. Currently, we only support time-based one-time password (TOTP) as the 2nd factor. We don't support recovery codes but we allow users to enroll more than 1 TOTP factor, with an upper limit of 10. Having a 2nd TOTP factor for recovery frees the user of the burden of having to store their recovery codes somewhere. It also reduces the attack surface since multiple recovery codes are usually generated compared to just having 1 backup TOTP factor. - id: mfa-enroll title: 'Enroll a factor' $ref: '@supabase/gotrue-js.GoTrueMFAApi.enroll' notes: | Enrolls a new factor. - Use `FactorType.TOTP` or `FactorType.Phone` as the factorType and use the returned id to create a challenge. - To create a challenge, see [`mfa.createChallenge()`](/docs/reference/kotlin/auth-mfa-challenge). - To verify a challenge, see [`mfa.verifyChallenge()`](/docs/reference/kotlin/auth-mfa-verify). - To create and verify a challenge in a single step, see [`mfa.createChallengeAndVerify()`](/docs/reference/kotlin/auth-mfa-challengeandverify). params: - name: factorType isOptional: false type: FactorType description: The type of MFA factor to enroll. Currently supports `FactorType.TOTP` and `FactorType.Phone`. - name: issuer isOptional: true type: String? description: Domain which the user is enrolling with. - name: config isOptional: true type: Config.() -> Unit description: Factor type specific configuration. examples: - id: enroll-totp-factor name: Enroll a time-based, one-time password (TOTP) factor isSpotlight: true code: | ```kotlin val factor = supabase.auth.mfa.enroll(factorType = FactorType.TOTP, friendlyName = "Your friendly Name") { // Optional issuer = "example.com" } // 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 val challenge = supabase.auth.mfa.createChallenge(factor.id) ``` - id: enroll-phone-factor name: Enroll a Phone Factor isSpotlight: true code: | ```kotlin val factor = supabase.auth.mfa.enroll(factorType = FactorType.Phone, friendlyName = "Your friendly Name") { phone = "+123456789" } // Use the id to create a challenge and send an SMS with a code to the user. val (phone) = factor.data val (factorId, factorType, _) = factor val challenge = supabase.auth.mfa.createChallenge(factor.id) ``` - id: get-local-verified-factors name: Check the local user for verified factors isSpotlight: true code: | ```kotlin val verifiedFactors = supabase.auth.mfa.verifiedFactors ``` - id: retrieve-verified-factors name: Retrieve verified factors isSpotlight: true code: | ```kotlin val verifiedFactors = supabase.auth.mfa.retrieveFactorsForCurrentUser() ``` - id: mfa-challenge title: 'mfa.challenge()' $ref: '@supabase/gotrue-js.GoTrueMFAApi.challenge' notes: | Creates a challenge for a factor. - An [enrolled factor](/docs/reference/kotlin/auth-mfa-enroll) is required before creating a challenge. - To verify a challenge, see [`mfa.verifyChallenge()`](/docs/reference/kotlin/auth-mfa-verify). - A phone factor sends a code to the user upon challenge. The channel defaults to `Phone.Channel.SMS` unless otherwise specified. params: - name: factorId isOptional: false type: String description: The id of the MFA factor you want to create a challenge for. - name: channel isOptional: true type: Phone.Channel? description: The channel to send the challenge to. Defaults to `Phone.Channel.SMS`. examples: - id: create-mfa-challenge name: Create a challenge for a factor isSpotlight: true code: | ```kotlin val challenge = supabase.auth.mfa.createChallenge(factorId = "34e770dd-9ff9-416c-87fa-43b31d7ef225") ``` - id: mfa-verify title: 'mfa.verify()' $ref: '@supabase/gotrue-js.GoTrueMFAApi.verify' notes: | Verifies a challenge for a factor. - To verify a challenge, please [create a challenge](/docs/reference/kotlin/auth-mfa-challenge) first. params: - name: factorId isOptional: false type: String description: The id of the MFA factor to verify. - name: challengeId isOptional: false type: String description: The id of the challenge to verify. - name: code isOptional: false type: String description: The code used to verify. - name: saveSession isOptional: true type: Boolean description: Whether to save the session. Defaults to true. examples: - id: verify-challenge name: Verify a challenge for a factor isSpotlight: true code: | ```kotlin supabase.auth.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 ) ``` - id: mfa-challenge-and-verify title: 'mfa.challengeAndVerify()' $ref: '@supabase/gotrue-js.GoTrueMFAApi.challengeAndVerify' notes: | Creates and verifies a challenge for a factor. - Creating and verifying a challenge in a single step is not supported by the `Phone` factor type. - An [enrolled factor](/docs/reference/kotlin/auth-mfa-enroll) is required before invoking `createChallengeAndVerify()`. - Executes [`mfa.createChallenge()`](/docs/reference/kotlin/auth-mfa-challenge) and [`mfa.verifyChallenge()`](/docs/reference/kotlin/auth-mfa-verify) in a single step. params: - name: factorId isOptional: false type: String description: The id of the MFA factor to verify. - name: code isOptional: false type: String description: The code used to verify. - name: saveSession isOptional: true type: Boolean description: Whether to save the session. Defaults to true. examples: - id: challenge-and-verify name: Create and verify a challenge for a factor isSpotlight: true code: | ```kotlin supabase.auth.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 ) ``` - id: mfa-unenroll title: 'mfa.unenroll()' $ref: '@supabase/gotrue-js.GoTrueMFAApi.unenroll' notes: | Unenroll removes a MFA factor. A user has to have an `AAL2` authentication level in order to unenroll a verified factor. params: - name: factorId isOptional: false type: String description: The id of the factor you want to unenroll. examples: - id: unenroll-a-factor name: Unenroll a factor isSpotlight: true code: | ```kotlin supabase.auth.mfa.unenroll(factorId = "34e770dd-9ff9-416c-87fa-43b31d7ef225") ``` - id: mfa-get-authenticator-assurance-level title: 'mfa.getAuthenticatorAssuranceLevel()' $ref: '@supabase/gotrue-js.GoTrueMFAApi.getAuthenticatorAssuranceLevel' notes: | - Authenticator Assurance Level (AAL) is the measure of the strength of an authentication mechanism. - In Supabase, having an AAL of `aal1` refers to having the 1st factor of authentication such as an email and password or OAuth sign-in while `aal2` refers to the 2nd factor of authentication such as a time-based, one-time-password (TOTP). - If the user has a verified factor, the `next` field will return `AuthenticatorAssuranceLevel.AAL2`, else, it will return `AuthenticatorAssuranceLevel.AAL1`. examples: - id: get-aal name: Get the AAL details of the current session isSpotlight: true code: | ```kotlin val (current, next) = supabase.auth.mfa.getAuthenticatorAssuranceLevel() ``` - id: aal-enabled name: Check whether the user has at least one verified factor isSpotlight: true code: | ```kotlin val (enabled, _) = supabase.auth.mfa.status //flow variant, automatically emitting new values on session changes val statusFlow = supabase.auth.mfa.statusFlow ``` - id: aal-enabled-for-current-session name: Check whether the user is signed in using AAL2 isSpotlight: true code: | ```kotlin val (_, active) = supabase.auth.mfa.status //flow variant, automatically emitting new values on session changes val statusFlow = supabase.auth.mfa.statusFlow ``` - id: get-claims title: 'getClaims()' description: | Extracts the JWT claims from the access token by first verifying the JWT against the server's JSON Web Key Set (JWKS) endpoint. notes: | - Prefer this method over `retrieveUser()` as JWKS responses are cached, resulting in significantly faster responses. - If the project is not using an asymmetric JWT signing key (like ECC or RSA), it sends a request to the Auth server (similar to `retrieveUser()`) to verify the JWT. - Returns a `ClaimsResponse` containing `claims` (a `JwtPayload` with typed accessors for standard JWT fields), `header`, and `signature`. - Standard claims available on `JwtPayload`: `iss`, `sub`, `aud`, `exp`, `iat`, `role`, `aal`, `sessionId`, `email`, `phone`, `isAnonymous`, `amr`, `appMetadata`, `userMetadata`. - Use `claims.getClaim(key)` or `claims.getClaimOrNull(key)` for custom claims. params: - name: jwt isOptional: true type: String? description: An optional specific JWT to verify. If not provided, uses the current session's access token. - name: options isOptional: true type: ClaimsRequestBuilder.() -> Unit description: Options to customize the behavior, such as allowing expired tokens. subContent: - name: allowExpired isOptional: true type: Boolean description: Whether to allow expired JWTs. Defaults to `false`. examples: - id: get-claims-basic name: Get claims from current session isSpotlight: true code: | ```kotlin val response = supabase.auth.getClaims() val email = response.claims.email val role = response.claims.role val aal = response.claims.aal ``` - id: get-claims-custom name: Get a custom claim code: | ```kotlin val response = supabase.auth.getClaims() val customValue = response.claims.getClaimOrNull("my_custom_claim") ``` - id: get-claims-specific-jwt name: Verify a specific JWT code: | ```kotlin val response = supabase.auth.getClaims(jwt = "your-jwt-token") ``` - id: admin-api title: 'Overview' notes: | - Any method under the `supabase.auth.admin` namespace requires a `secret` key. - These methods are considered admin methods and should be called on a trusted server. Never expose your `secret` key in the browser. examples: - id: create-auth-admin-client name: Create server-side auth client isSpotlight: true code: | ```kotlin val supabase = createSupabaseClient( supabaseUrl = "https://id.supabase.co", supabaseKey = "supabaseKey" ) { install(Auth) { minimalConfig() //disables session saving and auto-refreshing } // install other plugins (these will use the secret key) } supabase.auth.importAuthToken("your-secret-key") // Access auth admin api val adminAuthClient = supabase.auth.admin ``` - id: get-user-by-id title: 'getUserById()' $ref: '@supabase/gotrue-js.GoTrueAdminApi.getUserById' notes: | Fetches the user object from the database based on the user's id. - The `retrieveUserById()` method requires the user's id which maps to the `auth.users.id` column. params: - name: uid isOptional: false type: String description: The id of the user you want to retrieve. examples: - id: fetch-the-user-object-using-the-access-token-jwt name: Fetch the user object using the access_token jwt isSpotlight: true code: | ```kotlin val user = supabase.auth.admin.retrieveUserById(uid = "f2a0b0a0-6b1a-4b7a-8f1a-4b7a6b1a8f1a") ``` - id: list-users title: 'listUsers()' $ref: '@supabase/gotrue-js.GoTrueAdminApi.listUsers' notes: | Retrieves a list of users. - Defaults to return 50 users per page. params: - name: page isOptional: true type: Int description: The page number to retrieve. - name: perPage isOptional: true type: Int description: The number of users to retrieve per page. examples: - id: get-a-full-list-of-users name: Get a page of users isSpotlight: true code: | ```kotlin val users = supabase.auth.admin.retrieveUsers() ``` - id: get-paginated-list-of-users name: Paginated list of users isSpotlight: false code: | ```kotlin val users = supabase.auth.admin.retrieveUsers( page = 1, perPage = 100 ) ``` - id: create-user title: 'createUser()' $ref: '@supabase/gotrue-js.GoTrueAdminApi.createUser' notes: | Creates a new user. - To confirm the user's email address or phone number, set `autoConfirm` to true. Both arguments default to false. params: - name: builder isOptional: false type: AdminUserBuilder.Email.() -> Unit or AdminUserBuilder.Phone.() -> Unit description: The builder to create a new user. subContent: - name: email/phone isOptional: true type: String description: The new user's email or phone. - name: password isOptional: false type: String description: The user's password. - name: autoConfirm isOptional: true type: Boolean description: Whether to auto-confirm the user's email or phone number. - name: userMetadata isOptional: true type: JsonObject? description: Custom user metadata. - name: appMetadata isOptional: true type: JsonObject? description: Custom app metadata. examples: - id: create-a-new-user-with-email-custom-user-metadata name: Create user with email isSpotlight: true code: | ```kotlin val userWithEmail = supabase.auth.admin.createUserWithEmail { email = "example@email.com" password = "secretpassword" userMetadata { put("name", "John") } } ``` - id: create-a-new-user-with-phone-custom-user-metadata name: Create user with phone isSpotlight: true code: | ```kotlin val userWithPhone = supabase.auth.admin.createUserWithPhone { phone = "+49123456789" password = "secretpassword" userMetadata { put("name", "John") } } ``` - id: auto-confirm-the-users-email name: Auto-confirm the user's email code: | ```kotlin val userWithEmail = supabase.auth.admin.createUserWithEmail { email = "example@email.com" password = "secretpassword" autoConfirm = true } ``` - id: auto-confirm-the-users-phone-number name: Auto-confirm the user's phone number code: | ```kotlin val userWithPhone = supabase.auth.admin.createUserWithPhone { phone = "+49123456789" password = "secretpassword" autoConfirm = true } ``` - id: delete-user title: 'deleteUser()' $ref: '@supabase/gotrue-js.GoTrueAdminApi.deleteUser' notes: | Deletes a user from the database. - The `deleteUser()` method requires the user's ID, which maps to the `auth.users.id` column. params: - name: uid isOptional: false type: String description: The id of the user you want to delete. examples: - id: removes-a-user name: Removes a user isSpotlight: true code: | ```kotlin supabase.auth.admin.deleteUser(uid = "uid") ``` - id: invite-user-by-email title: 'inviteUserByEmail()' $ref: '@supabase/gotrue-js.GoTrueAdminApi.inviteUserByEmail' notes: | Sends an invite link to the user's email address. params: - name: email isOptional: false type: String description: The email to send the invite to. - name: redirectTo isOptional: true type: String description: The redirect url to use. If you don't specify this, the platform specific will be used, like deeplinks on android. - name: data isOptional: true type: JsonObject description: Custom data to create the user with. examples: - id: invite-a-user name: Invite a user isSpotlight: true code: | ```kotlin supabase.auth.admin.inviteUserByEmail( email = "example@email.com", //optional: redirectTo = "https://example.com/redirect", data = buildJsonObject { put("custom", "value") } ) ``` - id: generate-link title: 'generateLink()' $ref: '@supabase/gotrue-js.GoTrueAdminApi.generateLink' notes: | Generates email links and OTPs. This will not send links or OTPs to the end user. This function is for custom admin functionality. params: - name: type isOptional: false type: LinkType description: The type of link to generate, e.g. `LinkType.Signup`. - name: redirectTo isOptional: true type: String description: The redirect url to use. If you don't specify this, the platform specific will be used, like deeplinks on android. - name: config isOptional: true type: C.() -> Unit description: The builder to create a new link. examples: - id: generate-a-signup-link name: Generate a signup link isSpotlight: true code: | ```kotlin val (url, user) = supabase.auth.admin.generateLinkFor(LinkType.Signup) { email = "example@email.com" password = "secretpassword" } ``` - id: generate-an-invite-link name: Generate an invite link isSpotlight: false code: | ```kotlin val (url, user) = supabase.auth.admin.generateLinkFor(LinkType.Invite) { email = "example@email.com" } ``` - id: generate-a-magic-link name: Generate a magic link isSpotlight: false code: | ```kotlin val (url, user) = supabase.auth.admin.generateLinkFor(LinkType.MagicLink) { email = "example@email.com" } ``` - id: generate-a-recovery-link name: Generate a recovery link isSpotlight: false code: | ```kotlin val (url, user) = supabase.auth.admin.generateLinkFor(LinkType.Recovery) { email = "example@email.com" } ``` - id: generate-links-to-change-current-email-address name: Generate links to change current email address isSpotlight: false code: | ```kotlin // generate an email change link to be sent to the current email address val (url, user) = supabase.auth.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.auth.admin.generateLinkFor(LinkType.EmailChangeNew) { email = "example@email.com" newEmail = "newEmail@email.com" } ``` - id: update-user-by-id title: 'updateUserById()' $ref: '@supabase/gotrue-js.GoTrueAdminApi.updateUserById' notes: | Updates the user data. params: - name: uid isOptional: false type: String description: The id of the user you want to update. - name: builder isOptional: false type: AdminUserUpdateBuilder.() -> Unit description: The builder to update the user. subContent: - name: email isOptional: true type: String description: The new email. - name: phone isOptional: true type: String description: The new phone number. - name: password isOptional: true type: String description: The new password. - name: userMetadata isOptional: true type: JsonObject? description: Custom user metadata. - name: appMetadata isOptional: true type: JsonObject? description: Custom app metadata. - name: emailConfirm isOptional: true type: Boolean description: Whether to confirm the user's email. - name: phoneConfirm isOptional: true type: Boolean description: Whether to confirm the user's phone number. - name: banDuration isOptional: true type: String description: The format for the ban duration follows a strict sequence of decimal numbers with a unit suffix. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". - name: role isOptional: true type: String description: The `role` claim set in the user's access token JWT. When a user signs up, this role is set to `authenticated` by default. You should only modify the `role` if you need to provision several levels of admin access that have different permissions on individual columns in your database. examples: - id: updates-a-users-email name: Updates a user's email isSpotlight: false code: | ```kotlin supabase.auth.admin.updateUserById(uid = "id") { email = "example@email.com" } ``` - id: updates-a-users-password name: Updates a user's password isSpotlight: false code: | ```js supabase.auth.admin.updateUserById(uid = "id") { password = "password" } ``` - id: updates-a-users-metadata name: Updates a user's metadata isSpotlight: true code: | ```kotlin supabase.auth.admin.updateUserById(uid = "id") { userMetadata = buildJsonObject { put("key", "value") } } ``` - id: updates-a-users-app-metadata name: Updates a user's app_metadata isSpotlight: false code: | ```kotlin supabase.auth.admin.updateUserById(uid = "id") { appMetadata = buildJsonObject { put("key", "value") } } ``` - id: confirms-a-users-email-address name: Confirms a user's email address isSpotlight: false code: | ```kotlin supabase.auth.admin.updateUserById(uid = "id") { emailConfirm = true } ``` - id: confirms-a-users-phone-number name: Confirms a user's phone number isSpotlight: false code: | ```kotlin supabase.auth.admin.updateUserById(uid = "id") { phoneConfirm = true } ``` - id: mfa-list-factors title: 'mfa.listFactors()' notes: | Lists all factors associated to a user. params: - name: uid isOptional: false type: String description: The id of the user you want to list factors for. examples: - id: list-factors name: List all factors for a user isSpotlight: true code: | ```kotlin const factors = supabase.auth.admin.retrieveFactors(uid = "id") ``` - id: mfa-delete-factor title: 'mfa.deleteFactor()' notes: | Deletes a factor on a user. This will log the user out of all active sessions if the deleted factor was verified. params: - name: uid isOptional: false type: String description: The id of the user you want to delete a factor for. - name: factorId isOptional: false type: String description: The id of the factor you want to delete. examples: - id: delete-factor name: Delete a factor for a user isSpotlight: true code: | ```kotlin supabase.auth.admin.deleteFactor(uid = "id", factorId = "factor_id") ``` - id: oauth-admin-api title: OAuth Admin API notes: | The OAuth Admin API allows you to manage OAuth clients programmatically. Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. These functions should only be called on a server. Never expose your `secret key` in the browser. - id: admin-oauth-list-clients title: 'admin.oauth.listClients()' notes: | Lists all OAuth 2.1 clients. Requires a `secret key`. params: - name: page isOptional: true type: Int? description: The page number for pagination. - name: perPage isOptional: true type: Int? description: The number of results per page. examples: - id: list-oauth-clients name: List all OAuth clients isSpotlight: true code: | ```kotlin val clients = supabase.auth.admin.oauth.listClients() ``` - id: admin-oauth-create-client title: 'admin.oauth.createClient()' notes: | Creates a new OAuth 2.1 client. Requires a `secret key`. examples: - id: create-oauth-client name: Create an OAuth client isSpotlight: true code: | ```kotlin val client = supabase.auth.admin.oauth.createClient { name = "My App" redirectUris = listOf("https://example.com/callback") } ``` - id: admin-oauth-get-client title: 'admin.oauth.getClient()' notes: | Retrieves an OAuth 2.1 client by ID. Requires a `secret key`. params: - name: clientId isOptional: false type: String description: The ID of the OAuth client to retrieve. examples: - id: get-oauth-client name: Get an OAuth client isSpotlight: true code: | ```kotlin val client = supabase.auth.admin.oauth.getClient(clientId = "client_id") ``` - id: admin-oauth-update-client title: 'admin.oauth.updateClient()' notes: | Updates an existing OAuth 2.1 client. Requires a `secret key`. params: - name: clientId isOptional: false type: String description: The ID of the OAuth client to update. examples: - id: update-oauth-client name: Update an OAuth client isSpotlight: true code: | ```kotlin val client = supabase.auth.admin.oauth.updateClient(clientId = "client_id") { name = "Updated App Name" } ``` - id: admin-oauth-delete-client title: 'admin.oauth.deleteClient()' notes: | Deletes an OAuth 2.1 client. Requires a `secret key`. params: - name: clientId isOptional: false type: String description: The ID of the OAuth client to delete. examples: - id: delete-oauth-client name: Delete an OAuth client isSpotlight: true code: | ```kotlin supabase.auth.admin.oauth.deleteClient(clientId = "client_id") ``` - id: admin-oauth-regenerate-client-secret title: 'admin.oauth.regenerateClientSecret()' notes: | Regenerates the client secret for an OAuth 2.1 client. Requires a `secret key`. params: - name: clientId isOptional: false type: String description: The ID of the OAuth client whose secret should be regenerated. examples: - id: regenerate-client-secret name: Regenerate client secret isSpotlight: true code: | ```kotlin val client = supabase.auth.admin.oauth.regenerateClientSecret(clientId = "client_id") ``` - id: invoke title: 'invoke()' description: | 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. notes: | - Requires an Authorization header. params: - name: function isOptional: false type: String description: The name of the function to invoke. - name: body isOptional: true type: T description: The body to send with the request. T can be any serializable type. - name: region isOptional: true type: FunctionRegion description: The region where the function is invoked. Defaults to `Functions.Config#defaultRegion`. - name: headers isOptional: true type: Headers description: The headers to send with the request. examples: - id: basic-invocation name: Basic invocation isSpotlight: true code: | ```kotlin val response = supabase.functions.invoke("function_name") // Decode the response body to a serializable class val data = response.body() ``` - id: basic-invocation-with-body name: Basic invocation with body isSpotlight: true code: | ```kotlin supabase.functions.invoke( function = "function_name", body = buildJsonObject { put("foo", "bar") }, headers = Headers.build { append(HttpHeaders.ContentType, "application/json") } ) ``` description: | The return type of the invoking methods is an `HttpResponse`. You can access the response body via `response.body()`, where `T` can be any serializable type. - id: invoke-with-streaming name: Invoke with streaming (SSE) description: | You can invoke edge functions that return Server-Sent Events (SSE) and consume them as a Kotlin Flow. isSpotlight: true code: | ```kotlin val function = supabase.functions.buildEdgeFunction("streaming-function") // Collect SSE events as a Flow function.collectAsFlow( body = buildJsonObject { put("prompt", "Hello!") } ).collect { event -> println("Event: ${event.event}") println("Data: ${event.data}") // Decode typed data val response = event.decodeAs() } ``` - id: reuse-function name: Reuse function by saving it to a variable isSpotlight: true code: | ```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 } ``` - id: stream title: 'stream()' description: | Return real-time data from your table as a [Flow](https://kotlinlang.org/docs/flow.html). - Realtime is disabled by default for new tables. You can turn it on by [managing replication](/docs/guides/realtime/postgres-changes#replication-setup). - `selectAsFlow` and `selectSingleValueAsFlow` will emit the initial data and then listen for changes. - Takes in a `filter` parameter to filter the data and a `primaryKey` parameter to cache the data by the primary key. - This method requires both the `Realtime` and `Postgrest` plugins to be installed. - The type parameter `T` must be a [serializable class](/docs/reference/kotlin/installing#serialization). - If you want more control over the realtime updates, you can use the `Realtime` plugin directly. params: - name: primaryKey isOptional: false type: KProperty1 or PrimaryKey description: The primary key to cache the data by. Can be a property reference or a custom primary key. - name: channelName isOptional: true type: String description: The name of the channel to use for the realtime updates. If null, a channel name following the format "schema:table:id" will be used - name: filter isOptional: true type: PostgrestFilterBuilder.() -> Unit or FilterOperation description: The filter to apply to the data. examples: - id: select-as-flow name: Listen for changes in multiple rows isSpotlight: true code: | ```kotlin val flow: Flow> = supabase.from("countries").selectAsFlow(Country::id) flow.collect { for (country in it) { println(country.name) } } ``` - id: select-as-flow-filter name: Listen for changes in multiple rows with a filter isSpotlight: true code: | ```kotlin val flow: Flow> = supabase.from("countries").selectAsFlow( Country::id, filter = FilterOperation("name", FilterOperator.ILIKE, "a%") ) flow.collect { for (country in it) { println(country.name) } } ``` - id: select-single-value-as-flow name: Listen for changes in a single row isSpotlight: true code: | ```kotlin val flow: Flow = supabase.from("countries").selectSingleValueAsFlow(Country::id) { //You can use the same filter methods as in the `select` method, but the result is limited to a single row Country::id eq 1 //or eq("id", 1) } flow.collect { println("My country is $it") } ``` description: | The flow will end if the row is deleted. - id: subscribe description: | Subscribe to realtime changes in your database. title: 'on().subscribe()' notes: | - Realtime is disabled by default for new Projects for better database performance and security. You can turn it on by [managing replication](/docs/guides/api). - If you want to receive the "previous" data for updates and deletes, you will need to set `REPLICA IDENTITY` to `FULL`, like this: `ALTER TABLE your_table REPLICA IDENTITY FULL;` - When using a method with a generic type like `track`, `broadcast` or `broadcastFlow`, you have to provide a [serializable class](/docs/reference/kotlin/installing#serialization) as the type parameter. - Presence, Broadcast and Database updates are sent through a [Flow](https://kotlinlang.org/docs/flow.html) examples: - id: liste-to-broadcasts name: Listen to broadcasts code: | ```kotlin @Serializable data class Message(val content: String, val sender: String) val channel = supabase.channel("channelId") { // optional config } val broadcastFlow = channel.broadcastFlow(event = "message") // Collect the flow broadcastFlow.onEach { // it: Message println(it) }.launchIn(coroutineScope) // launch a new coroutine to collect the flow channel.subscribe(blockUntilSubscribed = true) ``` - id: listen-to-presence-updates name: Listen to presence updates code: | ```kotlin @Serializable data class PresenceState(val username: String) val channel = supabase.channel("channelId") { //optional config } //if you want more control and want to receive the raw data, use the `presenceChangeFlow` method val presenceFlow = channel.presenceDataFlow() //Collect the flow presenceFlow.onEach { for (presence in it) { println(presence.username) } }.launchIn(coroutineScope) // launch a new coroutine to collect the flow channel.subscribe(blockUntilSubscribed = true) //send your own state channel.track(PresenceState(username = "John")) description: | You have two methods you can use to listen for presence updates: - `presenceDataFlow` takes care of caching presences based on their id and automatically emits the updated list. - `presenceChangeFlow` emits the raw data received by realtime. Can be used if more control is required. - id: listen-to-all-database-changes name: Listen to all database changes code: | ```kotlin val channel = supabase.channel("channelId") { //optional config } val changeFlow = channel.postgresChangeFlow(schema = "public") //Collect the flow changeFlow.onEach { 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}") } }.launchIn(coroutineScope) // launch a new coroutine to collect the flow channel.subscribe() ``` - id: listen-to-a-specific-table name: Listen to a specific table code: | ```kotlin val channel = supabase.channel("channelId") { //optional config } //This flow will automatically emit the initial data of all messages (which can be restricted by specifying a filter) and then listens for updates. //The data is cached automatically by the primary key you specify val users: Flow> = channel.postgresListDataFlow(schema = "public", table = "users", primaryKey = User::id) //If you want more control and want to receive the raw data use the `postgresChangeFlow` method: val changeFlow = channel.postgresChangeFlow(schema = "public") { table = "users" } //Collect the flow changeFlow.onEach { 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}") } }.launchIn(coroutineScope) // launch a new coroutine to collect the flow channel.subscribe() ``` description: | You have two methods you can use if you want to listen for database updates on a specific table: - `postgresListDataFlow` fetches the initial data of all database entries matching your filter (or all entries if you didn't specify one) and then caches the data based on their primary key. Inserts, Updates and Deletes are handled automatically and you will get the updated list through the flow. - `postgresChangeFlow` emits the raw data received by realtime. Events can be filtered by specifying a `PostgresAction` type parameter (see examples), or all by specifying only `PostgresAction`. Can be used if more control is required. - id: listen-to-inserts name: Listen to inserts code: | ```kotlin val channel = supabase.channel("channelId") { //optional config } val changeFlow = channel.postgresChangeFlow(schema = "public") { table = "users" } //Collect the flow changeFlow.onEach { println(it.record) }.launchIn(coroutineScope) // launch a new coroutine to collect the flow channel.subscribe() ``` - id: listen-to-updates name: Listen to updates description: | By default, Supabase will send only the updated record. If you want to receive the previous values as well you can enable full replication for the table you are listening too: ```sql alter table "your_table" replica identity full; ``` code: | ```kotlin val channel = supabase.channel("channelId") { //optional config } val changeFlow = channel.postgresChangeFlow(schema = "public") { table = "users" } //Collect the flow changeFlow.onEach { println(it.record) println(it.oldRecord) }.launchIn(coroutineScope) // launch a new coroutine to collect the flow channel.subscribe() ``` - id: listen-to-deletes name: Listen to deletes description: | By default, Supabase does not send deleted records. If you want to receive the deleted record you can enable full replication for the table you are listening too: ```sql alter table "your_table" replica identity full; ``` code: | ```kotlin val channel = supabase.channel("channelId") { //optional config } val changeFlow = channel.postgresChangeFlow(schema = "public") { table = "users" } //Collect the flow changeFlow.onEach { println(it.oldRecord) }.launchIn(coroutineScope) // launch a new coroutine to collect the flow channel.subscribe() ``` - id: listening-to-row-level-changes name: Listen to row level changes code: | ```kotlin val channel = supabase.channel("channelId") { //optional config } //This flow will automatically emit the user's initial data and then emits new values on update. The flow ends on deletion val user: Flow = channel.postgresSingleDataFlow(schema = "public", table = "users", primaryKey = User::id) { //This is the same filter as used in postgrest, so you could use complex queries, but only one entry is fetched eq("id", 1) } //If you want more control, use the `postgresChangeFlow` method which works the same as the other examples val changeFlow = channel.postgresChangeFlow(schema = "public") { table = "users" filter("id", FilterOperator.EQ, 1) } //Collect the flow changeFlow.onEach { println(it.oldRecord) }.launchIn(coroutineScope) // launch a new coroutine to collect the flow channel.subscribe() ``` description: | You have two methods you can use if you want to listen for updates on a specific database row: - `postgresSingleDataFlow` fetches the initial data matching the filter and then emits updates based on realtime events. - `postgresChangeFlow` emits the raw data received by realtime. To filter the realtime queries, use the `filter` method. - id: broadcast-message title: broadcastMessage() description: | Broadcast a message to all connected clients to a channel. notes: | - When using REST you don't need to subscribe to the channel $ref: '@supabase/realtime-js.RealtimeChannel.send' examples: - id: send-a-message name: Send a message via websocket isSpotlight: true code: | ```kotlin val channel = supabase.channel("room1") channel.subscribe(blockUntilSubscribed = true) channel.broadcast("cursor-pos", message = buildJsonObject { put("x", 10) put("y", 20) }) ``` response: | ``` ok | timed out | error ``` - id: send-a-message-via-rest name: Send a message via REST isSpotlight: true code: | ```kotlin val channel = supabase.channel("room1") channel.broadcast("cursor-pos", message = buildJsonObject { put("x", 10) put("y", 20) }) ``` - id: remove-channel description: | Unsubscribes and removes Realtime channel from Realtime client. title: 'removeChannel()' notes: | - Removing a channel is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. - Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed. - If you removed all channels, the client automatically disconnects from the Realtime websocket. This can be disabled in the Realtime config by setting `disconnectOnNoSubscriptions` to false. examples: - id: removes-a-channel name: Remove a channel isSpotlight: true code: | ```kotlin val channel = supabase.channel("channelId") { //optional config } //... supabase.realtime.removeChannel(channel) ``` - id: unsubscribe-channel name: Unsubscribe from a channel isSpotlight: true code: | ```kotlin val channel = supabase.channel("channelId") { //optional config } //... channel.unsubscribe() ``` - id: remove-all-channels title: removeAllChannels() $ref: '@supabase/supabase-js.index.SupabaseClient.removeAllChannels' notes: | Unsubscribes and removes all Realtime channels from Realtime client. - Removing channels is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed. - If you removed all channels, the client automatically disconnects from the Realtime websocket. This can be disabled in the Realtime config by setting `disconnectOnNoSubscriptions` to false. examples: - id: remove-all-channels name: Remove all channels isSpotlight: true code: | ```kotlin supabase.realtime.removeAllChannels() ``` - id: get-channels title: getChannels() $ref: '@supabase/supabase-js.index.SupabaseClient.getChannels' notes: | Returns all Realtime channels. examples: - id: get-all-channels name: Get all channels isSpotlight: true code: | ```kotlin val channels = supabase.realtime.subscriptions.entries ``` - id: file-buckets title: 'Overview' notes: | This section contains methods for working with File Buckets. - id: list-buckets title: listBuckets() $ref: '@supabase/storage-js.packages/StorageBucketApi.default.listBuckets' notes: | - RLS policy permissions required: - `buckets` table permissions: `select` - `objects` table permissions: none - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works examples: - id: list-buckets name: List buckets isSpotlight: true code: | ```kotlin val buckets = supabase.storage.retrieveBuckets() ``` - id: get-bucket title: getBucket() $ref: '@supabase/storage-js.packages/StorageBucketApi.default.getBucket' notes: | - RLS policy permissions required: - `buckets` table permissions: `select` - `objects` table permissions: none - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works examples: - id: get-bucket name: Get bucket isSpotlight: true code: | ```kotlin val bucket = supabase.storage.retrieveBucketById(bucketId = "avatars") ``` - id: create-bucket title: createBucket() $ref: '@supabase/storage-js.packages/StorageBucketApi.default.createBucket' notes: | - RLS policy permissions required: - `buckets` table permissions: `insert` - `objects` table permissions: none - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works params: - name: id isOptional: false type: String description: The id of the bucket you want to create. - name: builder isOptional: true type: BucketBuilder.() -> Unit description: The builder to create a new bucket. subContent: - name: public isOptional: true type: Boolean description: Whether the bucket is public or not. - name: fileSizeLimit isOptional: true type: FileSizeLimit description: The maximum file size. examples: - id: create-bucket name: Create bucket isSpotlight: true code: | ```kotlin supabase.storage.createBucket(id = "icons") { public = true fileSizeLimit = 5.megabytes } ``` - id: update-bucket title: updateBucket() $ref: '@supabase/storage-js.packages/StorageBucketApi.default.updateBucket' notes: | - RLS policy permissions required: - `buckets` table permissions: `select` and `update` - `objects` table permissions: none - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works params: - name: id isOptional: false type: String description: The id of the bucket you want to create. - name: builder isOptional: true type: BucketBuilder.() -> Unit description: The builder to create a new bucket. subContent: - name: public isOptional: true type: Boolean description: Whether the bucket is public or not. - name: fileSizeLimit isOptional: true type: FileSizeLimit description: The maximum file size. examples: - id: update-bucket name: Update bucket isSpotlight: true code: | ```kotlin supabase.storage.updateBucket("cards") { public = false fileSizeLimit = 20.megabytes allowedMimeTypes(ContentType.Image.PNG, ContentType.Image.JPEG) } ``` - id: empty-bucket title: emptyBucket() $ref: '@supabase/storage-js.packages/StorageBucketApi.default.emptyBucket' notes: | - RLS policy permissions required: - `buckets` table permissions: `select` - `objects` table permissions: `select` and `delete` - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works params: - name: bucketId isOptional: false type: String description: The id of the bucket you want to empty. examples: - id: empty-bucket name: Empty bucket isSpotlight: true code: | ```kotlin supabase.storage.emptyBucket(bucketId = "icons") ``` - id: delete-bucket title: deleteBucket() $ref: '@supabase/storage-js.packages/StorageBucketApi.default.deleteBucket' notes: | - RLS policy permissions required: - `buckets` table permissions: `select` and `delete` - `objects` table permissions: none - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works params: - name: bucketId isOptional: false type: String description: The id of the bucket you want to delete. examples: - id: delete-bucket name: Delete bucket isSpotlight: true code: | ```kotlin supabase.storage.deleteBucket(bucketId = "icons") ``` - id: analytics-buckets title: 'Overview' notes: | This section contains methods for working with Analytics Buckets. - Analytics buckets are accessed via the `supabase.storage.analytics` namespace. - Analytics buckets are used for storing and querying analytics data. - id: storageanalytics-createbucket title: 'analytics.createBucket()' description: | Creates a new Analytics bucket. notes: | - This is an alpha feature and may change in the future. - Analytics buckets are used for storing and querying analytics data. params: - name: name isOptional: false type: String description: The name of the analytics bucket to create. examples: - id: create-analytics-bucket name: Create analytics bucket code: | ```kotlin val bucket = supabase.storage.analytics.createBucket("analytics-bucket") ``` response: | ```json { "name": "analytics-bucket", "type": "ANALYTICS", "created_at": "2024-12-03T18:00:00.000Z", "updated_at": "2024-12-03T18:00:00.000Z" } ``` - id: storageanalytics-listbuckets title: 'analytics.listBuckets()' description: | Lists all Analytics buckets with optional filtering and sorting. notes: | - This is an alpha feature and may change in the future. params: - name: filter isOptional: true type: StorageListFilter.Buckets.() -> Unit description: Filter block for the operation. subContent: - name: limit isOptional: true type: Int description: Maximum number of buckets to return. - name: offset isOptional: true type: Int description: Number of buckets to skip. - name: sortColumn isOptional: true type: BucketSortColumn description: 'Column to sort by. Options: `BucketSortColumn.ID`, `BucketSortColumn.NAME`, `BucketSortColumn.CREATED_AT`, `BucketSortColumn.UPDATED_AT`.' - name: sortOrder isOptional: true type: SortOrder description: 'Sort order. Options: `SortOrder.ASC`, `SortOrder.DESC`.' - name: search isOptional: true type: String description: Search term to filter buckets by name. examples: - id: list-analytics-buckets name: List analytics buckets code: | ```kotlin val buckets = supabase.storage.analytics.listBuckets { limit = 50 offset = 2 search = "myString" sortBy(BucketSortColumn.ID, SortOrder.ASC) } ``` response: | ```json [ { "name": "analytics-bucket", "type": "ANALYTICS", "created_at": "2024-12-03T18:00:00.000Z", "updated_at": "2024-12-03T18:00:00.000Z" } ] ``` - id: storageanalytics-deletebucket title: 'analytics.deleteBucket()' description: | Deletes an Analytics bucket. notes: | - This is an alpha feature and may change in the future. params: - name: name isOptional: false type: String description: The name of the analytics bucket to delete. examples: - id: delete-analytics-bucket name: Delete analytics bucket code: | ```kotlin val responseMessage = supabase.storage.analytics.deleteBucket("analytics-bucket") ``` response: | ```json { "message": "Successfully deleted" } ``` - id: vector-buckets title: 'Overview' notes: | This section contains methods for working with Vector Buckets. - id: storagevectors-create-bucket title: 'vectors.createBucket()' description: | Creates a new Vector bucket. notes: | - This is an alpha feature and may change in the future. - Vector buckets are used for storing and querying vector embeddings. params: - name: name isOptional: false type: String description: The name of the vector bucket to create. examples: - id: create-vector-bucket name: Create vector bucket code: | ```kotlin supabase.storage.vectors.createBucket("vectors-bucket") ``` - id: storagevectors-get-bucket title: 'vectors.getBucket()' description: | Retrieves details of a Vector bucket. notes: | - This is an alpha feature and may change in the future. params: - name: name isOptional: false type: String description: The name of the vector bucket to retrieve. examples: - id: get-vector-bucket name: Get vector bucket code: | ```kotlin val bucket = supabase.storage.vectors.getBucket("vectors-bucket") ``` response: | ```json { "vectorBucket": { "vectorBucketName": "vectors-bucket", "creationTime": "2024-12-03T18:00:00.000Z" } } ``` - id: storagevectors-list-buckets title: 'vectors.listBuckets()' description: | Lists all Vector buckets with optional pagination. notes: | - This is an alpha feature and may change in the future. params: - name: filter isOptional: true type: VectorBucketFilter.() -> Unit description: Optional filter block for the operation. subContent: - name: prefix isOptional: true type: String description: Filter buckets by name prefix. - name: maxResults isOptional: true type: Int description: Maximum number of buckets to return. - name: nextToken isOptional: true type: String description: Token for pagination. examples: - id: list-vector-buckets name: List vector buckets code: | ```kotlin val response = supabase.storage.vectors.listBuckets { prefix = "myPrefix" maxResults = 20 nextToken = "nextToken" } println(response.vectorBuckets) ``` response: | ```json { "vectorBuckets": [ { "vectorBucketName": "vectors-bucket" } ], "nextToken": null } ``` - id: storagevectors-delete-bucket title: 'vectors.deleteBucket()' description: | Deletes a Vector bucket. notes: | - This is an alpha feature and may change in the future. params: - name: name isOptional: false type: String description: The name of the vector bucket to delete. examples: - id: delete-vector-bucket name: Delete vector bucket code: | ```kotlin supabase.storage.vectors.deleteBucket("vectors-bucket") ``` - id: vectorbucket-createindex title: 'vectors.from().createIndex()' description: | Creates a new vector index in a vector bucket. notes: | - This is an alpha feature and may change in the future. params: - name: options isOptional: false type: CreateIndexOptions.() -> Unit description: Configuration block for the operation. subContent: - name: indexName isOptional: false type: String description: The name of the index to create. - name: dimension isOptional: false type: Int description: The dimension of the vectors in this index. - name: distanceMetric isOptional: false type: DistanceMetric description: 'The distance metric to use. Options: `DistanceMetric.COSINE`, `DistanceMetric.EUCLIDEAN`.' - name: dataType isOptional: false type: VectorDataType description: The data type of the vectors. - name: metadataConfiguration isOptional: true type: MetadataConfiguration description: Optional metadata configuration for the index. examples: - id: create-vector-index name: Create vector index code: | ```kotlin supabase.storage.vectors .from("vectors-bucket") .createIndex { indexName = "my-index" dimension = 128 distanceMetric = DistanceMetric.COSINE dataType = VectorDataType.FLOAT32 } ``` - id: vectorbucket-getindex title: 'vectors.from().getIndex()' description: | Retrieves details of a vector index. notes: | - This is an alpha feature and may change in the future. params: - name: indexName isOptional: false type: String description: The name of the index to retrieve. examples: - id: get-vector-index name: Get vector index code: | ```kotlin val index = supabase.storage.vectors .from("vectors-bucket") .getIndex("index-name") ``` - id: vectorbucket-listindexes title: 'vectors.from().listIndexes()' description: | Lists all indexes in a vector bucket. notes: | - This is an alpha feature and may change in the future. params: - name: options isOptional: false type: ListIndexesOptions.() -> Unit description: Configuration block for the operation. subContent: - name: nextToken isOptional: true type: String description: Token for pagination. - name: maxResults isOptional: true type: Int description: Maximum number of indexes to return. - name: prefix isOptional: true type: String description: Filter indexes by name prefix. examples: - id: list-vector-indexes name: List vector indexes code: | ```kotlin val response = supabase.storage.vectors .from("vectors-bucket") .listIndexes { maxResults = 20 prefix = "myPrefix" nextToken = "nextToken" } println(response.indexes) ``` - id: vectorbucket-deleteindex title: 'vectors.from().deleteIndex()' description: | Deletes a vector index. notes: | - This is an alpha feature and may change in the future. params: - name: indexName isOptional: false type: String description: The name of the index to delete. examples: - id: delete-vector-index name: Delete vector index code: | ```kotlin supabase.storage.vectors .from("vectors-bucket") .deleteIndex("index-name") ``` - id: vectorindex-putvectors title: 'vectors.from().index().putVectors()' description: | Inserts or updates vectors in an index. notes: | - This is an alpha feature and may change in the future. params: - name: vectors isOptional: false type: List description: List of vector objects to insert or update. examples: - id: put-vectors name: Put vectors code: | ```kotlin supabase.storage.vectors .from("vectors-bucket") .index("index-name") .putVectors(listOf( VectorObject("vector-1", VectorData(floatArrayOf(2.0f, 3.0f, 4.0f)), buildJsonObject { put("meta", true) }) )) ``` - id: vectorindex-getvectors title: 'vectors.from().index().getVectors()' description: | Retrieves vectors by their keys. notes: | - This is an alpha feature and may change in the future. params: - name: options isOptional: false type: GetVectorOptions.() -> Unit description: Configuration block for the operation. subContent: - name: keys isOptional: false type: List description: List of vector keys to retrieve. - name: returnData isOptional: true type: Boolean description: Whether to return vector data. Defaults to `true`. - name: returnMetadata isOptional: true type: Boolean description: Whether to return metadata. Defaults to `true`. examples: - id: get-vectors name: Get vectors code: | ```kotlin val vectors = supabase.storage.vectors .from("vectors-bucket") .index("index-name") .getVectors { keys.add("vector-1") } ``` - id: vectorindex-listvectors title: 'vectors.from().index().listVectors()' description: | Lists vectors in an index with optional pagination. notes: | - This is an alpha feature and may change in the future. params: - name: options isOptional: true type: ListVectorsOptions.() -> Unit description: Optional configuration block for the operation. If omitted, default pagination and response settings are used. subContent: - name: maxResults isOptional: true type: Int description: Maximum number of vectors to return. - name: nextToken isOptional: true type: String description: Token for pagination. - name: returnData isOptional: true type: Boolean description: Whether to return vector data. Defaults to `true`. - name: returnMetadata isOptional: true type: Boolean description: Whether to return metadata. Defaults to `true`. - name: segmentCount isOptional: true type: Int description: Number of segments for distributed queries. - name: segmentIndex isOptional: true type: Int description: Segment index for distributed queries. examples: - id: list-vectors name: List vectors code: | ```kotlin val response = supabase.storage.vectors .from("vectors-bucket") .index("index-name") .listVectors() println(response.vectors) ``` - id: vectorindex-queryvectors title: 'vectors.from().index().queryVectors()' description: | Queries vectors using a query vector to find similar vectors. notes: | - This is an alpha feature and may change in the future. params: - name: options isOptional: false type: QueryVectorsOptions.() -> Unit description: Configuration block for the query. subContent: - name: queryVector isOptional: false type: VectorData description: The query vector to search with. - name: topK isOptional: true type: Int description: Number of results to return. - name: filter isOptional: true type: VectorFilter description: Optional filter to apply to the query. - name: returnDistance isOptional: true type: Boolean description: Whether to return distance scores. Defaults to `true`. - name: returnMetadata isOptional: true type: Boolean description: Whether to return metadata. Defaults to `true`. examples: - id: query-vectors name: Query vectors code: | ```kotlin val response = supabase.storage.vectors .from("vectors-bucket") .index("index-name") .queryVectors { queryVector = VectorData(floatArrayOf(3.0f, 4.0f, 1.0f)) topK = 10 } println(response.vectors) ``` - id: vectorindex-deletevectors title: 'vectors.from().index().deleteVectors()' description: | Deletes vectors by their keys. notes: | - This is an alpha feature and may change in the future. - Keys batch size must be between 1 and 500. params: - name: bucketName isOptional: false type: String description: The name of the vector bucket. - name: indexName isOptional: false type: String description: The name of the index. - name: keys isOptional: false type: List description: List of vector keys to delete. Must contain between 1 and 500 keys. examples: - id: delete-vectors name: Delete vectors code: | ```kotlin supabase.storage.vectors .from("vectors-bucket") .index("index-name") .deleteVectors(listOf("vector-1", "vector-2")) ``` - id: storagefile-exists title: 'storage.from().exists()' description: | Checks the existence of a file. params: - name: path isOptional: false type: String description: The file path, including the file name. For example `folder/image.png`. examples: - id: check-file-existence name: Check file existence code: | ```kotlin val exists = supabase.storage.from("avatars").exists("folder/avatar1.png") ``` - id: storagefile-info title: 'storage.from().info()' description: | Retrieves the details of an existing file. Returns detailed file metadata including size, content type, and timestamps. params: - name: path isOptional: false type: String description: The file path, including the file name. For example `folder/image.png`. examples: - id: get-file-info name: Get file info code: | ```kotlin val file = supabase.storage.from("avatars").info("folder/avatar1.png") println(file.size) ``` - id: from-upload title: from.upload() $ref: '@supabase/storage-js.packages/StorageFileApi.default.upload' notes: | - RLS policy permissions required: - `buckets` table permissions: none - `objects` table permissions: `insert` - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works - Resumable uploads use a `Disk` cache by default to store the upload urls. You can customize that in the Auth config by changing the `resumable.cache` property. params: - name: path isOptional: false type: String description: The path of the file you want to upload. - name: data isOptional: false type: ByteArray description: The data of the file you want to upload. - name: options isOptional: true type: UploadOptionBuilder.() -> Unit description: Additional options for the upload. subContent: - name: upsert isOptional: true type: Boolean description: Whether to overwrite the file if it already exists. - name: contentType isOptional: true type: ContentType description: The content type of the file. Will be automatically inferred using the file extension if not provided. examples: - id: upload-file name: Upload file isSpotlight: true code: | ```kotlin val bucket = supabase.storage.from("avatars") bucket.upload("myIcon.png", byteArray) { upsert = false } //on JVM you can use java.io.File bucket.upload("myIcon.png", file) { upsert = false } ``` - id: upload-file-with-progress name: Upload file with progress isSpotlight: true code: | ```kotlin val bucket = supabase.storage.from("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") } } ``` - id: create-resumable-upload name: Create resumable upload isSpotlight: true code: | ```kotlin val bucket = supabase.storage.from("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" ) ``` - id: start-resumable-upload name: Start and resumable upload isSpotlight: true code: | ```kotlin upload.startOrResumeUploading() ``` - id: pause-resumable-upload name: Pause resumable upload code: | ```kotlin upload.pause() ``` - id: cancel-resumable-upload name: Cancel resumable upload code: | ```kotlin upload.cancel() ``` description: | This will also remove the upload url from the cache - id: listen-to-upload-state name: Listen to the resumable upload state code: | ```kotlin upload.stateFlow.collect { println("Progress: ${it.progress * 100}%") println("Paused: ${it.paused}") println("Is done: ${it.isDone}") } ``` - id: continue-previous-upload name: Continue previous uploads isSpotlight: true code: | ```kotlin val bucket = supabase.storage.from("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() } ``` - id: from-update title: from.update() $ref: '@supabase/storage-js.packages/StorageFileApi.default.update' notes: | - RLS policy permissions required: - `buckets` table permissions: none - `objects` table permissions: `update` and `select` - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works params: - name: path isOptional: false type: String description: The path of the file you want to upload. - name: data isOptional: false type: ByteArray description: The data of the file you want to upload. - name: options isOptional: true type: UploadOptionBuilder.() -> Unit description: Additional options for the upload. subContent: - name: upsert isOptional: true type: Boolean description: Whether to overwrite the file if it already exists. - name: contentType isOptional: true type: ContentType description: The content type of the file. Will be automatically inferred using the file extension if not provided. examples: - id: update-file name: Update file isSpotlight: true code: | ```kotlin val bucket = supabase.storage.from("avatars") bucket.update("myIcon.png", byteArray) { upsert = false } //on JVM you can use java.io.File bucket.update("myIcon.png", file) { upsert = false } ``` - id: from-move title: from.move() $ref: '@supabase/storage-js.packages/StorageFileApi.default.move' notes: | - RLS policy permissions required: - `buckets` table permissions: none - `objects` table permissions: `update` and `select` - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works params: - name: from isOptional: false type: String description: The path of the file you want to move. - name: to isOptional: false type: String description: The new path of the file. - name: destinationBucket isOptional: true type: String description: The destination bucket of the file. examples: - id: move-file name: Move file isSpotlight: true code: | ```kotlin val bucket = supabase.storage.from("avatars") bucket.move("icon1.png", "icon2.png") ``` - id: from-copy title: from.copy() $ref: '@supabase/storage-js.packages/StorageFileApi.default.copy' notes: | - RLS policy permissions required: - `buckets` table permissions: none - `objects` table permissions: `insert` and `select` - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works params: - name: from isOptional: false type: String description: The path of the file you want to copy. - name: to isOptional: false type: String description: The new path of the file. - name: destinationBucket isOptional: true type: String description: The destination bucket of the file. examples: - id: copy-file name: Copy file isSpotlight: true code: | ```kotlin supabase.storage.from("test").copy(from = "avatar.png", to = "avatar2.png") ``` - id: from-create-signed-url title: from.createSignedUrl() $ref: '@supabase/storage-js.packages/StorageFileApi.default.createSignedUrl' notes: | - RLS policy permissions required: - `buckets` table permissions: none - `objects` table permissions: `select` - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works params: - name: path isOptional: false type: String description: The path of the file you want to create a signed url for. - name: expiresIn isOptional: false type: Duration description: The duration the signed url should be valid for. - name: builder isOptional: true type: ImageTransformation.() -> Unit description: The transformation to apply to the image. subContent: - name: width isOptional: true type: Int description: The width of the image. - name: height isOptional: true type: Int description: The height of the image. - name: resize isOptional: true type: Resize description: The resize mode of the image. - name: quality isOptional: true type: Int description: The quality of the image. (Percentage 1-100, defaults to 80) - name: format isOptional: true type: String description: Specify in which format you want the image to receive. (Defaults to 'origin', which means the original format) examples: - id: create-signed-url name: Create Signed URL isSpotlight: true code: | ```kotlin val bucket = supabase.storage.from("avatars") val url = bucket.createSignedUrl(path = "icon.png", expiresIn = 3.minutes) ``` - id: create-signed-url-with-transformation name: Create Signed URL with transformation code: | ```kotlin val bucket = supabase.storage.from("avatars") val url = bucket.createSignedUrl(path = "icon.png", expiresIn = 3.minutes) { size(100, 100) fill() quality = 80 } ``` - id: from-create-signed-urls title: from.createSignedUrls() notes: | - RLS policy permissions required: - `buckets` table permissions: none - `objects` table permissions: `select` - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works params: - name: expiresIn isOptional: false type: Duration description: The duration the signed url should be valid for. - name: paths isOptional: false type: vararg String description: The paths of the files you want to create signed urls for. examples: - id: create-signed-urls name: Create Signed URLs isSpotlight: true code: | ```kotlin val urls = supabase.storage.from("avatars").createSignedUrls(20.minutes, "avata1.jpg", "avatar2.jpg") ``` - id: from-create-signed-upload-url title: from.createSignedUploadUrl() $ref: '@supabase/storage-js.packages/StorageFileApi.default.createSignedUploadUrl' notes: | - RLS policy permissions required: - `buckets` table permissions: none - `objects` table permissions: `insert` - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works params: - name: path isOptional: false type: String description: The path of the file you want to upload. - name: upsert isOptional: true type: Boolean description: Whether to overwrite the file if it already exists. examples: - id: create-signed-upload-url name: Create Signed Upload URL isSpotlight: true code: | ```kotlin val url = supabase.storage.from("avatars").createSignedUploadUrl("avatar.png") ``` - id: from-upload-to-signed-url title: from.uploadToSignedUrl() $ref: '@supabase/storage-js.packages/StorageFileApi.default.uploadToSignedUrl' notes: | - RLS policy permissions required: - `buckets` table permissions: none - `objects` table permissions: none - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works params: - name: path isOptional: false type: String description: The path of the file you want to upload. - name: token isOptional: false type: String description: The token you received from `createSignedUploadUrl`. - name: data isOptional: true type: ByteArray description: The data of the file you want to upload. - name: options isOptional: true type: UploadOptionBuilder.() -> Unit description: Additional options for the upload. subContent: - name: upsert isOptional: true type: Boolean description: Whether to overwrite the file if it already exists. - name: contentType isOptional: true type: ContentType description: The content type of the file. Will be automatically inferred using the file extension if not provided. examples: - id: upload-to-signed-url name: Upload to a signed URL isSpotlight: true code: | ```kotlin supabase.storage.from("avatars").uploadToSignedUrl(path = "avatar.jpg", token = "token-from-createSignedUploadUrl", data = bytes) //or on JVM: supabase.storage.from("avatars").uploadToSignedUrl(path = "avatar.jpg", token = "token-from-createSignedUploadUrl", file = File("avatar.jpg")) ``` - id: from-get-public-url title: from.getPublicUrl() $ref: '@supabase/storage-js.packages/StorageFileApi.default.getPublicUrl' notes: | - The bucket needs to be set to public, either via [updateBucket()](/docs/reference/kotlin/storage-updatebucket) or by going to Storage on [supabase.com/dashboard](https://supabase.com/dashboard), clicking the overflow menu on a bucket and choosing "Make public" - RLS policy permissions required: - `buckets` table permissions: none - `objects` table permissions: none - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works params: - name: path isOptional: false type: String description: The path of the file you want to get the public url for. examples: - id: returns-the-url-for-an-asset-in-a-public-bucket name: Returns the URL for an asset in a public bucket isSpotlight: true code: | ```kotlin val url = supabase.storage.from("public-bucket").publicUrl("folder/avatar1.png") ``` - id: transform-asset-in-public-bucket name: Returns the URL for an asset in a public bucket with transformations isSpotlight: true code: | ```kotlin val url = supabase.storage.from("public-bucket").publicRenderUrl("folder/avatar1.png") { size(100, 100) } ``` - id: from-download title: from.download() $ref: '@supabase/storage-js.packages/StorageFileApi.default.download' notes: | - RLS policy permissions required: - `buckets` table permissions: none - `objects` table permissions: `select` - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works params: - name: path isOptional: false type: String description: The path of the file you want to download. - name: options isOptional: true type: DownloadOptionBuilder.() -> Unit description: Additional options for the download. subContent: - name: transform isOptional: true type: ImageTransformation.() -> Unit = {} description: Image transformation. examples: - id: download-file-authenticated name: Download file from non-public bucket isSpotlight: true code: | ```kotlin val bucket = supabase.storage.from("avatars") val bytes = bucket.downloadAuthenticated("test.png") //or on JVM: bucket.downloadAuthenticatedTo("test.png", File("test.png")) ``` - id: download-file-public name: Download file from public bucket isSpotlight: true code: | ```kotlin val bucket = supabase.storage.from("avatars") val bytes = bucket.downloadPublic("test.png") //or on JVM: bucket.downloadPublicTo("test.png", File("test.png")) ``` - id: download-with-transformation name: Download file with transformation code: | ```kotlin val bucket = supabase.storage.from("avatars") val bytes = bucket.downloadPublic("test.png") { transform { size(100, 100) fill() quality = 100 } } //or on JVM: bucket.downloadPublicTo("test.png", File("test.png")) { transform { size(100, 100) fill() quality = 100 } } ``` - id: download-with-progress name: Download file with progress code: | ```kotlin val bucket = supabase.storage.from("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 } } ``` - id: from-remove title: from.remove() $ref: '@supabase/storage-js.packages/StorageFileApi.default.remove' notes: | - RLS policy permissions required: - `buckets` table permissions: none - `objects` table permissions: `delete` and `select` - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works params: - name: paths isOptional: false type: vararg String description: The paths of the files you want to remove. examples: - id: delete-file name: Delete file isSpotlight: true code: | ```kotlin val bucket = supabase.storage.from("avatars") bucket.delete("test.png", "test2.png") ``` - id: from-list title: from.list() $ref: '@supabase/storage-js.packages/StorageFileApi.default.list' notes: | - RLS policy permissions required: - `buckets` table permissions: none - `objects` table permissions: `select` - Refer to the [Storage guide](/docs/guides/storage/security/access-control) on how access control works examples: - id: list-files-in-a-bucket name: List files in a bucket isSpotlight: true code: | ```kotlin val bucket = supabase.storage.from("avatars") val files = bucket.list() ```