Skip to content

WebSocket Notifications System (SocialVibes)

This document describes the WebSocket + toast notification system added to SocialVibes, how to use it, how to extend it, and where to modify the code when scaling.


Overview

The system consists of:

  • FastAPI WebSocket server (backend) for real‑time push.
  • REST publish endpoint for sending toasts.
  • Optional shared secret auth for partner tools/CLI.
  • React Native client for WebSocket receive + toast UI.
  • Local per‑user notification history (AsyncStorage).
  • Optional Redis pub/sub mode for future horizontal scaling.

Backend Architecture

Key Files

fastapi/app/domains/websocket/
  ├── manager.py      # Connection manager + optional Redis pub/sub
  ├── routes.py       # /ws (socket) + /ws/toast (publish) + /ws/history
  └── schemas.py      # Pydantic payload models

WebSocket Endpoint

  • URL: ws://<host>/api/v1/ws?token=<FIREBASE_ID_TOKEN>
  • Requires Firebase token (auth is enforced for clients).

Publish Endpoint

  • URL: POST http://<host>/api/v1/ws/toast
  • Accepts JSON payload (see schema below)
  • Auth options:
  • JWT (Authorization: Bearer )
  • Shared secret header (X‑SV‑KEY: )

Payload Schema

{
  "title": "Minecraft Turnering",
  "teaser": "Starter om 10 minutter i Hal C",
  "description": "Tryk her for detaljer!",
  "image_url": "https://...",
  "action_url": "sv://event/123",
  "action_label": "Se aktivitet"
}

Config Settings (fastapi/.env)

WS_REDIS_ENABLED=false
WS_CONNECTION_THRESHOLD=100
WS_REDIS_CHANNEL=sv:ws:broadcast
WS_HISTORY_SIZE=0
WS_PUBLISH_SECRET=your-shared-secret
WS_PUBLISH_HEADER=X-SV-KEY

Notification History

Currently per‑user history is stored locally on the device using AsyncStorage. This means:

Each user sees their own notifications Persistent across app restarts No backend load Not shared across devices (yet)

If you want server‑side persistent history later, see “Scaling & Growth” below.


Frontend Architecture

WebSocket Client

frontend/src/core/ws/
  ├── types.ts              # Shared types (ToastPayload etc.)
  ├── useWebSocket.ts       # Native WS connection logic
  └── WebSocketProvider.tsx # Context provider + useWSEvent

Toast UI

frontend/src/core/components/toast/
  ├── EventToast.tsx        # Small banner toast
  └── EventDetailModal.tsx  # Large modal view

Notification History UI

frontend/src/core/state/notifications.store.ts
frontend/src/app/(tabs)/notifications.tsx

Header + Bell

frontend/src/app/(tabs)/_layout.tsx

Partner / CLI Publishing

To allow external partners or internal tools to publish without JWT, a shared secret is supported.

Header (default)

X-SV-KEY: your-shared-secret

Set in fastapi/.env:

WS_PUBLISH_SECRET=your-shared-secret

CLI Tool

Location:

/sv-cli
  ├── Program.cs
  └── sv-cli.csproj

Example:

dotnet run --project sv-cli -- toast \
  --url http://192.168.1.108:8080/api/v1 \
  --title "Minecraft Turnering" \
  --teaser "Starter om 10 minutter i Hal C" \
  --description "Tryk her for detaljer!" \
  --image-url "https://..." \
  --action-url "sv://event/123" \
  --action-label "Se aktivitet" \
  --secret your-shared-secret

Supported env vars:

SV_API_URL
SV_JWT
SV_PUBLISH_SECRET
SV_PUBLISH_HEADER

Scaling & Growth

1) Horizontal Scaling (multiple instances)

Enable Redis broadcast mode:

WS_REDIS_ENABLED=true

All instances publish to Redis, and each instance forwards to its local connections.

2) Per‑user server history (future)

Add a DB table:

notifications
  id
  user_id
  title
  teaser
  description
  image_url
  created_at
  read

Modify:

  • fastapi/app/domains/websocket/routes.py
  • write to DB on publish
  • new /ws/history that filters by user_id
  • Frontend: fetch history from API rather than AsyncStorage

3) More event types

Steps:

  1. Add to backend EventType enum in schemas.py
  2. Add new payload schema
  3. Add matching interface in frontend/src/core/ws/types.ts
  4. Add UI handler in WebSocketProvider or a new component

Summary of Where to Modify

Goal File(s)
Change toast payload fastapi/app/domains/websocket/schemas.py + frontend/src/core/ws/types.ts
Adjust toast UI frontend/src/core/components/toast/EventToast.tsx
Adjust modal UI frontend/src/core/components/toast/EventDetailModal.tsx
Add new event types schemas.py, types.ts, new UI handler
Change auth strategy fastapi/app/domains/websocket/routes.py
Add persistent history new DB layer + /ws/history endpoint
CLI behavior /sv-cli/Program.cs

Minimal + Scalable Summary

  • Minimal now: small set of files, no heavy dependencies, fast local WS.
  • Scalable later: Redis pub/sub + optional DB history + new event types.