# Android FCM Notifications - Troubleshooting Guide

## Issue: Chat notifications work on Web but not Android

### Current Status
- ✅ Web notifications working
- ✅ Android has `google-services.json` configured
- ✅ Android has FCM plugin in `build.gradle.kts`
- ✅ Android has notification permissions in `AndroidManifest.xml`
- ❓ Android FCM token registration status unknown

---

## Diagnostic Steps

### Step 1: Check Android Logs for FCM Token

Run the Android app with logging:
```bash
cd c:\Webs\Sojorn
.\run_dev.ps1
```

**In Android Studio or terminal, check logcat:**
```bash
adb logcat | findstr "FCM"
```

**Look for these log messages:**
```
[FCM] Initializing for platform: android
[FCM] Permission status: AuthorizationStatus.authorized
[FCM] Requesting token...
[FCM] Token registered (android): eXaMpLe...
[FCM] Syncing token with backend...
[FCM] Token synced with Go Backend successfully
[FCM] Initialization complete
```

### Step 2: Check for Common Errors

#### Error: "Token is null after getToken()"
**Cause:** Firebase not properly initialized or `google-services.json` mismatch

**Fix:**
1. Verify `google-services.json` package name matches:
   ```json
   "package_name": "com.gosojorn.app"
   ```
2. Check `build.gradle.kts` has:
   ```kotlin
   applicationId = "com.gosojorn.app"
   ```
3. Rebuild: `flutter clean && flutter pub get && flutter run`

#### Error: "Permission denied"
**Cause:** User denied notification permission or Android 13+ permission not requested

**Fix:**
1. Check `AndroidManifest.xml` has:
   ```xml
   <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
   ```
2. On Android 13+, permission must be requested at runtime
3. Uninstall and reinstall app to re-trigger permission prompt

#### Error: "Failed to initialize notifications"
**Cause:** Firebase plugin not properly initialized

**Fix:**
1. Check `android/build.gradle` (project level) has:
   ```gradle
   dependencies {
       classpath 'com.google.gms:google-services:4.4.0'
   }
   ```
2. Check `android/app/build.gradle.kts` has:
   ```kotlin
   plugins {
       id("com.google.gms.google-services")
   }
   ```

---

## Step 3: Verify Backend Receives Token

### Check Database for Android Tokens

SSH to server:
```bash
ssh -i "C:\Users\Patrick\.ssh\mpls.pem" patrick@194.238.28.122
```

Query database:
```bash
sudo -u postgres psql sojorn
```

```sql
-- Check for Android tokens
SELECT 
    user_id, 
    platform, 
    LEFT(fcm_token, 30) as token_preview, 
    created_at 
FROM public.fcm_tokens 
WHERE platform = 'android'
ORDER BY created_at DESC 
LIMIT 5;
```

**Expected output:**
```
user_id                              | platform | token_preview                  | created_at
-------------------------------------+----------+--------------------------------+-------------------
5568b545-5215-4734-875f-84b3106cd170 | android  | eXaMpLe_android_token_here...  | 2026-01-29 06:00
```

**If no Android tokens:**
- Token registration failed
- Token sync to backend failed
- Check Android logs for errors

---

## Step 4: Test Push Notification Manually

### Send Test Notification from Server

```bash
# Get an Android FCM token from database
sudo -u postgres psql sojorn -c "SELECT fcm_token FROM public.fcm_tokens WHERE platform = 'android' LIMIT 1;"
```

The Go backend automatically sends notifications when:
- Someone sends you a chat message
- Someone follows you
- Someone accepts your follow request

**Test by sending a chat message:**
1. Open app on Android device
2. Have another user (or web browser) send you a message
3. Check Android logs for: `[FCM] Foreground message received`

---

## Step 5: Check Notification Channel (Android 8+)

Android 8+ requires notification channels. Check `strings.xml`:

**File:** `android/app/src/main/res/values/strings.xml`
```xml
<resources>
    <string name="default_notification_channel_id">chat_messages</string>
    <string name="default_notification_channel_name">Chat messages</string>
</resources>
```

**Referenced in AndroidManifest.xml:**
```xml
<meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="@string/default_notification_channel_id" />
```

---

## Common Issues & Solutions

### Issue 1: "google-services.json not found"

**Symptoms:**
- Build fails with "File google-services.json is missing"
- FCM token is null

**Solution:**
```bash
# Verify file exists
ls sojorn_app/android/app/google-services.json

# If missing, download from Firebase Console:
# https://console.firebase.google.com/project/sojorn-a7a78/settings/general
# Click "Add app" > Android > Download google-services.json
```

### Issue 2: Package name mismatch

**Symptoms:**
- FCM token is null
- No errors in logs

**Solution:**
Verify all package names match:
1. `google-services.json`: `"package_name": "com.gosojorn.app"`
2. `build.gradle.kts`: `applicationId = "com.gosojorn.app"`
3. `AndroidManifest.xml`: `<manifest xmlns:android="...">` (no package attribute needed)

### Issue 3: Notification permission not granted

**Symptoms:**
- Log shows: `[FCM] Permission status: AuthorizationStatus.denied`
- No token generated

**Solution:**
```bash
# Uninstall app
adb uninstall com.gosojorn.app

# Reinstall and allow notification permission when prompted
flutter run
```

### Issue 4: Token generated but not synced to backend

**Symptoms:**
- Log shows: `[FCM] Token registered (android): ...`
- Log shows: `[FCM] Sync failed: ...`
- No token in database

**Solution:**
Check API endpoint exists:
```bash
# On server
sudo journalctl -u sojorn-api -f | grep "notifications/device"
```

Verify Go backend has the endpoint:
```go
// Should be in cmd/api/main.go
authorized.POST("/notifications/device", settingsHandler.RegisterFCMToken)
```

---

## Comparison: Web vs Android

### Web (Working ✅)
- Uses VAPID key for authentication
- Service worker handles background messages
- Token format: `d2n2ELGKel7yzPL3wZLGSe:APA91b...`

### Android (Troubleshooting ❓)
- Uses `google-services.json` for authentication
- Native Android handles background messages
- Token format: Different from web, longer
- Requires runtime permission on Android 13+

---

## Debug Checklist

Run through this checklist:

- [ ] `google-services.json` exists in `android/app/`
- [ ] Package name matches in all files
- [ ] `build.gradle.kts` has `google-services` plugin
- [ ] `AndroidManifest.xml` has `POST_NOTIFICATIONS` permission
- [ ] App has notification permission granted
- [ ] Android logs show FCM initialization
- [ ] Android logs show token generated
- [ ] Token appears in database `fcm_tokens` table
- [ ] Backend logs show notification being sent
- [ ] Android logs show notification received

---

## Next Steps

1. **Run the app with enhanced logging:**
   ```bash
   cd c:\Webs\Sojorn
   .\run_dev.ps1
   ```

2. **Monitor Android logs:**
   ```bash
   adb logcat | findstr "FCM"
   ```

3. **Look for the specific log messages:**
   - `[FCM] Initializing for platform: android`
   - `[FCM] Token registered (android): ...`
   - `[FCM] Token synced with Go Backend successfully`

4. **If token is null:**
   - Check `google-services.json` is correct
   - Verify package name matches
   - Rebuild: `flutter clean && flutter pub get && flutter run`

5. **If token generated but notifications not received:**
   - Check database has the token
   - Send a test message
   - Check backend logs for push notification being sent
   - Verify Android device has internet connection

---

## Files to Check

### Android Configuration
- `sojorn_app/android/app/google-services.json` - Firebase config
- `sojorn_app/android/app/build.gradle.kts` - Build configuration
- `sojorn_app/android/app/src/main/AndroidManifest.xml` - Permissions
- `sojorn_app/android/app/src/main/res/values/strings.xml` - Notification channel

### Flutter Code
- `sojorn_app/lib/services/notification_service.dart` - FCM initialization (now with enhanced logging)
- `sojorn_app/lib/main.dart` - App initialization

### Backend
- `go-backend/internal/services/push_service.go` - Push notification sender
- `go-backend/internal/handlers/settings_handler.go` - FCM token registration endpoint

---

## Quick Commands

```bash
# Check Android logs
adb logcat | findstr "FCM"

# Check if app is installed
adb shell pm list packages | findstr gosojorn

# Uninstall app
adb uninstall com.gosojorn.app

# Check notification settings
adb shell dumpsys notification | findstr gosojorn

# Check database for tokens
ssh -i "C:\Users\Patrick\.ssh\mpls.pem" patrick@194.238.28.122
sudo -u postgres psql sojorn -c "SELECT platform, COUNT(*) FROM fcm_tokens GROUP BY platform;"
```

---

## Expected Behavior

**When working correctly:**

1. App starts → `[FCM] Initializing for platform: android`
2. Permission requested → User grants → `[FCM] Permission status: AuthorizationStatus.authorized`
3. Token generated → `[FCM] Token registered (android): eXaMpLe...`
4. Token synced → `[FCM] Token synced with Go Backend successfully`
5. Message sent → Backend sends push → `[FCM] Foreground message received`
6. Notification appears in Android notification tray

---

## Contact & Support

If issues persist after following this guide:
1. Share Android logcat output (filtered for FCM)
2. Share database query results for `fcm_tokens` table
3. Share backend logs when sending notification
4. Verify Firebase Console shows Android app is active
