# Push Notification Pitfalls (iOS PWA)

Captured from the Jul 9, 2026 shark game push notification debugging session.

## iOS Safari does NOT support PushManager in browser tabs

On iPhones, `PushManager` is only available when the web app is opened from the Home Screen as a standalone PWA (no URL bar, no browser chrome). Safari's browser tab does NOT expose it.

**Symptom:** `FAIL: No PushManager` when tapping "Enable Notifications" in Safari.

**Fix:** User must:
1. Tap Share icon -> "Add to Home Screen"
2. Open from home screen icon (fullscreen mode)
3. Push subscription now works via Apple Push Service (APNs endpoint: `web.push.apple.com`)

## Subscription to APNs requires the subscribe-noauth endpoint

The standard `POST /api/push/subscribe` requires JWT authentication. For test pages without login, create a separate `POST /api/push/subscribe-noauth` endpoint that stores subscriptions with `user_id: NULL` to avoid FK constraint failures.

## Database schema: user_id must be nullable

```sql
CREATE TABLE IF NOT EXISTS push_subscriptions (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id INTEGER,  -- NULL for no-auth subscriptions; FK to users.id otherwise
    endpoint TEXT NOT NULL UNIQUE,
    p256dh TEXT NOT NULL,
    auth TEXT NOT NULL,
    created_at TEXT DEFAULT (datetime('now'))
);
```

## Common backend errors

| Error | Cause | Fix |
|-------|-------|-----|
| `FOREIGN KEY constraint failed` | user_id=0 but no user.id=0 exists | Use NULL or valid FK |
| `{"sent":0}` | All push send attempts failed silently | Change `except: pass` to `except: print(f"Push failed: {e}")` |
| `name 'json' is not defined` | `import json` missing at top of server.py | Add `import json` to imports |
| `ModuleNotFoundError: pywebpush` | Installed in wrong venv | Install in the systemd service's venv, not system Python |
