Files
Compass/android/README.md
2025-10-28 18:41:54 +01:00

361 lines
10 KiB
Markdown

# 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.
Right now it's just a webview wrapper around the web application, but in the future it may
contain native code as well.
/!\ This is still a work in progress, as google sign in does not work yet. Most of the issue is that Google doesn't allow to sign in inside the webview for security reasons.
We could sign in in a browser with signInWithRedirect and then redirect to the webview, but I haven't found a way to make it come back to the app and store the token.
We could also use a native sign in with SocialLogin, but it only runs on local assets, not on the webview that loads the remote sign-in page. So one way would be to force the webview to load the local assets, but it's not a clean solution and I haven't found a way to do it yet.
Third solution is to implement a native app, not using webview, in React Native.
If you can make it work, please contribute!
This document describes how to:
1. Build and run the web frontend and backend locally
2. Sync and build the Android WebView wrapper
3. Debug, sign, and publish the APK
4. Enable Google Sign-In and push notifications
---
## 1. Project Overview
The app is a Capacitor Android project that loads the deployed Next.js site (`https://compassmeet.com`) 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.
---
## 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
```bash
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:
```bash
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:
1. Open Android Studio.
2. Click on "Open an existing Android Studio project".
3. Navigate to the `android` folder in this repository and select it.
4. Wait for Android Studio to index the project and download any necessary dependencies.
5. Connect your Android device via USB or set up an Android emulator.
6. Click on the "Run" button (green play button) in Android Studio to build and run the application.
7. Select your device or emulator and click "OK".
8. 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
```bash
cd android
./gradlew assembleDebug
```
Outputs:
```
android/app/build/outputs/apk/debug/app-debug.apk
```
### Install on emulator
```bash
adb install -r app/build/outputs/apk/debug/app-debug.apk
```
### Release build (signed)
1. Generate a release keystore:
```bash
keytool -genkey -v -keystore release-key.keystore -alias compass \
-keyalg RSA -keysize 2048 -validity 10000
```
2. Add signing config to `android/app/build.gradle`
3. Build:
```bash
./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 com.compass.app
adb logcat | grep Capacitor
adb logcat | grep console
```
You can also add this inside `MainActivity.java`:
```java
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
Log.d("WebView", consoleMessage.message());
return true;
}
});
```
---
## 10. Deploy to Play Store
1. Sign the release APK or AAB.
2. Verify package name matches Firebase settings (`com.compass.app`).
3. Upload to Google Play Console.
4. Add Privacy Policy and content rating.
5. 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
```bash
# 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
```bash
# 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
* [Capacitor Docs](https://capacitorjs.com/docs)
* [Firebase Android Setup](https://firebase.google.com/docs/android/setup)
* [FCM HTTP API](https://firebase.google.com/docs/cloud-messaging/send-message)
* [Next.js Deployment](https://nextjs.org/docs/deployment)
# 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.gradle` files 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
1. Add a **Web app** → obtain `firebaseConfig`
2. Add an **Android app**
* Package name: `com.compass.app`
* Add your SHA-1 and SHA-256 fingerprints (see below)
* Download `google-services.json` and put it in:
```
android/app/google-services.json
```
### To get SHA-1 for debug keystore
```bash
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:
```ts
import { googleNativeLogin } from 'web/lib/service/android-push'
```
## 8. Push Notifications (FCM)
### Setup FCM
* Add Firebase Cloud Messaging to your project
* Include `google-services.json` under `android/app/`
* Add in `android/build.gradle`:
```gradle
classpath 'com.google.gms:google-services:4.3.15'
```
* Add at the bottom of `android/app/build.gradle`:
```gradle
apply plugin: 'com.google.gms.google-services'
```
### Test notification
```ts
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));
```
---