Set Up the Mobile App Environment
In this part, we’ll create a modern Android app using Kotlin and Jetpack Compose for the UI, which will be used as boilerplate for the next module, where the app will talk to the backend (we previously created). The backend will talk to Vonage Verify.
Overview of the App Flow
The app will follow this flow:
- The user enters their phone number.
- The app sends the phone number to the backend (
POST /verification). - If Silent Authentication succeeds, the user is verified.
- If it fails (or isn’t available), the user is asked for the SMS code.
- The app sends the code to the backend (
POST /check-code). - The app shows the verification result.
Remember: The Android app never stores Vonage secrets. It only calls your backend.
Create the Android Project
Open Android Studio.
Click New Project → Empty Compose Activity.
Use these settings:
- Name:
Verify2FADemo - Language: Kotlin
- Minimum SDK: API 24 (Android 7.0)
- Name:
Click Finish and wait for Gradle sync to complete.
Set up Android Dependencies
Open app/build.gradle.kts and add (or update) the following dependencies.
dependencies {
// Jetpack Compose (UI)
implementation("androidx.activity:activity-compose:1.12.3")
implementation(platform("androidx.compose:compose-bom:2026.01.01"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.material3:material3")
// Networking + JSON parsing
implementation("com.squareup.okhttp3:okhttp:5.3.2")
implementation("com.google.code.gson:gson:2.13.2")
// Coroutines (we'll use these for background networking)
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2")
}
This is worth spelling out for readers who are new to mobile:
Compose libraries: Build UI with Kotlin functions instead of XML layouts (less boilerplate, easier to follow in a tutorial).
OkHttp: A reliable HTTP client for talking to your backend. (Android does not ship a “nice” modern HTTP client by default.)
Gson: Converts Kotlin/Java objects ↔ JSON so you don’t manually build JSON strings everywhere.
Coroutines: Android apps must not block the main thread. Coroutines let us do networking in the background and update UI safely.
After editing the file, click Sync Now.
Internet Permissions and Local Networking
In AndroidManifest.xml, add this inside the <manifest> tag:
Without this, Android will simply block all outbound network calls.
If you call a backend over plain http://... (not HTTPS), Android may block it depending on your target SDK / network security settings.
For local development, you can allow cleartext traffic by adding this to the <application> tag:
Store Backend Configuration in local.properties
Hardcoding URLs directly in Kotlin files is fragile and unsafe.
Instead, we’ll store the backend URL in local.properties, which is:
- Not committed to git
- Environment-specific
- Designed for local configuration
Open (or create) local.properties in the root of the Android project and add:
BACKEND_URL=http://your-backend-ip:3000
Next, we make this value available to the Android app via BuildConfig.
In app/build.gradle.kts, add:
android {
defaultConfig {
buildConfigField(
"String",
"BACKEND_URL",
"\"${project.findProperty("BACKEND_URL")}\""
)
}
}
Then Sync Gradle again. This generates:
BuildConfig.BACKEND_URL
which we can safely use in Kotlin code.
Getting Started with Silent Authentication
Silent Authentication takes quite a bit to understand. This tutorial shows you how to build an integration from scratch with Nodejs and Kotlin