docs: document SQLite storage for FCM registrations
Update README and .env.example for the SQLite database location, schema overview, backup/WAL notes, and clarify that JSON data is not migrated.
This commit is contained in:
@@ -8,7 +8,8 @@ PORT=3003
|
||||
# If unset, uses Application Default Credentials (e.g. GOOGLE_APPLICATION_CREDENTIALS).
|
||||
# FIREBASE_SERVICE_ACCOUNT_JSON={"type":"service_account",...}
|
||||
|
||||
# Local persistence directory for registered FCM tokens (default: ./data)
|
||||
# Directory for the SQLite FCM registration database (default: ./data).
|
||||
# Creates fcm-tokens.sqlite (plus -wal/-shm while the process is running).
|
||||
# FCM_TOKEN_DATA_DIR=./data
|
||||
|
||||
# Set to "test-local" to bypass ethr JWT expiry verification in local dev only.
|
||||
|
||||
52
README.md
52
README.md
@@ -1,5 +1,7 @@
|
||||
A lightweight Express service that schedules and sends Firebase Cloud Messaging (FCM) push notifications to wake up registered devices.
|
||||
|
||||
Device registrations are stored in a local **SQLite** database (not JSON).
|
||||
|
||||
## Dev
|
||||
|
||||
```bash
|
||||
@@ -11,6 +13,8 @@ Here is one way to generate the contents: `cat your-downloaded-key.json | jq -c
|
||||
|
||||
Optionally set `ENDORSER_URL` if you are not using the default production Endorser API (`https://api.endorser.ch`).
|
||||
|
||||
Optionally set `FCM_TOKEN_DATA_DIR` if you want the SQLite database somewhere other than `./data`.
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
pnpm run dev
|
||||
@@ -18,6 +22,8 @@ pnpm run dev
|
||||
|
||||
The server starts on `http://localhost:3003` (or the port in `PORT`). Hot-reloads on file changes.
|
||||
|
||||
On first use, the service creates `FCM_TOKEN_DATA_DIR` (default `./data`) and the SQLite file `fcm-tokens.sqlite` with the required schema.
|
||||
|
||||
### Authentication
|
||||
|
||||
`POST /notifications/register` and `POST /notifications/refresh` require a Bearer JWT. After local JWT verification, the service checks the token with Endorser (`GET /api/report/rateLimits` on `ENDORSER_URL`). Registration and refresh continue only if Endorser accepts the JWT.
|
||||
@@ -26,6 +32,42 @@ The server starts on `http://localhost:3003` (or the port in `PORT`). Hot-reload
|
||||
|
||||
Set `NODE_ENV=test-local` in `.env` to bypass ethr JWT *expiry* verification during local development (this is separate from the `testMode` bypass above).
|
||||
|
||||
## Storage
|
||||
|
||||
### Database location
|
||||
|
||||
| Path | Description |
|
||||
|---|---|
|
||||
| `{FCM_TOKEN_DATA_DIR}/fcm-tokens.sqlite` | Primary SQLite database (default dir: `./data`) |
|
||||
| `{FCM_TOKEN_DATA_DIR}/fcm-tokens.sqlite-wal` | WAL journal (present while the process is running) |
|
||||
| `{FCM_TOKEN_DATA_DIR}/fcm-tokens.sqlite-shm` | Shared-memory file used with WAL mode |
|
||||
|
||||
`FCM_TOKEN_DATA_DIR` defaults to `./data` (relative to the process working directory). The `data/` directory is gitignored.
|
||||
|
||||
### Schema (high level)
|
||||
|
||||
Table `fcm_registrations` holds one row per registered device:
|
||||
|
||||
- Identity: `id`, `user_id`, `device_id`, `fcm_token`, `platform`
|
||||
- Flags: `test_mode`
|
||||
- Timestamps: `created_at`, `updated_at`, `last_notified_at`
|
||||
|
||||
Unique on `(user_id, device_id)`. Indexes also exist on `user_id`, `device_id`, `fcm_token`, and `(user_id, fcm_token)`.
|
||||
|
||||
The schema is created automatically on startup if the database or tables do not already exist.
|
||||
|
||||
### JSON → SQLite
|
||||
|
||||
There is **no automatic migration** from the old JSON file (`fcm-tokens.json`). That format is no longer used. If you still have a local `fcm-tokens.json` from earlier development, it is ignored; re-register devices or import data manually if you need it.
|
||||
|
||||
### Backup
|
||||
|
||||
Persist or back up the SQLite files under `FCM_TOKEN_DATA_DIR`:
|
||||
|
||||
1. Prefer stopping the service, then copy `fcm-tokens.sqlite` (and any `-wal` / `-shm` sidecars if present).
|
||||
2. Or, while the service is running, copy **all three** files (`fcm-tokens.sqlite`, `-wal`, `-shm`) together so the backup stays consistent under WAL mode.
|
||||
3. For Docker, mount a volume at the data directory (or set `FCM_TOKEN_DATA_DIR` to a mounted path) so registrations survive container recreation.
|
||||
|
||||
## Production
|
||||
|
||||
Runs TypeScript directly via `tsx` (no compile step).
|
||||
@@ -35,13 +77,19 @@ pnpm install --prod
|
||||
pnpm start
|
||||
```
|
||||
|
||||
Ensure `FCM_TOKEN_DATA_DIR` points at a durable location (or accept the default `./data` next to the process cwd).
|
||||
|
||||
Or with Docker:
|
||||
|
||||
```bash
|
||||
docker build --no-cache -t notify-wakeup-api:amd-$NOTIFY_WAKEUP_API_VERSION --platform linux/amd64 .
|
||||
docker run --env-file notify-wakeup-api.env -p 3003:3003 notify-wakeup-api
|
||||
docker run --env-file notify-wakeup-api.env -p 3003:3003 \
|
||||
-v notify-wakeup-data:/app/data \
|
||||
notify-wakeup-api
|
||||
```
|
||||
|
||||
Mount a volume over `/app/data` (or whatever path you set with `FCM_TOKEN_DATA_DIR`) so the SQLite database is not lost when the container is replaced.
|
||||
|
||||
Required environment variables:
|
||||
|
||||
| Variable | Description |
|
||||
@@ -49,4 +97,4 @@ Required environment variables:
|
||||
| `FIREBASE_SERVICE_ACCOUNT_JSON` | Inline service account JSON (one line). If unset, falls back to Application Default Credentials. |
|
||||
| `PORT` | HTTP port (default: `3003`). |
|
||||
| `ENDORSER_URL` | Endorser API base URL used for auth checks on register/refresh (default: `https://api.endorser.ch`). |
|
||||
| `FCM_TOKEN_DATA_DIR` | Directory for persisting registered FCM tokens (default: `./data`). |
|
||||
| `FCM_TOKEN_DATA_DIR` | Directory for the SQLite database file `fcm-tokens.sqlite` (default: `./data`). |
|
||||
|
||||
Reference in New Issue
Block a user