# Firebase Cloud Messaging (FCM) Setup Guide Step-by-step guide to set up FCM for Alfred Mobile app with correct IAM permissions. ## Prerequisites - Google Cloud project with Firebase enabled - Android app registered with package name: `com.openclaw.alfred` - `google-services.json` downloaded and placed in `app/` directory ## Firebase Service Account Setup ### Step 1: Create Service Account 1. Go to **Google Cloud Console IAM**: - https://console.cloud.google.com/iam-admin/serviceaccounts?project=YOUR_PROJECT_ID 2. Click **"Create Service Account"** 3. **Service account details:** - Name: `alfred-fcm-server` - Description: `FCM service account for Alfred proxy notifications` - Click **Create and Continue** ### Step 2: Grant IAM Role **CRITICAL**: The service account needs the correct role for FCM HTTP v1 API. **Required Role:** - **Firebase Admin SDK Administrator Service Agent** (`roles/firebase.sdkAdminServiceAgent`) This role includes: - ✅ `cloudmessaging.messages.create` (required for sending FCM) - ✅ `firebase.projects.get` - ❌ NOT `firebasenotifications.*` (legacy API - wrong) **How to add the role:** 1. In the role selection dropdown, search: **"Firebase Admin SDK Administrator"** 2. Select: **"Firebase Admin SDK Administrator Service Agent"** 3. Click **Continue**, then **Done** ### Step 3: Download Service Account Key 1. Click on the service account you just created 2. Go to **Keys** tab 3. Click **Add Key** → **Create new key** 4. Choose **JSON** format 5. Click **Create** - downloads a JSON file 6. Save this file securely (e.g., `service-account.json`) ### Step 4: Enable Firebase Cloud Messaging API 1. Go to: https://console.cloud.google.com/apis/library/fcm.googleapis.com?project=YOUR_PROJECT_ID 2. Click **"Enable"** 3. Wait for activation (~30 seconds) ## Alfred Proxy Configuration ### Place Service Account Key ```bash cd ~/.openclaw/workspace/alfred-proxy cp ~/Downloads/your-service-account-key.json service-account.json chmod 600 service-account.json ``` ### Update .env (if needed) The proxy reads the service account from `service-account.json` automatically. No additional configuration needed. ### Verify Configuration ```bash # Check service account email matches grep "client_email" service-account.json # Should show: alfred-fcm-server@YOUR_PROJECT_ID.iam.gserviceaccount.com ``` ## Testing FCM Permissions ### Test 1: Send Notification via Proxy ```bash curl -X POST http://localhost:18790/api/notify \ -H "Content-Type: application/json" \ -d '{ "notificationType": "alarm", "title": "Test Alarm", "message": "Testing FCM permissions", "priority": "high", "sound": true, "vibrate": true }' ``` **Expected response:** ```json {"success":true,"clients":0,"fcm":1} ``` ### Test 2: Check Proxy Logs ```bash tail -f /tmp/alfred-proxy.log | grep fcm ``` **Success looks like:** ``` [fcm] Sending push notification to 1 registered device(s) [fcm] Successfully sent 1 message(s) ``` **Permission error looks like:** ``` [fcm] Error: Permission 'cloudmessaging.messages.create' denied ``` If you see the permission error, verify: 1. Service account has correct role (Firebase Admin SDK Administrator Service Agent) 2. FCM API is enabled 3. Service account key is fresh (regenerate if > 1 hour old) ## Common Issues ### Wrong Role: "Firebase Cloud Messaging Admin" **Problem:** This role gives `firebasenotifications.*` permissions (legacy API), not `cloudmessaging.*` (v1 API). **Solution:** Remove this role, add **"Firebase Admin SDK Administrator Service Agent"** instead. ### API Not Enabled **Problem:** FCM HTTP v1 API not enabled. **Solution:** ```bash # Enable via gcloud (if you have CLI installed) gcloud services enable fcm.googleapis.com --project=YOUR_PROJECT_ID # Or enable in console: # https://console.cloud.google.com/apis/library/fcm.googleapis.com ``` ### Token Not Persisted **Problem:** FCM tokens lost after proxy restarts. **Solution:** Already fixed! Tokens now persist to `fcm-tokens.json`. Verify: ```bash cat alfred-proxy/fcm-tokens.json ``` Should show registered tokens. If empty, reconnect the Alfred app. ## Architecture ``` Alfred App (Android) ↓ (on connect) {"type": "fcm.register", "token": "..."} ↓ Alfred Proxy - Saves to fcm-tokens.json - Loads on startup ↓ (when alarm triggered) Firebase Admin SDK - admin.messaging().sendEachForMulticast() - Requires: cloudmessaging.messages.create permission ↓ Firebase Cloud Messaging (Google) ↓ Alfred App (receives notification even when asleep) ``` ## Security Best Practices 1. **Never commit service account keys** to git - Already in `.gitignore`: `service-account.json` 2. **Restrict service account permissions** - Use minimal role: Firebase Admin SDK Administrator Service Agent - Don't use "Firebase Admin" (too broad) 3. **Rotate keys periodically** - Generate new key every 90 days - Delete old keys from service account 4. **File permissions** ```bash chmod 600 alfred-proxy/service-account.json ``` ## Verification Checklist After setup, verify: - [ ] Service account exists with correct name - [ ] Role: **Firebase Admin SDK Administrator Service Agent** - [ ] FCM API enabled in Google Cloud Console - [ ] Service account key downloaded and placed correctly - [ ] Proxy logs show: `[firebase] Firebase Admin SDK initialized` - [ ] Test notification succeeds: `[fcm] Successfully sent X message(s)` - [ ] Alfred app receives notification even when locked ## Next Steps Once FCM is working: 1. Set up alarms via cron jobs (see TOOLS.md) 2. Configure morning briefings 3. Test cross-device notifications 4. Monitor FCM quota (free tier: 10M messages/month) --- **Last Updated:** 2026-02-04 **Status:** ✅ Working with correct IAM role