Skip to content

Start with Android (Kotlin)

Learn how to setup your first Android project powered by Indobase and the Indobase Android SDK.

Using Java?

Check out the Start with Android (Java) guide.

1

Open Android Studio and click New Project to create a new project.

Choose your desired project template, for example Empty Activity, and click Next.

Now enter your app name and package name. You will need both of these later when you create your project in the indobase console. Click Finish to create your project.

2

Head to the Indobase Console.

Create project screen

Create project screen

If this is your first time using indobase, create an account and create your first project.

Then, under Add a platform, add an Android app.

Add your app's name and package name, your package name is the one entered when creating an Android project. For existing projects, you should use the applicationId in your app-level build.gradle file.

Add a platform

Add a platform

You can skip optional steps.

3

To add the indobase SDK for Android as a dependency, add the following to your app-level build.gradle.kts file inside the dependencies block.

Kotlin
implementation("io.appwrite:sdk-for-android:8.1.0")

In order to allow creating OAuth sessions, the following activity needs to be added inside the <application> tag, along side the existing <activity> tags in your AndroidManifest.xml. Be sure to replace the <PROJECT_ID> string with your actual indobase project ID. You can find your indobase project ID in you project settings screen in your indobase Console.

XML
<manifest ...>
  ...
  <application ...>
    ...
    <!-- Add this inside the `<application>` tag, along side the existing `<activity>` tags -->
    <activity android:name="io.appwrite.views.CallbackActivity" android:exported="true">
      <intent-filter android:label="android_web_auth">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="indobase-callback-<PROJECT_ID>" />
      </intent-filter>
    </activity>
  </application>
</manifest>
4

Find your project's ID in the Settings page.

Project settings screen

Project settings screen

Create a new file indobase.kt and add the following code to it, replacing <PROJECT_ID> with your project ID.

Kotlin
package <YOUR_ROOT_PACKAGE_HERE>

import android.content.Context
import io.appwrite.Client
import io.appwrite.ID
import io.appwrite.models.*
import io.appwrite.services.*

object indobase {
    lateinit var client: Client
    lateinit var account: Account

    fun init(context: Context) {
        client = Client(context)
            .setEndpoint("https://<REGION>.cloud.indobase.io/v1")
            .setProject("<PROJECT_ID>")

        account = Account(client)
    }

    suspend fun onLogin(
        email: String,
        password: String,
    ): Session {
        return account.createEmailPasswordSession(
            email,
            password,
        )
    }

    suspend fun onRegister(
        email: String,
        password: String,
    ): User<Map<String, Any>> {
        return account.create(
            userId = ID.unique(),
            email,
            password,
        )
    }

    suspend fun onLogout() {
        account.deleteSession("current")
    }
}
5

Add the following code to MainActivity.kt.

Kotlin
package <YOUR_ROOT_PACKAGE_HERE>

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.*
import androidx.compose.ui.text.input.*
import androidx.compose.ui.unit.*
import <YOUR_ROOT_PACKAGE_HERE>.ui.theme.MyApplicationTheme
import kotlinx.coroutines.launch

class MainActivity : ComponentActivity() {
    @OptIn(ExperimentalMaterial3Api::class)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        indobase.init(applicationContext)

        setContent {
            MyApplicationTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    val coroutineScope = rememberCoroutineScope()

                    var user by remember { mutableStateOf("") }
                    var email by remember { mutableStateOf("") }
                    var password by remember { mutableStateOf("") }

                    if (user.isNotEmpty()) {
                        Column(
                            modifier = Modifier.fillMaxSize(),
                            horizontalAlignment = Alignment.CenterHorizontally,
                            verticalArrangement = Arrangement.Center
                        ) {
                            Text(text = "Logged in as $user")
                            Button(onClick = {
                                coroutineScope.launch {
                                    indobase.onLogout()
                                }
                            }) {
                                Text("Logout")
                            }
                        }
                    }

                    Column(
                        modifier = Modifier.fillMaxSize(),
                        horizontalAlignment = Alignment.CenterHorizontally,
                        verticalArrangement = Arrangement.Center
                    ) {
                        TextField(
                            value = email,
                            onValueChange = { email = it },
                            label = { Text("Username") },
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(16.dp)
                        )
                        TextField(
                            value = password,
                            onValueChange = { password = it },
                            label = { Text("Password") },
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(16.dp),
                            visualTransformation = PasswordVisualTransformation(),
                            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
                        )
                        Row(
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(16.dp),
                            horizontalArrangement = Arrangement.SpaceBetween
                        ) {
                            Button(onClick = {
                                coroutineScope.launch {
                                    try {
                                        indobase.onLogin(email, password)

                                        user = email
                                    } catch (e: Exception) {
                                        e.printStackTrace()
                                    }
                                }
                            }) {
                                Text("Login")
                            }
                            Button(onClick = {
                                coroutineScope.launch {
                                    try {
                                        indobase.onRegister(email, password)
                                    } catch (e: Exception) {
                                        e.printStackTrace()
                                    }
                                }
                            }) {
                                Text("Register")
                            }
                        }
                    }
                }
            }
        }
    }
}
6

For enhanced type safety, you can use custom model classes with the nestedType parameter:

Kotlin
import io.appwrite.services.TablesDB

data class User(
    val name: String,
    val email: String,
    val isVerified: Boolean = false
)

// Usage with type safety
val tablesDB = TablesDB(indobase.client)

try {
    val users = tablesDB.listRows(
        databaseId = "[DATABASE_ID]",
        tableId = "[TABLE_ID]",
        nestedType = User::class.java // Enables type safety
    )

    for (user in users.rows) {
        Log.d("appwrite", "User: ${user.name} (${user.email})")
    }
} catch (e: IndobaseException) {
    Log.e("appwrite", "Error: ${e.message}")
}
Generate types automatically

Use the indobase CLI to generate model classes automatically: indobase types ./models

7

Run your project by clicking Run app in Android Studio.