# 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
```
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
chat_messages
Chat messages
```
**Referenced in AndroidManifest.xml:**
```xml
```
---
## 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`: `` (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