Compass Android WebView App
This folder contains the source code for the Android application of Compass. A hybrid mobile app built with Next.js (TypeScript) frontend, Firebase backend, and wrapped as a Capacitor WebView for Android. In the future it may contain native code as well.
This document describes how to:
- Build and run the web frontend and backend locally
- Sync and build the Android WebView wrapper
- Debug, sign, and publish the APK
- Enable Google Sign-In and push notifications
1. Project Overview
The app is a Capacitor Android project that loads the local Next.js assests inside a WebView.
During development, it can instead load the local frontend (http://10.0.2.2:3000) and backend (http://10.0.2.2:8088).
Firebase handles authentication and push notifications. Google Sign-In is supported natively in the WebView via the Capacitor Social Login plugin.
Project Structure
app/src/main/java/com/compass/app: Contains the Java/Kotlin source code for the Android application.app/src/main/res: Contains the resources for the application, such as layouts, strings, and images.app/build.gradle: The Gradle build file for the Android application module.build.gradle: The top-level Gradle build file for the project.AndroidManifest.xml: The manifest file that describes essential information about the application.
Why Local Is the Default
- Performance: Local assets load instantly, without network latency.
- Reliability: Works offline or in poor connectivity environments.
- App Store policy compliance: Apple and Google generally prefer that the main experience doesn’t depend on a remote site (for security, review, and performance reasons).
- Version consistency: The web bundle is versioned with the app, ensuring no breaking updates outside your control.
When Remote (No Local Assets) Is sometimes Used
Loading from a remote URL (e.g. https://compassmeet.com) is less common, but seen in a few cases:
- Internal enterprise apps where the WebView just wraps an existing web portal.
- Dynamic content or frequent updates where pushing a new web build every time through app stores would be too slow.
- To leverage the low latency of ISR and SSR. However, this approach requires:
- Careful handling of CORS, SSL, and login/session persistence.
- Compliance with Google Play policies (they may reject apps that are “just a webview of a website” unless there’s meaningful native integration).
A middle ground we use:
- The app ships with local assets for core functionality.
- The app fetches remote content or updates (e.g., via Capacitor Live Updates, Ionic Appflow).
2. Prerequisites
Required Software
| Tool | Version | Purpose |
|---|---|---|
| Node.js | 22+ | For building frontend/backend |
| yarn | latest | Package manager |
| Java | 21 | Required for Android Gradle plugin |
| Android Studio | latest | For building and signing APKs |
| Capacitor CLI | latest | Android bridge |
| OpenJDK | 21 | JDK for Gradle |
Environment Setup
sudo apt install openjdk-21-jdk
sudo update-alternatives --config java
# Select Java 21
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64
java -version
javac -version
3. Build and Run the Web App
yarn install
yarn build-web
Local mode
If you want the webview to load from your local web version of Compass, run the web app.
In root directory:
export NEXT_PUBLIC_LOCAL_ANDROID=1
yarn dev # or prod
- Runs Next.js frontend at
http://localhost:3000 - Runs backend at
http://10.0.2.2:8088
Deployed mode
If you want the webview to load from the deployed web version of Compass (like at www.compassmeet.com), no web app to run.
5. Android WebView App Setup
Install dependencies
cd android
./gradlew clean
Sync web files and native plugins with Android, for offline fallback. In root:
export NEXT_PUBLIC_LOCAL_ANDROID=1 # if running your local web Compass
yarn build-web # if you made changes to web app
npx cap sync android
Load from site
During local development, open Android Studio project and run the app on an emulator or your physical device. Note that right now you can't use a physical device for the local web version (10.0.2.2:3000 time out )
npx cap open android
Building the Application:
- Open Android Studio.
- Click on "Open an existing Android Studio project".
- Navigate to the
androidfolder in this repository and select it. - Wait for Android Studio to index the project and download any necessary dependencies.
- Connect your Android device via USB or set up an Android emulator.
- Click on the "Run" button (green play button) in Android Studio to build and run the application.
- Select your device or emulator and click "OK".
- The application should now build and launch on your device or emulator.
6. Building the APK
From Android Studio
- If you want to generate a signed APK for release, go to "Build" > "Generate Signed Bundle / APK..." and follow the prompts.
- Make sure to test the application thoroughly on different devices and Android versions to ensure compatibility.
Debug build
cd android
./gradlew assembleDebug
Outputs:
android/app/build/outputs/apk/debug/app-debug.apk
Install on emulator
adb install -r app/build/outputs/apk/debug/app-debug.apk
Release build (signed)
-
Generate a release keystore:
keytool -genkey -v -keystore release-key.keystore -alias compass \ -keyalg RSA -keysize 2048 -validity 10000 -
Add signing config to
android/app/build.gradle -
Build:
./gradlew assembleRelease
9. Debugging
Client logs from the emulator on Chrome can be accessed at:
chrome://inspect/#devices
Backend logs can be accessed from the output of yarn prod / dev like in the web application.
Java/Kotlin logs can be accessed via Android Studio's Logcat.
adb logcat | grep CompassApp
adb logcat | grep com.compassconnections.app
adb logcat | grep Capacitor
You can also add this inside MainActivity.java:
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
Log.d("WebView", consoleMessage.message());
return true;
}
});
10. Deploy to Play Store
- Sign the release APK or AAB.
- Verify package name matches Firebase settings (
com.compassconnections.app). - Upload to Google Play Console.
- Add Privacy Policy and content rating.
- Submit for review.
11. Common Issues
| Problem | Cause | Fix |
|---|---|---|
INSTALL_FAILED_UPDATE_INCOMPATIBLE |
Old APK signed with different key | Uninstall old app first |
Account reauth failed [16] |
Missing or incorrect SHA-1 in Firebase | Re-add SHA-1 of keystore |
| App opens in Firefox | Missing WebViewClient override |
Fix shouldOverrideUrlLoading |
| APK > 1 GB | Cached webpack artifacts included | Add .next/ and /public/cache to .gitignore and build excludes |
13. Local Development Workflow
# Terminal 1
export NEXT_PUBLIC_LOCAL_ANDROID=1
yarn dev # or prod
# Terminal 2: start frontend
export NEXT_PUBLIC_LOCAL_ANDROID=1
yarn build-web # if you made changes to web app
npx cap sync android
# Run on emulator or device
14. Deployment Workflow
# 1. Build web app for production
yarn build-web
# 2. Sync assets to Android
npx cap sync android
# 3. Build signed release APK in Android Studio
15. Resources
Useful Commands
- To build the project:
./gradlew assembleDebug - To run unit tests:
./gradlew test - To run instrumentation tests:
./gradlew connectedAndroidTest - To clean the project:
./gradlew clean - To install dependencies: Open Android Studio and it will handle dependencies automatically.
- To update dependencies: Modify the
build.gradlefiles and sync the project in Android Studio. - To generate a signed APK: Use the "Generate Signed Bundle / APK..." option in Android Studio.
- To lint the project:
./gradlew lint - To check for updates to the Android Gradle Plugin:
./gradlew dependencyUpdates - To run the application on a connected device or emulator:
./gradlew installDebug - To view the project structure: Use the "Project" view in Android Studio.
- To analyze the APK:
./gradlew analyzeRelease - To run ProGuard/R8:
./gradlew minifyRelease - To generate documentation:
./gradlew javadoc
One time setups
Was already done for Compass, so you only need to do the steps below if you create a project separated from Compass.
Configure Firebase
In Firebase Console
-
Add a Web app → obtain
firebaseConfig -
Add an Android app
-
Package name:
com.compassconnections.app -
Add your SHA-1 and SHA-256 fingerprints (see below)
-
Download
google-services.jsonand put it in:android/app/google-services.json
-
To get SHA-1 for debug keystore
keytool -list -v \
-keystore ~/.android/debug.keystore \
-alias androiddebugkey \
-storepass android \
-keypass android
Add both SHA-1 and SHA-256 to Firebase.
7. Google Sign-In (Web + Native)
In Firebase Console:
- Enable Google provider under Authentication → Sign-in method
- Add your Android SHA-1
- Add your Web OAuth client ID
In your code:
import { googleNativeLogin } from 'web/lib/service/android-push'
8. Push Notifications (FCM)
Setup FCM
-
Add Firebase Cloud Messaging to your project
-
Include
google-services.jsonunderandroid/app/ -
Add in
android/build.gradle:classpath 'com.google.gms:google-services:4.3.15' -
Add at the bottom of
android/app/build.gradle:apply plugin: 'com.google.gms.google-services'
Test notification
const message = {
notification: {
title: "Test Notification",
body: "Hello from Firebase Admin SDK"
},
token: "..."
};
initAdmin()
await admin.messaging().send(message)
.then(response => console.log("Successfully sent message:", response))
.catch(error => console.error("Error sending message:", error));