Back to the Couchbase homepageCouchbase logo
Couchbase Developer

  • Docs

    • Integrations
    • SDKs
    • Mobile SDKs

    • AI Developer
    • Backend
    • Full-stack
    • Mobile
    • Ops / DBA

    • Data Modeling
    • Scalability

  • Tutorials

    • Developer Community
    • Ambassador Program
  • Sign In
  • Try Free

Learn Couchbase Lite Key Value Engine with Kotlin and Jetpack Compose

  • Learn how to run Couchbase Lite in Standalone mode.
  • Use the Key Value engine to create and update documents.

Introduction

In this part of our learning path, you will walk through the "Audit Inventory" demo application of using Couchbase Lite in standalone mode, which means the database does not sync information from other resources using replication. While the demo app has a lot of functionality, this step will walk you through:

  • Installing Couchbase Lite on Android
  • Database operations for creating, opening, closing, and deleting a database
  • Document create, read, update, and delete (CRUD) operations via key-value pair

In this step of the learning path, you will be working with the code that allows users to log in and make changes to their user profile information. User profile information is persisted as a Document in the local Couchbase Lite Database. When the user logs out and logs back in again, the profile information is loaded from the Database.

User Profile App Demo,400

Installation

Fetching App Source Code

Clone Source Code

  • Clone the Learn Couchbase Lite with Kotlin and Jetpack Compose repository from GitHub.
git clone https://github.com/couchbase-examples/android-kotlin-cbl-learning-path.git

Installing Couchbase Lite Framework

  • The Demo app already contains the appropriate additions for downloading and utilizing the Kotlin Android Couchbase Lite dependency module. However, in the future, to include Couchbase Lite support within an Andorid app add the following within src/build.gradle
allprojects {
    repositories {
        ...

        maven {
            url "https://mobile.maven.couchbase.com/maven2/dev/"
        }
    }
}

Then add the following to the app/build.gradle file.

dependencies {
    ...

    implementation "com.couchbase.lite:couchbase-lite-android-ktx:3.0.0"
}

Try it out

  • Open src/build.gradle using Android Studio.
  • Build and run the project.
  • Verify that you see the login screen.

User Profile Login Screen Image

Data Model

Couchbase Lite is a JSON Document Store. A Document is a logical collection of named fields and values. The values are any valid JSON types. In addition to the standard JSON types, Couchbase Lite supports Date and Blob data types. While it is not required or enforced, it is a recommended practice to include a "type" property that can serve as a namespace for related documents.

The User Profile Document

The sample app deals with a single Document with a "documentType" property of "user". The document ID is of the form "user::<email>". An example of a document would be:

{
  "surname":"Doe",
  "givenName":"Jane",
  "jobTitle":"Developer",
  "team":"team1",
  "email":"demo@example.com"
  "documentType":"user",
  "imageData":
  {
   "length":217527,
   "content_type":"image/jpeg",
   "digest":"sha1-+8y7vkRd2J95kVe/yG2WhuEFa4o=",
   "@type":"blob"
  },
}

Special Blob data type that is associated with the profile image.

Team Membership

The team property designates which team a user is a member of. The team property is a security boundary used as part of the database name, which means users in the same team will use the same database file if a user shares the same physical device or emulator. To simplify things in this learning path, the MockAuthenticationService class defines users and which teams they belong to. Security rules, team membership, and authentication would normally be handled in an OAuth provider or a custom system in an actual mobile application.

UserProfile

Open the UserProfileViewModel.kt ViewModel in the com.couchbase.learningpath.ui.profile directory. For the purpose of this tutorial the "user" Document is first stored within an Any of type HashMap<String, Any>.

val profile = HashMap<String, Any>()
profile["givenName"] = givenName.value as Any
profile["surname"] = surname.value as Any
profile["jobTitle"] = jobTitle.value as Any
profile["email"] = emailAddress.value as Any
profile["team"] = team.value as Any
profile["documentType"] = "user" as Any
profilePic.value?.let {
  val outputStream = ByteArrayOutputStream()
  it.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
  profile["imageData"] =
      Blob("image/jpeg", outputStream.toByteArray()) as Any
}

The HashMap<String, Any> object functions are used as a data storage mechanism between the app's UI and the backing functionality of the Couchbase Lite Document object.

Basic Database Operations

In this section, we will do a code walkthrough of the basic Database operations.

Initialize Couchbase Lite

Before you can start using Couchbase Lite on Android, you would have to initialize it. Couchbase Lite needs to be initialized with the appropriate Android Application Context.

  • Open the DatabaseManager.kt file and locate the init constructor.
class InventoryDatabase private constructor (private val context: Context) {
    ...
    init {
        //setup couchbase lite
        CouchbaseLite.init(context)
        ...
    }

Create and Open a Database

When a user logs in, we create an empty Couchbase Lite database if one does not exist.

  • Open the DatabaseManager.kt file and locate the initializeDatabases function.
fun initializeDatabases(currentUser: User) 

NOTE: You will notice that this code has initialization for two different databases, the inventory database that we will be usign in this step, and the warehouse database. For this step you can ignore the code that initializes the warehouse database as we will cover it in a later step.

  • We create an instance of the DatabaseConfiguration within DatabaseManager.kt. Each team has their own instance of the Database that is located in a folder corresponding to the team name. Please note that the default path is platform-specific.
val dbConfig = DatabaseConfigurationFactory.create(context.filesDir.toString())
  • Then we create a local Couchbase Lite database named "teamname_userprofiles". If a database already exists, the existing version is returned.
// create or open a database to share between team members to store
// projects, assets, and user profiles
// calculate database name based on current logged in users team name
val teamName = (currentUser.team.filterNot { it.isWhitespace() }).lowercase()
currentInventoryDatabaseName = teamName.plus("_").plus(defaultInventoryDatabaseName)
inventoryDatabase = Database(currentInventoryDatabaseName, dbConfig)

Close a Database

When a user logs out or the app goes to the background, we close the Couchbase Lite database.

  • Open the DatabaseManger.kt file and locate the closeDatabases() function.
fun closeDatabases() {
  • Closing the database is pretty straightforward
inventoryDatabase?.close()

Deleting a Database

Deletion of a database is pretty straightforward and this is how you would do it.

fun deleteDatabases() {
  try {
    closeDatabases()
    Database.delete(currentInventoryDatabaseName, context.filesDir)
    Database.delete(warehouseDatabaseName, context.filesDir)
  } catch (e: Exception) {
    android.util.Log.e(e.message, e.stackTraceToString())
  }
}

fun closeDatabases() {
  try {
    inventoryDatabase?.close()
    locationDatabase?.close()
  } catch (e: java.lang.Exception) {
    android.util.Log.e(e.message, e.stackTraceToString())
  }
}

Try it out

  • The app can be tested using a simulator/emulator or device.
  • Log in to the app with any username and password. Let's use the values "demo@example.com" and "P@ssw0rd12" for username and password fields respectively. If this is the first time that the user is signing in, a new Couchbase Lite database will be created. If not, the existing database will be opened.

Document Operations

Once an instance of the Couchbase Lite database is created/opened for the specific user, we can perform basic Document functions on the database. In this section, we will walk through the code that describes basic Document operations

Reading a Document

Once the user logs in, the user is taken to the "Projects" screen. From this screen the user would tap on the Drawer menu icon (sometimes referred to the Hamburger icon) in the upper left hand corner of the screen and tap on the Update User Profile text button. A request is made to load The "User Profile" Document for the user. When the user logs in the very first time, there would be no user profile document for the user.

  • Open the UserProfileRepository.kt file and locate the getCurrentUserDocumentId function. This document Id is constructed by prefixing the term "user::" to the email Id of the user.
private fun getCurrentUserDocumentId(currentUser: String): String {
  return "user::${currentUser}"
}
  • Next, in the UserProfileRepository.kt file, locate the get method.
override suspend fun get(currentUser: String): Map<String, Any> {

Note: The get function is required by the interface KeyValueRepository found in the file KeyValueRepository.kt.

  • We try to fetch the Document with specified documentId from the database.
val results = HashMap<String, Any>()  //  <1>
results["email"] = currentUser as Any  //  <2>

val database = InventoryDatabase.getInstance(context).database
database?.let { db ->
  val documentId = getCurrentUserDocumentId(currentUser)
  val doc = db.getDocument(documentId)  //  <3>
  if (doc != null) {
      if (doc.contains("givenName")) { //  <4>
          results["givenName"] = doc.getString("givenName") as Any  //  <4>
      }
      if (doc.contains("surname")) { //  <4>
          results["surname"] = doc.getString("surname") as Any  //  <4>
      }
      if (doc.contains("jobTitle")) { //  <4>
          results["jobTitle"] = doc.getString("jobTitle") as Any  //  <4>
      }
      if (doc.contains("team")) { //  <4>
          results["team"] = doc.getString("team") as Any  //  <4>
      }
      if (doc.contains("imageData")) { //  <4>
          results["imageData"] = doc.getBlob("imageData") as Any  // <4>
      }
  }
}
return@withContext results  //  <5>
  1. Create an instance of the UserProfile via HashMap<String, Any>.
  2. Set the email property of the UserProfile with the email Id of the logged-in user. This value is not editable.
  3. Fetch an immutable copy of the Document from the Database
  4. If the document exists and is fetched successfully, we use appropriate type-getters to fetch the various members of the Document based on the property name. Specifically, note the support of the getBlob type to fetch the value of a property of type Blob
  5. Return the newly constructed UserProfile object.

Creating / Updating a Document

A "User Profile" Document is created for the user when the user taps the "Save" button on the "Edit Profile" view. The method below applies whether you are creating a document or updating an existing version.

  • Open the UserProfileRepository.kt file and locate the save function.
override suspend fun save(data: Map<String, Any>): Boolean {
  • We create a mutable instance of the Document. By default, all APIs in Couchbase Lite deal with immutable objects, thereby making them thread-safe by design. To mutate an object, you must explicitly get a mutable copy of the object. Use appropriate type-setters to set the various properties of the Document.
val mutableDocument = MutableDocument(documentId, data)
  • Save the document.
database?.save(mutableDocument)
}

Deleting a Document

We don't delete a Document in this sample app. However, deletion of a document is pretty straightforward and this is how you would do it.

val document = db.getDocument(documentId)

document?.let {
  db.delete(it)
  result = true
}

Try It Out

  • You should have followed the steps discussed in the "Try It Out" section under Create and Open a Database.
  • Enter a "First Name", "Last Name", and "Job Title" for the user in the Text Entry boxes and Tap "Save".
  • Confirm that you see a "Successfully Updated Profile" toast message. The first time you update the profile screen, the Document will be created.

User Profile Document Creation

  • Now tap on the "Photo" image and select an image from the Photo Album. Note that emulators don't have photos included in most images by default, so you might need to add a photo to select. Also some versions of Android differ in the UI used to browse for images.

image selection

  • Tap "Save"
  • Confirm that you see the toast message "Successfully Updated Profile". The Document will be updated this time.
  • Tap the Drawer menu icon in the upper left hand corner
  • Tap "Logout" to log out of the app
  • Log back into the app with the same user email Id and password that you used earlier. In my example, I used "demo@example.com" and "P@ssw0rd12". (Logging in with those credentials again)
  • Tap the Drawer menu icon in the upper left hand corner again
  • Confirm that you see the user profile widget with the name and image values that you set earlier.

log off

Learn More

Congratulations on completing the first step of the learning path by reviewing the code that saves User Profiles! In this section, we walked through a very basic example of how to get up and running with Couchbase Lite as a local-only, standalone embedded data store in your Android app. Continue on to the next step to learn how to use a pre-built database with Couchbase Lite.

References

  • Documentation: Installing Couchbase Lite on Android
  • Documentation: Database for Android
  • Documentation: Documents - Data Model

This tutorial is part of multiple Couchbase Learning Paths:
HOME
Couchbase Lite and Sync Gateway with Kotlin and JetPack Compose
NEXT
Include Pre-built Database
HOME
Couchbase Lite and Capella App Services with Kotlin and JetPack Compose
NEXT
Include Pre-built Database
Contents
Couchbase home page link

3250 Olcott Street
Santa Clara, CA 95054
United States

  • company
  • about
  • leadership
  • news & press
  • investor relations
  • careers
  • events
  • legal
  • contact us
  • support
  • Developer portal
  • Documentation
  • Forums
  • PROFESSIONAL SERVICES
  • support login
  • support policy
  • training
  • quicklinks
  • blog
  • downloads
  • get started
  • resources
  • why nosql
  • pricing
  • follow us
  • Social Media Link for FacebookFacebook
  • Social Media Link for TwitterTwitter
  • Social Media Link for LinkedInLinkedIn
  • Social Media Link for Youtubeyoutube
  • Social Media Link for GitHubGithub
  • Social Media Link for Stack OverflowStack Overflow
  • Social Media Link for Discorddiscord

© 2025 Couchbase, Inc. Couchbase and the Couchbase logo are registered trademarks of Couchbase, Inc. All third party trademarks (including logos and icons) referenced by Couchbase, Inc. remain the property of their respective owners.

Terms of UsePrivacy PolicyCookie PolicySupport PolicyDo Not Sell My Personal InformationMarketing Preference Center