A retail inventory management app for Android demonstrating Couchbase Lite's offline-first capabilities, real-time sync with Capella App Services, and peer-to-peer sync between devices.
Important
Before proceeding with the Android setup, you must complete the Capella backend configuration described in the root README. This includes creating a Capella cluster, deploying an App Service, setting up the bucket/scopes/collections, importing the sample dataset, creating App Endpoints and App Users, and recording the public connection URL. If you skip these steps, the app will fail to authenticate and sync.
If you've already completed the initial setup and have Java 17 + Couchbase Lite EE installed:
# Open the project in Android Studio
open -a "Android Studio" /path/to/Android
# Or build from command line
cd /path/to/Android
./gradlew assembleDebug
# Install on device
./gradlew installDebugFirst time setup? Continue reading below for complete installation instructions.
The following requirements apply to both macOS and Windows:
- Android Studio: Ladybug (2024.2.1) or later
- Android SDK:
- Minimum SDK: 24 (Android 7.0 Nougat)
- Target SDK: 35 (Android 15)
- Compile SDK: 35
- JDK: 17 or later
- Kotlin: 2.0.21
The project uses Gradle with Kotlin DSL for dependency management. Key dependencies:
- Couchbase Lite Android: 3.3.0 (Enterprise Edition with KTX extensions)
- Jetpack Compose: Material 3 UI components
- Kotlin Coroutines: For asynchronous operations
- Lifecycle Components: ViewModel and LiveData
All dependencies are declared in gradle/libs.versions.toml and automatically resolved by Gradle.
- Homebrew: For installing Java on macOS (optional but recommended)
Android Studio manages library dependencies via Gradle. Third-party libraries such as Couchbase Lite Enterprise Edition will be resolved and downloaded at compile time.
If you don't have Java 17 installed, install it using Homebrew:
# Install OpenJDK 17
brew install openjdk@17
# Configure environment variables in ~/.zshrc
echo 'export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH"' >> ~/.zshrc
echo 'export JAVA_HOME="/opt/homebrew/opt/openjdk@17"' >> ~/.zshrc
# Apply changes
source ~/.zshrc
# Verify installation
java -versionYou should see: openjdk version "17.0.x"
Create global Gradle configuration to handle SSL certificates:
# Create global gradle.properties
cat > ~/.gradle/gradle.properties << 'EOF'
# Global Gradle properties
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 -Djavax.net.ssl.trustStoreType=KeychainStore
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.caching=true
EOFDue to SSL certificate issues with the Couchbase Maven repository, we need to manually download the Enterprise Edition libraries:
# Create local Maven repository directories
mkdir -p ~/.m2/repository/com/couchbase/lite/couchbase-lite-android-ee-ktx/3.3.0
mkdir -p ~/.m2/repository/com/couchbase/lite/couchbase-lite-android-ee/3.3.0
# Download EE KTX (72KB)
cd ~/.m2/repository/com/couchbase/lite/couchbase-lite-android-ee-ktx/3.3.0
curl -L -k "https://mobile.maven.couchbase.com/maven2/dev/com/couchbase/lite/couchbase-lite-android-ee-ktx/3.3.0/couchbase-lite-android-ee-ktx-3.3.0.aar" -o couchbase-lite-android-ee-ktx-3.3.0.aar
curl -L -k "https://mobile.maven.couchbase.com/maven2/dev/com/couchbase/lite/couchbase-lite-android-ee-ktx/3.3.0/couchbase-lite-android-ee-ktx-3.3.0.pom" -o couchbase-lite-android-ee-ktx-3.3.0.pom
# Download EE Core (9.4MB)
cd ~/.m2/repository/com/couchbase/lite/couchbase-lite-android-ee/3.3.0
curl -L -k "https://mobile.maven.couchbase.com/maven2/dev/com/couchbase/lite/couchbase-lite-android-ee/3.3.0/couchbase-lite-android-ee-3.3.0.aar" -o couchbase-lite-android-ee-3.3.0.aar
curl -L -k "https://mobile.maven.couchbase.com/maven2/dev/com/couchbase/lite/couchbase-lite-android-ee/3.3.0/couchbase-lite-android-ee-3.3.0.pom" -o couchbase-lite-android-ee-3.3.0.pom
# Verify files were downloaded
ls -lh ~/.m2/repository/com/couchbase/lite/couchbase-lite-android-ee-ktx/3.3.0/
ls -lh ~/.m2/repository/com/couchbase/lite/couchbase-lite-android-ee/3.3.0/Note: The -k flag bypasses SSL certificate verification. This is only needed for the initial download. Once files are in your local Maven repository (~/.m2/), Gradle will use them directly.
After completing the macOS-specific steps above, continue with the Common Setup Steps that apply to both platforms.
Before opening the project, ensure the following. Commands below are shown for a Unix-like shell (macOS Terminal, Linux, or Git Bash on Windows); Windows Command Prompt / PowerShell equivalents are noted inline.
macOS / Linux / Git Bash:
# Check Java version
java -version # Should show 17.0.x
# Check Gradle wrapper exists
cd <path-to-repo>/Android
ls -la gradlew # Should exist and be executable
# Verify Couchbase EE (core + KTX) is installed locally
ls -la ~/.m2/repository/com/couchbase/lite/couchbase-lite-android-ee/3.3.0/*.aar
ls -la ~/.m2/repository/com/couchbase/lite/couchbase-lite-android-ee-ktx/3.3.0/*.aarOpen Android Studio and select File > Open, then navigate to the Android directory and open it.
Android Studio will automatically sync Gradle and resolve dependencies from:
- Local Maven repository (
~/.m2/repository/on macOS,%USERPROFILE%\.m2\repository\on Windows) for Couchbase Lite EE - Google Maven for Android libraries
- Maven Central for other dependencies
This may take a few minutes on first open.
Install the following software using the default settings:
- Git for Windows
- [Android Studio](Download Android Studio & App Tools - Android Developers)
We use Android Studio to clone the repository.
- Open Android Studio
- On the Welcome screen, click Clone Repository
- Enter URL
[https://github.com/couchbase-examples/couchbase-lite-retail-demo.git](https://github.com/couchbase-examples/couchbase-lite-retail-demo.git) - Select a folder into which to clone the repository; take not of the folder path
- Once the project has been cloned, close the project (File -> Close Project)
- Remove the project from recent history (Click the three dots and select Remove from recent projects)
- On the Welcome screen, click Open
- Navigate to the folder into which you cloned the project
- Important: Do not select the main
couchbase-lite-retail-demofolder. Instead, select only theAndroidfolder - Android Studio will now start a "Gradle Sync". At the bottom of the screen you will see a progress bar. Wait until this finishes. If it asks to "Trust Project," click Trust.
After import completes, proceed to the Common Setup Steps. In particular, modify the gradle.properties file as described in Step 3: Configure Capella App Services — Option B: Gradle Properties. You can find the gradle.properties file after expanding Gradle Scripts on the left hand side.
The following steps apply to both macOS and Windows. Complete your platform-specific setup above before continuing.
Before running the app, configure your Capella App Services connection using environment variables or Gradle properties.
Where to find CBL_BASE_URL: In your Capella dashboard, go to App Services > select your App Endpoint (e.g. supermarket-nyc) > Connect tab. Copy the Public Connection URL, it will look like wss://<id>.apps.cloud.couchbase.com. Use only the base URL; do not append the database name (that is handled separately by CBL_AA_DB / CBL_NYC_DB).
On MacOS, set these environment variables before running Android Studio:
export CBL_BASE_URL="wss://your-endpoint.apps.cloud.couchbase.com:4984"
export CBL_AA_DB="supermarket-aa"
export CBL_NYC_DB="supermarket-nyc"
export CBL_AA_USER="aa-store-01@supermarket.com"
export CBL_NYC_USER="nyc-store-01@supermarket.com"
export CBL_PASSWORD="P@ssword1"Then launch Android Studio from the same terminal:
studio.sh # or open -a "Android Studio" on macOSOn Windows, either set persistent values via System Properties > Environment Variables, or use a PowerShell session:
$env:CBL_BASE_URL = "wss://your-endpoint.apps.cloud.couchbase.com:4984"
$env:CBL_AA_DB = "supermarket-aa"
$env:CBL_NYC_DB = "supermarket-nyc"
$env:CBL_AA_USER = "aa-store-01@supermarket.com"
$env:CBL_NYC_USER = "nyc-store-01@supermarket.com"
$env:CBL_PASSWORD = "P@ssword1"
# Launch Android Studio from the same session so it inherits the variables.
# Adjust the path if your install location differs.
& "C:\Program Files\Android\Android Studio\bin\studio64.exe"Command Prompt (CMD) equivalent:
set "CBL_BASE_URL=wss://your-endpoint.apps.cloud.couchbase.com:4984"
set "CBL_AA_DB=supermarket-aa"
set "CBL_NYC_DB=supermarket-nyc"
set "CBL_AA_USER=aa-store-01@supermarket.com"
set "CBL_NYC_USER=nyc-store-01@supermarket.com"
set "CBL_PASSWORD=P@ssword1"
"C:\Program Files\Android\Android Studio\bin\studio64.exe"Variables set via $env: or set apply only to the current shell session; launching Android Studio from that same session is what lets the IDE inherit them.
Add these properties to your local gradle.properties file (create it in the Android directory if it doesn't exist):
CBL_BASE_URL=wss://your-endpoint.apps.cloud.couchbase.com:4984
CBL_AA_DB=supermarket-aa
CBL_NYC_DB=supermarket-nyc
CBL_AA_USER=aa-store-01@supermarket.com
CBL_NYC_USER=nyc-store-01@supermarket.com
CBL_PASSWORD=P@ssword1Note: Do not commit gradle.properties with sensitive credentials to version control.
Creating a virtual device is documented at Create and manage virtual devices | Android Studio | Android Developers. In short:
- Go to Tools -> Device Manager
- Click Add a new device, then Create virtual device
- Select a device, e.g., a Pixel phone
- On the next screen, select, e.g.:
- API: API 28 "Pie"
- System image: Choose the image matching your host architecture; emulating the wrong architecture is either unsupported or prohibitively slow.
- On Intel/AMD Macs and Windows PCs: Google Play Intel x86 Atom System Image
- On Apple Silicon Macs (M1/M2/M3/M4): Google Play ARM 64 v8a System Image
- Click Finish
At the top toolbar, ensure your virtual device emulator is selected. Click the Green Run button (▶). The emulator comes up on the right hand side, running the application.
Further documentation: Run apps on the Android Emulator | Android Studio | Android Developers
Android/
├── app/
│ ├── src/main/
│ │ ├── java/com/example/groceryapplication/
│ │ │ ├── GroceryApplication.kt # Application class
│ │ │ ├── MainActivity.kt # Main activity with Compose setup
│ │ │ ├── AppConfig.kt # Configuration (database, sync, stores)
│ │ │ ├── DatabaseManager.kt # Couchbase Lite database operations
│ │ │ ├── AppServicesSyncManager.kt # Sync with Capella App Services
│ │ │ ├── MultipeerSyncManager.kt # Peer-to-peer sync
│ │ │ ├── AuthenticationManager.kt # User authentication
│ │ │ ├── Screens/
│ │ │ │ ├── LoginScreen.kt
│ │ │ │ ├── InventoryScreen.kt
│ │ │ │ ├── OrdersScreen.kt
│ │ │ │ └── ProfileScreen.kt
│ │ │ └── Models/
│ │ │ ├── GroceryItem.kt
│ │ │ ├── Order.kt
│ │ │ └── StoreProfile.kt
│ │ ├── res/ # Resources (layouts, drawables, etc.)
│ │ └── AndroidManifest.xml
│ ├── build.gradle.kts # App-level Gradle build file
│ └── proguard-rules.pro
├── gradle/
│ ├── libs.versions.toml # Centralized dependency versions
│ └── wrapper/ # Gradle wrapper files
├── build.gradle.kts # Project-level Gradle build file
└── gradle.properties # Gradle configuration
- Database Name:
GroceryInventoryDB - Scopes:
AA-Store,NYC-Store(based on selected store) - Collections:
inventory- Product inventory itemsorders- Customer ordersprofile- Store profile information
The app uses continuous replication, which is event-driven (not polling). Changes are pushed and pulled immediately over a persistent WebSocket connection to Capella App Services.
Key settings in AppConfig.kt:
SYNC_CONTINUOUS: Enables real-time bidirectional syncENABLE_APP_SERVICES_SYNC: Toggle cloud sync on/offENABLE_P2P_SYNC: Toggle peer-to-peer sync on/off
The app syncs inventory, orders, and store profile data with your Capella cluster through App Services. Changes made in the app are immediately synced to the cloud and to other connected devices.
Devices on the same local network can sync directly with each other without going through the cloud. This is useful for:
- Demo scenarios with multiple devices
- Offline collaboration between nearby devices
- Reducing cloud bandwidth usage
P2P sync uses the same peer group ID as the iOS app, enabling cross-platform local sync between Android and iOS devices.
The app works fully offline using Couchbase Lite as the local database. All operations (create, read, update, delete) work without network connectivity. When connectivity is restored, changes automatically sync to the cloud.
The app is built entirely with Jetpack Compose, Google's modern declarative UI toolkit for Android. This provides a responsive and intuitive user experience.
./gradlew assembleDebugOutput: app/build/outputs/apk/debug/app-debug.apk
./gradlew assembleReleaseFor production releases, configure signing in app/build.gradle.kts.
./gradlew installDebug"Could not install Gradle distribution" or SSL/Certificate errors
If you see errors related to Gradle distribution or SSL certificates:
# Stop all Gradle daemons
cd /path/to/Android
./gradlew --stop
# Clean caches
rm -rf .gradle/
rm -rf ~/.gradle/daemon/
# Verify global gradle.properties exists with SSL config
cat ~/.gradle/gradle.properties
# Should contain: -Djavax.net.ssl.trustStoreType=KeychainStore
# Restart Android Studio and sync again"Could not resolve com.couchbase.lite:couchbase-lite-android-ee-ktx"
This usually means the Couchbase Lite EE libraries aren't in your local Maven repository:
# Verify the files exist
ls -la ~/.m2/repository/com/couchbase/lite/couchbase-lite-android-ee/3.3.0/*.aar
ls -la ~/.m2/repository/com/couchbase/lite/couchbase-lite-android-ee-ktx/3.3.0/*.aar
# If missing, re-run Step 3 from Initial SetupAlso verify that settings.gradle.kts includes mavenLocal():
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
mavenLocal() // Must be first!
google()
mavenCentral()
}
}"BuildConfig cannot be resolved"
- Make sure
buildFeatures { buildConfig = true }is set inapp/build.gradle.kts - Sync project with Gradle files (File > Sync Project with Gradle Files)
- Verify all required environment variables or Gradle properties are set
Gradle sync failures
- Verify Java 17 is installed:
java -version - Check
JAVA_HOMEis set:echo $JAVA_HOME - Update Android Gradle Plugin: Tools > SDK Manager > SDK Tools
- Clean and rebuild: Build > Clean Project, then Build > Rebuild Project
- Try invalidating caches: File > Invalidate Caches > Invalidate and Restart
Sync not working
- Verify your
CBL_BASE_URLis correct and includeswss://protocol - Check that configuration variables are properly set (check Logcat for printed config)
- Verify your App Services endpoint is running in Capella
- Check Logcat for sync-related error messages (filter by "AppServicesSyncManager")
Authentication failures
- Ensure the user credentials match those configured in Capella App Services
- Verify the database name (
CBL_AA_DBorCBL_NYC_DB) matches your App Endpoint - Check that the username format matches the expected pattern
App crashes on launch
- Check Logcat for stack traces
- Verify all required configuration values are set (not empty strings)
- Ensure the device/emulator meets minimum API level 24
Data not appearing
- Confirm your Capella cluster has data imported into the correct scope/collection
- Check that scope and collection names in
AppConfig.ktmatch your Capella setup - Look for database errors in Logcat (filter by "DatabaseManager")
P2P sync not discovering devices
- Ensure devices are on the same Wi-Fi network
- Check that local network permissions are granted
- Verify the
P2P_PEER_GROUP_IDis the same across all devices - Look for P2P-related logs in Logcat (filter by "MultipeerSyncManager")
Couchbase Lite logging can be configured in DatabaseManager.kt to help debug sync and database issues:
Database.log.console.level = LogLevel.VERBOSEYou can use the Couchbase Lite command-line tool to inspect the database file:
- Pull the database from device:
adb pull /data/data/com.example.groceryapplication/files/GroceryInventoryDB.cblite2 - Use
cblitetool to query the database
The following files were created or configured during the initial setup process:
Contains JVM arguments and Gradle settings, including SSL certificate handling. Location and trustStoreType value are platform-specific:
- macOS / Linux:
~/.gradle/gradle.properties - Windows:
%USERPROFILE%\.gradle\gradle.properties(CMD) or$env:USERPROFILE\.gradle\gradle.properties(PowerShell)
macOS:
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 -Djavax.net.ssl.trustStoreType=KeychainStore
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.caching=trueWindows (use Windows-ROOT, or omit the trustStoreType arg entirely — KeychainStore is macOS-only and will throw KeyStoreException on Windows):
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 -Djavax.net.ssl.trustStoreType=Windows-ROOT
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.caching=trueConfigured with mavenLocal() repository to use locally downloaded Couchbase Lite EE:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
mavenLocal() // Check local Maven repository first
google()
mavenCentral()
maven {
url = uri("https://mobile.maven.couchbase.com/maven2/dev/")
isAllowInsecureProtocol = false
}
}
}Java configuration is set per-platform:
macOS (~/.zshrc):
export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH"
export JAVA_HOME="/opt/homebrew/opt/openjdk@17"Windows — PowerShell (current session):
$env:JAVA_HOME = "C:\Program Files\Microsoft\jdk-17" # adjust to your JDK install path
$env:Path = "$env:JAVA_HOME\bin;$env:Path"Windows — persistent (System Properties): open System Properties → Advanced → Environment Variables, set JAVA_HOME to your JDK 17 install directory, and prepend %JAVA_HOME%\bin to the Path variable. Launch Android Studio after applying the change so it inherits the new environment.
This project uses Couchbase Lite Enterprise Edition, which includes features like:
- Peer-to-peer sync (MultipeerReplicator) - Required for this demo
- Encrypted sync - Additional security layer
- Delta sync - More efficient synchronization
The Community Edition does not include peer-to-peer sync, so the MultipeerSyncManager features won't work if you switch to CE.
To use the Community Edition (if you don't need P2P sync), change the dependency in app/build.gradle.kts:
// Replace enterprise edition
implementation("com.couchbase.lite:couchbase-lite-android-ee-ktx:3.3.0")
// With community edition (available on Maven Central)
implementation("com.couchbase.lite:couchbase-lite-android-ktx:3.3.0")You would also need to comment out or remove the P2P sync functionality in:
MultipeerSyncManager.ktMultipeerSyncComponents.kt- References to MultipeerSyncManager in other screens
To verify your setup:
# Check Java
java -version # Should show: openjdk version "17.0.x"
# Check Gradle
./gradlew --version # Should show: Gradle 8.11.1
# Check Couchbase EE locally installed
ls -la ~/.m2/repository/com/couchbase/lite/couchbase-lite-android-ee/3.3.0/*.aar
# Test build
./gradlew assembleDebug # Should complete successfully- Main Project README - Complete setup including Capella cluster configuration
- iOS App README - iOS version of this app
- Web App README - Web version of this app
- Couchbase Lite Android Documentation
The repository contains significant amounts of code across various layers. For a developer specifically interested in Couchbase Lite, approximately 80% of the codebase consists of Android framework "noise" (UI, navigation, and theme boilerplate).
We provide guidance as to which parts of the code are of particular relevance.
These components manage the presentation and Android environment but contain no database logic:
ui/theme/*&MainActivity.kt: Application styling and standard Android permission handlingLandingScreen.kt& Navigation: Jetpack Compose routing between different app screensInventoryScreen.kt,GroceryItemCard.kt, &LoginScreen.kt: UI layouts and Compose states for displaying and interacting with data
The core database implementation is concentrated in these key files:
DatabaseManager.kt: The central orchestrator for the database lifecycle and reactive queriesAppServicesSyncManager.kt: Manages cloud synchronization with Couchbase Capella App ServicesMultipeerSyncManager.kt: Implements serverless P2P synchronizationAuthenticationManager.kt: Handles user sessions using a dedicated local database
The application uses a reactive pattern where data flows from the Couchbase Lite engine directly into the UI layers via Kotlin StateFlows.
DatabaseManager: Initializes Couchbase Lite and opens theGroceryInventoryDB. It manages dynamic data partitioning by opening collections (inventory,orders,profile) within store-specific scopes likeAA-StoreorNYC-Storebased on the user's login.AppServicesSyncManager: Configures and manages a continuous, bidirectionalReplicatorto sync local collections with a remote WebSocket endpoint in Couchbase CapellaMultipeerSyncManager: Uses theMultipeerReplicatorAPI to discover nearby devices via DNS-SD and sync data over a secure, TLS-encrypted mesh networkAuthenticationManager: Operates a standaloneAuthDBto persistuser_sessiondocuments. This allows user login states to persist across app restarts independently of the main inventory database
For developers new to this project, explore the source code in the following order to understand the data flow:
- Initialize:
DatabaseManager.kt. Learn how the engine and collections are opened - Authenticate:
AuthenticationManager.kt. See how simple local persistence works - Sync Cloud:
AppServicesSyncManager.kt. Review theReplicatorconfiguration - Sync P2P:
MultipeerSyncManager.kt. Understand serverless discovery and TLS security
This workflow demonstrates how a user action bridges the UI, the local database, and cloud synchronization.
-
UI Submission: A user enters a quantity in the
OrderFormDialogand clicks "Create Order" -
Manager Call: The UI triggers
databaseManager.createOrder(item, quantity). -
Local Persistence
- The
DatabaseManageraccesses theorderscollection for the active store scope - It generates a unique document ID using a NanoID-style algorithm
- A
MutableDocumentis created, populated with the order details, and saved locally viacollection.save()
- The
-
Sync Trigger: If cloud sync is enabled, the manager calls
pushDocumentImmediately(documentId) -
Transmission: The
AppServicesSyncManagerensures the continuous replicator detects the new local document and transmits it immediately to Capella
This diagram illustrates the factual path of an inventory update, from the user interface interaction through local persistence and out to the cloud.
-
User Trigger: The user interacts with the
GroceryItemCard, triggering theonQuantityChangedevent -
Screen Logic: The
InventoryScreenreceives the event and invokesdatabaseManager.updateQuantityWithSync() -
Sync-Aware Update: The
DatabaseManageridentifies the active sync mode (App Services) and prepares aMutableDocument -
Local Persistence: The manager updates the
stockQtyfield and removes legacy fields to prevent sync conflicts before callingcollection.save() -
Immediate Push: The manager explicitly triggers
pushDocumentImmediately()to ensure the change is prioritized by the replicato -
Cloud Transmission: The
AppSyncManagerpasses the change to the active continuous replicator for transmission to Couchbase Capella
This sequence illustrates the critical path from user credentials to a fully synchronized, store-specific database environment .
Sequence Breakdown:
-
Authentication & Store Mapping:
LoginScreentriggers the login.AuthManagerusesAppConfig.setStoreForUser()to dynamically update thescopeNameandsyncGatewayURLbased on the user's location (AA vs NYC) -
Background Handoff:
AuthManagerinvokesdatabaseManager.startSyncAfterLogin(). The manager launches a background coroutine to ensure the UI remains responsive during setup -
Scoped Resource Prep:
DatabaseManagerrunssetupIndexes()to create value indexes specifically within the new store's collections -
Replicator Activation:
AppSyncManagercleans up any existing replicators, builds a new configuration using the dynamicAppConfigcredentials, and starts a continuousPUSH_AND_PULLsync
The application implements a centralized cloud synchronization pattern through the AppServicesSyncManager, which orchestrates a Replicator to bridge local collections with Couchbase Capella. This implementation utilizes a ReplicatorConfiguration that targets a specific URLEndpoint and employs a BasicAuthenticator for secure communication.
The synchronization is configured as a PUSH_AND_PULL type and operates in a continuous, event-driven mode rather than relying on polling. This ensures that changes in the inventory, profile, and orders collections are synchronized in real-time. To maintain high responsiveness for critical actions, the DatabaseManager can trigger an explicit pushDocumentImmediately call, forcing the replicator to pick up local changes (such as a newly created replenishment order) and transmit them to App Services without delay.
The app utilizes the latest Couchbase Lite organizational structure to partition data dynamically.
- Logical Partitioning: Instead of just using the default database, the app organizes data into a specific
scopeName(e.g.,AA-StoreorNYC-Store) - Categorization: Within those scopes, it separates data into three distinct collections:
inventory,orders, andprofile. This reflects a production-ready multi-tenant or multi-location strategy
The codebase demonstrates how to use official Couchbase Lite KTX extensions to integrate with modern Android reactive patterns.
queryChangeFlow(): InDatabaseManager.getOrdersFlow(), the app uses this built-in extension to convert a Query into a Cold Flow.- Automatic Updates: This allows the UI to stay in sync with the database without manual polling or observer management
To ensure searches remain fast as the database grows (the app handles over 3,000 items), it utilizes native indexing.
IndexBuilder: TheDatabaseManagerprogrammatically creates value indexes for thenameandcategoryproperties within the inventory collection- Search Performance: These indexes are essential for the case-insensitive searches performed in
searchGrocery()
While many apps rely on "Last Write Wins," this project implements sophisticated custom resolution logic for distributed environments.
GroceryCRDTResolver: The app defines a customConflictResolverfor theMultipeerReplicator- Convergent Merging: This resolver specifically understands the PN-Counter structure, manually merging the "p" (positive) and "n" (negative) dictionaries from local and remote documents to ensure no inventory updates are lost during a sync conflict
For the serverless P2P mesh network, security is handled natively within the Couchbase SDK.
TLSIdentity: TheMultipeerSyncManagercreates or retrieves a self-signed TLS identity for the device.- Authenticated Discovery: It uses a
MultipeerCertificateAuthenticatorto validate peers before allowing them to join the mesh network



