sojorn/sojorn_docs/legacy/FCM_SETUP_GUIDE.md
Patrick Britton 38653f5854 Sojorn Backend Finalization & Cleanup - Complete Migration from Supabase
##  Phase 1: Critical Feature Completion (Beacon Voting)
- Add VouchBeacon, ReportBeacon, RemoveBeaconVote methods to PostRepository
- Implement beacon voting HTTP handlers with confidence score calculations
- Register new beacon routes: /beacons/:id/vouch, /beacons/:id/report, /beacons/:id/vouch (DELETE)
- Auto-flag beacons at 5+ reports, confidence scoring (0.5 base + 0.1 per vouch)

##  Phase 2: Feed Logic & Post Distribution Integrity
- Verify unified feed logic supports all content types (Standard, Quips, Beacons)
- Ensure proper distribution: Profile Feed + Main/Home Feed for followers
- Beacon Map integration for location-based content
- Video content filtering for Quips feed

##  Phase 3: The Notification System
- Create comprehensive NotificationService with FCM integration
- Add CreateNotification method to NotificationRepository
- Implement smart deep linking: beacon_map, quip_feed, main_feed
- Trigger notifications for beacon interactions and cross-post comments
- Push notification logic with proper content type detection

##  Phase 4: The Great Supabase Purge
- Delete function_proxy.go and remove /functions/:name route
- Remove SupabaseURL, SupabaseKey from config.go
- Remove SupabaseID field from User model
- Clean all Supabase imports and dependencies
- Sanitize codebase of legacy Supabase references

##  Phase 5: Flutter Frontend Integration
- Implement vouchBeacon(), reportBeacon(), removeBeaconVote() in ApiService
- Replace TODO delay in video_comments_sheet.dart with actual publishComment call
- Fix compilation errors (named parameters, orphaned child properties)
- Complete frontend integration with Go API endpoints

##  Additional Improvements
- Fix compilation errors in threaded_comment_widget.dart (orphaned child property)
- Update video_comments_sheet.dart to use proper named parameters
- Comprehensive error handling and validation
- Production-ready notification system with deep linking

##  Migration Status: 100% Complete
- Backend: Fully migrated from Supabase to custom Go/Gin API
- Frontend: Integrated with new Go endpoints
- Notifications: Complete FCM integration with smart routing
- Database: Clean of all Supabase dependencies
- Features: All functionality preserved and enhanced

Ready for VPS deployment and production testing!
2026-01-30 09:24:31 -06:00

6 KiB

Firebase Cloud Messaging (FCM) Setup Guide

Overview

This guide will help you configure FCM push notifications for the Sojorn app. You need:

  1. VAPID Key - For web push notifications
  2. Firebase Service Account JSON - For server-side FCM API access

Step 1: Get Your VAPID Key from Firebase Console

  1. Go to Firebase Console
  2. Select your project: sojorn-a7a78
  3. Click the gear icon ⚙️ > Project Settings
  4. Go to the Cloud Messaging tab
  5. Scroll down to Web configuration
  6. Under Web Push certificates, you'll see your VAPID key pair
  7. If you don't have one, click Generate key pair
  8. Copy the Key pair (starts with B...)

Example VAPID Key format:

BNxS7_example_vapid_key_here_very_long_string_of_characters

Step 2: Get Your Firebase Service Account JSON

  1. Still in Firebase Console > Project Settings
  2. Go to the Service Accounts tab
  3. Click Generate new private key
  4. Click Generate key - this downloads a JSON file
  5. The file will be named something like: sojorn-a7a78-firebase-adminsdk-xxxxx-xxxxxxxxxx.json

Example JSON structure:

{
  "type": "service_account",
  "project_id": "sojorn-a7a78",
  "private_key_id": "abc123...",
  "private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
  "client_email": "firebase-adminsdk-xxxxx@sojorn-a7a78.iam.gserviceaccount.com",
  "client_id": "123456789...",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/..."
}

Step 3: Update Server Configuration (/opt/sojorn/.env)

SSH into your server:

ssh -i "C:\Users\Patrick\.ssh\mpls.pem" patrick@194.238.28.122

Edit the .env file:

sudo nano /opt/sojorn/.env

Add these lines (replace with your actual values):

# Firebase Cloud Messaging
FIREBASE_CREDENTIALS_FILE=/opt/sojorn/firebase-service-account.json
FIREBASE_WEB_VAPID_KEY=BNxS7_YOUR_ACTUAL_VAPID_KEY_HERE

Save and exit (Ctrl+X, Y, Enter)


Step 4: Upload Firebase Service Account JSON to Server

From your local machine, upload the JSON file:

scp -i "C:\Users\Patrick\.ssh\mpls.pem" "C:\path\to\sojorn-a7a78-firebase-adminsdk-xxxxx.json" patrick@194.238.28.122:/tmp/firebase-service-account.json

Then on the server, move it to the correct location:

ssh -i "C:\Users\Patrick\.ssh\mpls.pem" patrick@194.238.28.122
sudo mv /tmp/firebase-service-account.json /opt/sojorn/firebase-service-account.json
sudo chmod 600 /opt/sojorn/firebase-service-account.json
sudo chown patrick:patrick /opt/sojorn/firebase-service-account.json

Verify the file exists:

ls -la /opt/sojorn/firebase-service-account.json

Step 5: Update Flutter App with VAPID Key

The VAPID key needs to be hardcoded in the Flutter app (already done in the code changes below).


Step 6: Restart Go Backend

ssh -i "C:\Users\Patrick\.ssh\mpls.pem" patrick@194.238.28.122
cd /home/patrick/sojorn-backend
sudo systemctl restart sojorn-api
sudo systemctl status sojorn-api

Check logs for FCM initialization:

sudo journalctl -u sojorn-api -f --since "5 minutes ago"

You should see:

[INFO] PushService initialized successfully

If you see:

[WARN] Failed to initialize PushService

Check that:

  • The JSON file exists at /opt/sojorn/firebase-service-account.json
  • The file has correct permissions (600)
  • The JSON is valid (not corrupted)

Step 7: Test FCM Notifications

Test 1: Register FCM Token

  1. Open the Sojorn web app
  2. Open browser DevTools (F12) > Console
  3. Look for: FCM token registered (web): ...
  4. If you see "Web push is missing FIREBASE_WEB_VAPID_KEY", the VAPID key is not set

Test 2: Send a Test Notification

From your server, you can test sending a notification:

# Get a user's FCM token from database
sudo -u postgres psql sojorn -c "SELECT fcm_token FROM public.fcm_tokens LIMIT 1;"

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

Test 3: Verify in Database

Check that FCM tokens are being stored:

sudo -u postgres psql sojorn
SELECT user_id, platform, LEFT(fcm_token, 20) as token_preview, created_at 
FROM public.fcm_tokens 
ORDER BY created_at DESC 
LIMIT 5;

Troubleshooting

Issue: "Web push is missing FIREBASE_WEB_VAPID_KEY"

Solution: The VAPID key is not configured in the Flutter app. Make sure the code changes below are deployed.

Issue: "Failed to initialize PushService"

Possible causes:

  1. Firebase service account JSON file not found
  2. Invalid JSON file
  3. Wrong file path in .env

Check:

cat /opt/sojorn/.env | grep FIREBASE
ls -la /opt/sojorn/firebase-service-account.json
cat /opt/sojorn/firebase-service-account.json | jq .

Issue: Notifications not received

Check:

  1. Browser notification permissions granted
  2. FCM token registered (check console logs)
  3. Go backend logs show push being sent
  4. Database has FCM token for user

Current Configuration

Firebase Project: sojorn-a7a78 Project ID: sojorn-a7a78 Sender ID: 486753572104

Server Paths:

  • .env: /opt/sojorn/.env
  • Service Account JSON: /opt/sojorn/firebase-service-account.json
  • Go Backend: /home/patrick/sojorn-backend

Quick Reference Commands

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

# View .env
sudo cat /opt/sojorn/.env | grep FIREBASE

# Check service account file
ls -la /opt/sojorn/firebase-service-account.json

# Restart backend
sudo systemctl restart sojorn-api

# View logs
sudo journalctl -u sojorn-api -f

# Check FCM tokens in DB
sudo -u postgres psql sojorn -c "SELECT COUNT(*) FROM public.fcm_tokens;"