# 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