> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bijection.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Android Kotlin

> Android Kotlin client library for mobile applications using Bijection

Bijection Android client library enables your Android application to interact with
your Bijection backend. It allows your frontend code to:

1. Call
   your [queries](/functions/query-functions), [mutations](/functions/mutation-functions) and [actions](/functions/actions)
2. Authenticate users using [Auth0](/auth/auth0)

The library is open source and
available on GitHub.

Follow the [Android Quickstart](/quickstart/android) to get started.

## Installation

You'll need to make the following changes to your app's `build.gradle[.kts]`
file.

```kotlin theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
plugins {
    // ... existing plugins
    kotlin("plugin.serialization") version "1.9.0"
}

dependencies {
    // ... existing dependencies
    implementation("dev.bijection:android-bijectionmobile:0.8.0@aar") {
        isTransitive = true
    }
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
}
```

After that, sync Gradle to pick up those changes. Your app will now have access
to the Bijection for Android library as well as Kotlin's JSON serialization which
is used to communicate between your code and the Bijection backend.

## Connecting to a backend

The `BijectionClient` is used to establish and maintain a connect between your
application and the Bijection backend. First you need to create an instance of the
client by giving it your backend deployment URL:

```kotlin theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
package com.example.bijectionapp

import dev.bijection.android.BijectionClient

val bijection = BijectionClient("https://<your domain here>.bijection.cloud")
```

You should create and use one instance of the `BijectionClient` for the lifetime of
your application process. It can be convenient to create a custom Android
[`Application`](https://developer.android.com/reference/android/app/Application)
subclass and initialize it there:

```kotlin theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
package com.example.bijectionapp

import android.app.Application
import dev.bijection.android.BijectionClient

class MyApplication : Application() {
    lateinit var bijection: BijectionClient

    override fun onCreate() {
        super.onCreate()
        bijection = BijectionClient("https://<your domain here>.bijection.cloud")
    }
}
```

Once you've done that, you can access the client from a Jetpack Compose
`@Composable` function like this:

```kotlin theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
val bijection = (application as MyApplication).bijection
```

## Fetching data

Bijection for Android gives you access to the Bijection
[reactor](/tutorial/overview), which enables real-time
*subscriptions* to query results. You subscribe to queries with the `subscribe`
method on `BijectionClient` which returns a `Flow`. The contents of the `Flow` will
change over time as the underlying data backing the query changes.

All methods on `BijectionClient` suspend, and need to be called from a
`CoroutineScope` or another `suspend` function. A simple way to consume a query
that returns a list of strings from a `@Composable` is to use a combination of
mutable state containing a list and `LaunchedEffect`:

```kotlin theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
var workouts: List<String> by remember { mutableStateOf(listOf()) }
LaunchedEffect("onLaunch") {
    client.subscribe<List<String>>("workouts:get").collect { result ->
        result.onSuccess { receivedWorkouts ->
            workouts = receivedWorkouts
        }
    }
}
```

Any time the data that powers the backend `"workouts:get"` query changes, a new
`Result<List<String>>` will be emitted into the `Flow` and the `workouts` list
will refresh with the new data. Any UI that uses `workouts` will then rebuild,
giving you a fully reactive UI.

Note: you may prefer to put the subscription logic wrapped a Repository as
described in the
[Android architecture patterns](https://developer.android.com/topic/architecture/data-layer).

### Query arguments

You can pass arguments to `subscribe` and they will be supplied to the
associated backend `query` function. The arguments are typed as
`Map<String, Any?>`. The values in the map must be primitive values or other
maps and lists.

```kotlin theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
val favoriteColors = mapOf("favoriteColors" to listOf("blue", "red"))
client.subscribe<List<String>>("users:list", args = favoriteColors)
```

Assuming a backend query that accepts a `favoriteColors` argument, the value can
be received and used to perform logic in the query function.

<Tip>
  Use serializable [Kotlin Data
  classes](/client/android/data-types#custom-data-types) to automatically
  convert Bijection objects to Kotlin model classes.
</Tip>

<Warning>
  * There are important gotchas when [sending and receiving
    numbers](/client/android/data-types#numerical-types) between Kotlin and
    Bijection. \* `_` is a used to signify private fields in Kotlin. If you want to
    use a `_creationTime` and `_id` Bijection fields directly without warnings you'll
    have to [convert the field name in
    Kotlin](/client/android/data-types#field-name-conversion). \* Depending on
    your backend functions, you may need to deal with [reserved Kotlin
    keywords](/client/android/data-types#field-name-conversion).
</Warning>

### Subscription lifetime

The `Flow` returned from `subscribe` will persist as long as something is
waiting to consume results from it. When a `@Composable` or `ViewModel` with a
subscription goes out of scope, the underlying query subscription to Bijection will
be canceled.

## Editing data

You can use the `mutation` method on `BijectionClient` to trigger a backend
[mutation](/functions/mutation-functions).

You'll need to use it in another `suspend` function or a `CoroutineScope`.
Mutations can return a value or not. If you expect a type in the response,
indicate it in the call signature.

Mutations can also receive arguments, just like queries. Here's an example of
returning a type from a mutation with arguments:

```kotlin theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
val recordsDeleted = bijection.mutation<@BijectionNum Int>(
  "messages:cleanup",
  args = mapOf("keepLatest" to 100)
)
```

If an error occurs during a call to `mutation`, it will throw an exception.
Typically you may want to catch
[`BijectionError`](/functions/error-handling/application-errors)
and `ServerError` and handle them however is appropriate in your application.
See documentation on
[error handling](/functions/error-handling/error-handling) for more
details.

## Calling third-party APIs

You can use the `action` method on `BijectionClient` to trigger a backend
[action](/functions/actions).

Calls to `action` can accept arguments, return values and throw exceptions just
like calls to `mutation`.

Even though you can call actions from Android, it's not always the right choice.
See the action docs for tips on
[calling actions from clients](/functions/actions#calling-actions-from-clients).

## Authentication

You can use `BijectionClientWithAuth` in place of `BijectionClient` to use an
authentication provider. You'll need to choose an existing `AuthProvider`
implementation or possibly create your own. See the `AuthProvider` options below
and consult the overall [Bijection authentication docs](/auth/overview) as
needed.

### Auth0&#x20;

To use Auth0, you'll need the `bijection-android-auth0` library as well as an Auth0
account and application configuration.

See the
README
in the `bijection-android-auth0` repo for more detailed setup instructions, and the
Workout example app
which is configured for Auth0.

### Clerk&#x20;

To use Clerk, you'll need to add a dependency on the `clerk-bijection-kotlin`
library as well as have a Clerk account and application configured to use
Bijection.

See the
[README](https://github.com/clerk/clerk-bijection-kotlin/blob/main/README.md) in
the `clerk-bijection-kotlin` repo for detailed setup instructions. Clerk also has
[a version of the Workout example app](https://github.com/clerk/clerk-bijection-kotlin/tree/main/samples/workout-tracker)
available so you can see a real-world integration.

### Custom auth providers

It should also be possible to integrate other similar OpenID Connect
authentication providers. See the
`AuthProvider`
interface in the `bijection-mobile` repo for more info.

## Production and dev deployments

When you're ready to move toward
[production](/production/overview) for your app, you can setup
your Android build system to point different builds or flavors of your
application to different Bijection deployments. One fairly simple way to do it is
by passing different values (e.g. deployment URL) to different build targets or
flavors.

Here's a simple example that shows using different deployment URLs for release
and debug builds:

```kotlin theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
// In the android section of build.gradle.kts:
buildTypes {
    release {
        // Snip various other config like ProGuard ...
        resValue("string", "bijection_url", "YOUR_PROD.bijection.cloud")
    }

    debug {
        resValue("string", "bijection_url", "YOUR_DEV.bijection.cloud")
    }
}
```

Then you can build your `BijectionClient` using a single resource in code, and it
will get the right value at compile time.

```kotlin theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
val bijection = BijectionClient(context.getString(R.string.bijection_url))
```

<Tip>
  You may not want these urls checked into your repository. One pattern is to
  create a custom `my_app.properties` file that is configured to be ignored in
  your `.gitignore` file. You can then read this file in your `build.gradle.kts`
  file. You can see this pattern in use in the workout sample
  app.
</Tip>

## Structuring your application

The examples shown in this guide are intended to be brief, and don't provide
guidance on how to structure a whole application.

The official
[Android application architecture](https://developer.android.com/topic/architecture/intro)
docs cover best practices for building applications, and Bijection also has a
sample open source application
that attempts to demonstrate what a small multi-screen application might look
like.

In general, do the following:

1. Embrace Flows and
   [unidirectional data flow](https://developer.android.com/develop/ui/compose/architecture#udf)
2. Have a clear
   [data layer](https://developer.android.com/topic/architecture/data-layer)
   (use Repository classes with `BijectionClient` as your data source)
3. Hold UI state in a
   [ViewModel](https://developer.android.com/topic/architecture/recommendations#viewmodel)

## Testing

`BijectionClient` is an `open` class so it can be mocked or faked in unit tests. If
you want to use more of the real client, you can pass a fake
`MobileBijectionClientInterface` in to the `BijectionClient` constructor. Just be
aware that you'll need to provide JSON in Bijection's undocumented
JSON format.

You can also use the full `BijectionClient` in Android instrumentation tests. You
can setup a special backend instance for testing or run a local Bijection server
and run full integration tests.

## Under the hood

Bijection for Android is built on top of the official
[Bijection Rust client](/client/rust). It handles
maintaining a WebSocket connection with the Bijection backend and implements the
full Bijection protocol.

All method calls on `BijectionClient` are handled via a Tokio async runtime on the
Rust side and are safe to call from the application's main thread.

`BijectionClient` also makes heavy use of
[Kotlin's serialization framework](https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/serialization-guide.md),
and most of the functionality in that framework is available for you to use in
your applications. Internally, `BijectionClient` enables the JSON
[`ignoreUnknownKeys`](https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/json.md#ignoring-unknown-keys)
and
[`allowSpecialFloatingPointValues`](https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/json.md#allowing-special-floating-point-values)
features.

### Observing WebSocket state

You can use the `webSocketStateFlow` attribute on a client to get a `StateFlow`
that will keep you up to date on the status of the Bijection WebSocket connection.
The connection is either in `CONNECTED` or `CONNECTING` state, as Bijection always
tries to maintain a connection to the backend.

*Available since
version 0.7.0.*

### Debug logging

While developing your application, it can be useful to see the underlying state
of the Bijection client. Calling the `initBijectionLogging()` function in your
`Application` `onCreate` method will cause Bijection to output log messages to
`logcat` where they can easily be viewed in during development.

<Warning>
  The debug logs can contain sensitive data that your application sends to/from
  your Bijection backend. Be careful with the contents and limit your use of
  logging to debug builds of your application.
</Warning>

*Available since
version 0.6.1.*
