WIP: new-activity notification #231
19
README.md
19
README.md
@@ -112,7 +112,24 @@ See [Logging Configuration Guide](doc/logging-configuration.md) for complete det
|
||||
|
||||
## Notification Debug Panel (dev builds)
|
||||
|
||||
In non-production bundles (for example `vite dev` or a Vite build whose mode is not `production`), the **Notification Debug Panel** at `/dev/notifications` helps you inspect pending notifications, trigger mock refreshes and wakeup pings, and review notification-related debug logs when working on local scheduling (including Capacitor). From the UI, open **Account**, enable **Show All General Advanced Functions**, then use the **Notification Debug Panel** link.
|
||||
In non-production bundles (for example `vite dev` or a Vite build whose mode is not `production`), the **Notification Debug Panel** at `/dev/notifications` helps you test notification registration, backend refresh, WAKEUP_PING handling, and local schedule inspection on native builds.
|
||||
|
||||
**Access:** **Account** → enable **Show All General Advanced Functions** → **Notification Debug Panel**.
|
||||
|
||||
Key configuration (independent settings):
|
||||
|
||||
- **Notification Backend URL** — which notification server receives API calls
|
||||
- **Test Mode** — `testMode` sent in JSON request bodies (default on)
|
||||
- **Skip JWT Authentication (Local Development Only)** — omit JWT headers for local unauthenticated backends (default off)
|
||||
|
||||
See [doc/notification-debug-panel.md](doc/notification-debug-panel.md) for controls, recommended settings (hosted test server vs local ngrok), and troubleshooting.
|
||||
|
||||
Platform-specific end-to-end guides:
|
||||
|
||||
- [doc/local-android-testing-ngrok.md](doc/local-android-testing-ngrok.md)
|
||||
- [doc/local-ios-testing-ngrok.md](doc/local-ios-testing-ngrok.md)
|
||||
|
||||
## Database Clearing (development)
|
||||
|
||||
### Quick Usage
|
||||
```bash
|
||||
|
||||
@@ -80,15 +80,16 @@ These blocks can be carried into `doc/local-android-testing-ngrok.md` (proposed
|
||||
- Non-production build required for Notification Debug Panel
|
||||
- Account → **Show All General Advanced Functions** → `/dev/notifications`
|
||||
- **Notification Backend URL**, **Save Backend URL**
|
||||
- `localStorage`: `notificationDebug.backendBaseUrl`, `notificationDebug.testMode`
|
||||
- Optional programmatic override via `@/services/notifications` (`setBackendBaseUrl`, `setTestMode`, `getNotificationApiBaseUrl`)
|
||||
- `localStorage`: `notificationDebug.backendBaseUrl`, `notificationDebug.testMode`, `notificationDebug.bypassAuth`
|
||||
- Optional programmatic override via `@/services/notifications` (`setBackendBaseUrl`, `setTestMode`, `setBypassAuth`, `getNotificationApiBaseUrl`)
|
||||
|
||||
### Debug panel usage (iOS §6 table, §8 “Two Simulate WAKEUP_PING buttons”)
|
||||
|
||||
| Control | Android relevance |
|
||||
|---------|-------------------|
|
||||
| Notification Backend URL | Same |
|
||||
| Test Mode | Same (`testMode: true` on API) |
|
||||
| Test Mode | Same (`testMode` in JSON body) |
|
||||
| Skip JWT Authentication | Same — explicit opt-in for unauthenticated local backends (default off) |
|
||||
| Register Token Now | Same (`POST /notifications/register`) |
|
||||
| Refresh Notifications | Same |
|
||||
| Simulate WAKEUP_PING (backend) | Same — isolates ngrok + refresh without FCM |
|
||||
|
||||
@@ -277,6 +277,8 @@ Before ngrok end-to-end testing, confirm:
|
||||
|
||||
The app normally calls `APP_SERVER` (from `VITE_APP_SERVER`). For local wakeup testing, override the notification API base URL without rebuilding.
|
||||
|
||||
For a full panel reference (configuration, authentication, and troubleshooting), see [notification-debug-panel.md](./notification-debug-panel.md).
|
||||
|
||||
### Open the panel
|
||||
|
||||
1. Use a **non-production** build (e.g. `build:android:dev` or `build:android:test`).
|
||||
@@ -287,15 +289,28 @@ The app normally calls `APP_SERVER` (from `VITE_APP_SERVER`). For local wakeup t
|
||||
|
||||
| Control | Purpose |
|
||||
|---------|---------|
|
||||
| **Notification Backend URL** | Paste ngrok HTTPS URL → **Save Backend URL** |
|
||||
| **Test Mode** | Sends `testMode: true` on register/refresh (default on when unset in storage) |
|
||||
| **Notification Backend URL** | Paste ngrok HTTPS URL → **Save Backend URL** (changes target server only) |
|
||||
| **Test Mode** | Sends `testMode: true/false` in register/refresh JSON bodies (default on when unset in storage) |
|
||||
| **Skip JWT Authentication (Local Development Only)** | When on, omits `Authorization` headers for local servers that accept unauthenticated requests (default **off**) |
|
||||
| **Register Token Now** | `POST /notifications/register` with current FCM token and `platform: "android"` |
|
||||
| **Refresh Notifications** | `POST /notifications/refresh` (same as post-wakeup flow) |
|
||||
| **Simulate WAKEUP_PING (Local)** | Calls refresh API directly (no FCM) — quick backend + ngrok test |
|
||||
| **Send Real WAKEUP_PING** | `POST /debug/send-wakeup` on the backend override URL; server sends a real FCM `WAKEUP_PING` to the panel’s current FCM token (see below) |
|
||||
| **Event Log** | Shared `[Notifications]` panel log (100 entries) |
|
||||
|
||||
Persistence: `localStorage` keys `notificationDebug.backendBaseUrl` and `notificationDebug.testMode` (`NotificationDebugConfig.ts`).
|
||||
Persistence: `localStorage` keys `notificationDebug.backendBaseUrl`, `notificationDebug.testMode`, and `notificationDebug.bypassAuth` (`NotificationDebugConfig.ts`).
|
||||
|
||||
### Authentication vs backend URL
|
||||
|
||||
These settings are **independent**:
|
||||
|
||||
- **Backend URL** — which server receives `/notifications/*` and `/debug/*` calls.
|
||||
- **Test Mode** — `testMode` field in JSON request bodies only.
|
||||
- **Skip JWT Authentication** — whether `Authorization: Bearer …` is sent (via `getNotificationApiHeaders()`).
|
||||
|
||||
For a **hosted shared test server** (for example `https://test-notify-api.timesafari.app`): set the backend URL, keep **Test Mode** on if the server requires it, and leave **Skip JWT Authentication** **off**. Ensure an active DID and endorser session exist in the app.
|
||||
|
||||
For **local ngrok / localhost**: set the backend URL to your tunnel or `http://127.0.0.1:PORT`. Enable **Skip JWT Authentication** only if your local **notification-wakeup-service** intentionally accepts unauthenticated requests.
|
||||
|
||||
### testMode
|
||||
|
||||
@@ -347,7 +362,7 @@ On a **successful end-to-end** run (HTTP success from the panel, then FCM delive
|
||||
[Notifications] Refresh completed (WAKEUP_PING) in …ms (scheduled N)
|
||||
```
|
||||
|
||||
Intermediate lines (e.g. `WAKEUP_PING received — will trigger refresh`, `Schedule replacement: …`, auth bypass messages) are normal. ngrok should also show a new `POST /notifications/refresh` after the push is handled.
|
||||
Intermediate lines (e.g. `WAKEUP_PING received — will trigger refresh`, `Schedule replacement: …`, `Using authenticated notification request` or auth bypass messages when **Skip JWT Authentication** is on) are normal. ngrok should also show a new `POST /notifications/refresh` after the push is handled.
|
||||
|
||||
#### Send Real WAKEUP_PING vs end-to-end success
|
||||
|
||||
@@ -363,11 +378,13 @@ From Chrome DevTools attached to the WebView (`chrome://inspect` → your app):
|
||||
import {
|
||||
setBackendBaseUrl,
|
||||
setTestMode,
|
||||
setBypassAuth,
|
||||
getNotificationApiBaseUrl,
|
||||
} from "@/services/notifications";
|
||||
|
||||
setBackendBaseUrl("https://abc123.ngrok-free.app");
|
||||
setTestMode(true);
|
||||
setBypassAuth(true); // local dev only — omit for hosted servers that require JWT
|
||||
getNotificationApiBaseUrl(); // → ngrok URL
|
||||
```
|
||||
|
||||
@@ -509,7 +526,7 @@ If wakeup works on a **Pixel** but fails on an OEM phone, assume battery policy
|
||||
2. Start **ngrok** and copy the HTTPS URL.
|
||||
3. Install a **non-production** Android build with `google-services.json` in place.
|
||||
4. Grant notification permission when prompted (or enable in Settings).
|
||||
5. Open **Notification Debug Panel** → paste ngrok URL → **Save Backend URL**; confirm **Test Mode** is on.
|
||||
5. Open **Notification Debug Panel** → paste ngrok URL → **Save Backend URL**; confirm **Test Mode** is on; enable **Skip JWT Authentication** only if your local backend accepts unauthenticated requests.
|
||||
6. Tap **Register Token Now** → confirm ngrok `POST /notifications/register` and `[Notifications] Token registration success` in Event Log / logcat.
|
||||
7. Tap **Refresh Notifications** → confirm `POST /notifications/refresh` and `Refresh completed in Nms (scheduled X)` in Event Log.
|
||||
8. Optional: tap **Simulate WAKEUP_PING (Local)** to verify ngrok + refresh without FCM.
|
||||
@@ -837,7 +854,7 @@ Structured checks for local ngrok + FCM testing. Each item lists **symptoms**, *
|
||||
|
||||
**Symptoms:** Event Log shows token registration failure; no FCM token in debug panel; ngrok has no `POST /notifications/register`; curl register fails.
|
||||
|
||||
**Likely causes:** Notification permission denied; missing `google-services.json`; Firebase package mismatch (`app.timesafari.app`); `VITE_FIREBASE_*` not in build; auth headers missing for register; duplicate-token skip.
|
||||
**Likely causes:** Notification permission denied; missing `google-services.json`; Firebase package mismatch (`app.timesafari.app`); `VITE_FIREBASE_*` not in build; JWT auth failure or **Skip JWT Authentication** mismatch with server expectations; duplicate-token skip.
|
||||
|
||||
**Verification:**
|
||||
|
||||
@@ -846,7 +863,7 @@ Structured checks for local ngrok + FCM testing. Each item lists **symptoms**, *
|
||||
3. Panel shows a token string before **Register Token Now**.
|
||||
4. ngrok inspect UI (`http://127.0.0.1:4040`) for register request status body.
|
||||
|
||||
**Fixes:** Grant permission and cold-start app; add `android/app/google-services.json` and rebuild; align Firebase Android app ID with Gradle `applicationId`; rebuild with correct `.env`; tap **Register Token Now** (forces re-register); fix DID/auth if register returns 401.
|
||||
**Fixes:** Grant permission and cold-start app; add `android/app/google-services.json` and rebuild; align Firebase Android app ID with Gradle `applicationId`; rebuild with correct `.env`; tap **Register Token Now** (forces re-register); for JWT-required servers, ensure active DID/endorser session and **Skip JWT Authentication** off; for local unauthenticated backends, enable **Skip JWT Authentication** (see [notification-debug-panel.md](./notification-debug-panel.md)).
|
||||
|
||||
---
|
||||
|
||||
@@ -985,7 +1002,7 @@ Compare with panel **Backend Status** and Event Log error text.
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `src/services/notifications/NotificationDebugConfig.ts` | Backend URL + testMode override |
|
||||
| `src/services/notifications/NotificationDebugConfig.ts` | Backend URL, testMode, and bypassAuth overrides |
|
||||
| `src/services/notifications/NotificationDebugEvents.ts` | Panel event log + `logNotification()` |
|
||||
| `src/services/notifications/notificationLog.ts` | Structured log helpers |
|
||||
| `src/services/notifications/NotificationService.ts` | `POST /notifications/register` |
|
||||
@@ -1007,6 +1024,7 @@ Compare with panel **Backend Status** and Event Log error text.
|
||||
- [notification-from-api-call.md](./notification-from-api-call.md)
|
||||
- [notification-permissions-and-rollovers.md](./notification-permissions-and-rollovers.md)
|
||||
- [BUILDING.md](../BUILDING.md) — Android build commands
|
||||
- [notification-debug-panel.md](./notification-debug-panel.md) — panel controls, authentication, troubleshooting
|
||||
- [Notification Debug Panel (README)](../README.md#notification-debug-panel-dev-builds)
|
||||
|
||||
For plugin-native behavior (exact alarms, Android pending inspector), see **daily-notification-plugin** documentation. For FCM payload format and `/debug/send-wakeup` contract, see **notification-wakeup-service**.
|
||||
|
||||
@@ -283,6 +283,8 @@ Before ngrok end-to-end testing, confirm:
|
||||
|
||||
The app normally calls `APP_SERVER` (from `VITE_APP_SERVER`). For local wakeup testing, override the notification API base URL without rebuilding.
|
||||
|
||||
For a full panel reference (configuration, authentication, and troubleshooting), see [notification-debug-panel.md](./notification-debug-panel.md).
|
||||
|
||||
### Open the panel
|
||||
|
||||
1. Use a **non-production** bundle (e.g. dev/test build).
|
||||
@@ -293,14 +295,28 @@ The app normally calls `APP_SERVER` (from `VITE_APP_SERVER`). For local wakeup t
|
||||
|
||||
| Control | Purpose |
|
||||
|---------|---------|
|
||||
| **Notification Backend URL** | Paste ngrok HTTPS URL → **Save Backend URL** |
|
||||
| **Test Mode** | Sends `testMode: true` on register/refresh (default on when unset in storage) |
|
||||
| **Notification Backend URL** | Paste ngrok HTTPS URL → **Save Backend URL** (changes target server only) |
|
||||
| **Test Mode** | Sends `testMode: true/false` in register/refresh JSON bodies (default on when unset in storage) |
|
||||
| **Skip JWT Authentication (Local Development Only)** | When on, omits `Authorization` headers for local servers that accept unauthenticated requests (default **off**) |
|
||||
| **Register Token Now** | `POST /notifications/register` with current FCM token |
|
||||
| **Refresh Notifications** | `POST /notifications/refresh` (same as post-wakeup flow) |
|
||||
| **Simulate WAKEUP_PING** | Calls refresh API directly (no FCM) — quick backend test |
|
||||
| **Simulate WAKEUP_PING (Local)** | Calls refresh API directly (no FCM) — quick backend test |
|
||||
| **Send Real WAKEUP_PING** | `POST /debug/send-wakeup`; server sends real FCM `WAKEUP_PING` (Android doc has full flow) |
|
||||
| **Event Log** | Shared `[Notifications]` panel log (100 entries) |
|
||||
|
||||
Persistence: `localStorage` keys `notificationDebug.backendBaseUrl` and `notificationDebug.testMode` (`NotificationDebugConfig.ts`).
|
||||
Persistence: `localStorage` keys `notificationDebug.backendBaseUrl`, `notificationDebug.testMode`, and `notificationDebug.bypassAuth` (`NotificationDebugConfig.ts`).
|
||||
|
||||
### Authentication vs backend URL
|
||||
|
||||
These settings are **independent**:
|
||||
|
||||
- **Backend URL** — which server receives notification API calls.
|
||||
- **Test Mode** — `testMode` field in JSON request bodies only.
|
||||
- **Skip JWT Authentication** — whether JWT `Authorization` headers are sent.
|
||||
|
||||
For a **hosted shared test server**: set the backend URL, keep **Test Mode** on if required, leave **Skip JWT Authentication** **off**, and ensure an active DID exists.
|
||||
|
||||
For **local ngrok**: set the backend URL; enable **Skip JWT Authentication** only if your local backend accepts unauthenticated requests.
|
||||
|
||||
### Programmatic override (optional)
|
||||
|
||||
@@ -310,11 +326,13 @@ From Safari Web Inspector or a dev console attached to the WebView:
|
||||
import {
|
||||
setBackendBaseUrl,
|
||||
setTestMode,
|
||||
setBypassAuth,
|
||||
getNotificationApiBaseUrl,
|
||||
} from "@/services/notifications";
|
||||
|
||||
setBackendBaseUrl("https://abc123.ngrok-free.app");
|
||||
setTestMode(true);
|
||||
setBypassAuth(true); // local dev only — omit for hosted servers that require JWT
|
||||
getNotificationApiBaseUrl(); // → ngrok URL
|
||||
```
|
||||
|
||||
@@ -502,7 +520,7 @@ Confirm parameters (token vs deviceId, auth headers) in that repo’s README or
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `src/services/notifications/NotificationDebugConfig.ts` | Backend URL + testMode override |
|
||||
| `src/services/notifications/NotificationDebugConfig.ts` | Backend URL, testMode, and bypassAuth overrides |
|
||||
| `src/services/notifications/NotificationDebugEvents.ts` | Panel event log + `logNotification()` |
|
||||
| `src/services/notifications/notificationLog.ts` | Structured log helpers |
|
||||
| `src/services/notifications/NotificationService.ts` | `POST /notifications/register` |
|
||||
@@ -515,6 +533,7 @@ Confirm parameters (token vs deviceId, auth headers) in that repo’s README or
|
||||
|
||||
## 13. Related docs
|
||||
|
||||
- [notification-debug-panel.md](./notification-debug-panel.md) — panel controls, authentication, troubleshooting
|
||||
- [Notification Debug Panel (README)](../README.md#notification-debug-panel-dev-builds)
|
||||
- [notification-system-overview.md](./notification-system-overview.md)
|
||||
- [notification-from-api-call.md](./notification-from-api-call.md)
|
||||
|
||||
193
doc/notification-debug-panel.md
Normal file
193
doc/notification-debug-panel.md
Normal file
@@ -0,0 +1,193 @@
|
||||
# Notification Debug Panel
|
||||
|
||||
**Created:** 2026-07-07
|
||||
**Audience:** Developers testing notification registration, refresh, and WAKEUP_PING flows on native (iOS/Android) dev builds.
|
||||
|
||||
The **Notification Debug Panel** is a dev-only UI for exercising the same notification orchestration paths the production app uses: FCM token registration, backend refresh, wakeup handling, and local schedule inspection. It does not duplicate scheduling logic.
|
||||
|
||||
---
|
||||
|
||||
## Access
|
||||
|
||||
1. Use a **non-production** build (for example `build:android:dev`, `build:ios:dev`, or `vite dev` with a non-`production` mode).
|
||||
2. Open **Account** → enable **Show All General Advanced Functions**.
|
||||
3. Open **Notification Debug Panel** (route `/dev/notifications`).
|
||||
|
||||
On native platforms, grant notification permission when prompted so FCM token registration and the debug actions work.
|
||||
|
||||
---
|
||||
|
||||
## Configuration (Backend Testing)
|
||||
|
||||
Settings persist in `localStorage` via `NotificationDebugConfig.ts`:
|
||||
|
||||
| Key | Default | Purpose |
|
||||
|-----|---------|---------|
|
||||
| `notificationDebug.backendBaseUrl` | *(unset — use `APP_SERVER`)* | Override which notification server receives API calls |
|
||||
| `notificationDebug.testMode` | `true` | Sent in JSON request bodies (`testMode: true/false`) |
|
||||
| `notificationDebug.bypassAuth` | `false` | When `true`, omit JWT `Authorization` headers on notification API calls |
|
||||
|
||||
All notification API requests (`/notifications/register`, `/notifications/refresh`, `/debug/send-wakeup`, etc.) obtain headers through `getNotificationApiHeaders()` in `notificationApiAuth.ts`.
|
||||
|
||||
### Notification Backend URL
|
||||
|
||||
Paste a base URL (no trailing slash) and tap **Save Backend URL**. This changes **only** which server the app calls (`getNotificationApiBaseUrl()`). It does **not** disable JWT authentication.
|
||||
|
||||
Leave empty to use the built-in default (`APP_SERVER` from `VITE_APP_SERVER`).
|
||||
|
||||
### Test Mode
|
||||
|
||||
When enabled (default if never saved), register and refresh requests include `"testMode": true` in the JSON body. The backend can use this to return dev-friendly schedules or route test traffic separately from production.
|
||||
|
||||
Test Mode is **independent of authentication**. It does not control whether `Authorization` headers are sent.
|
||||
|
||||
### Skip JWT Authentication (Local Development Only)
|
||||
|
||||
When **off** (default), the app resolves the active DID and sends `Authorization: Bearer …` on notification API calls.
|
||||
|
||||
When **on**, requests include only `Content-Type: application/json` — for local servers (localhost or ngrok) that intentionally accept unauthenticated notification requests during development.
|
||||
|
||||
Enable this **only** for local development backends that do not require JWT. Hosted shared test servers that require normal app authentication should leave this **off**.
|
||||
|
||||
The panel **Backend Status** section shows the active URL, `testMode`, and `bypassAuth` values.
|
||||
|
||||
---
|
||||
|
||||
## Recommended settings
|
||||
|
||||
### Hosted test server
|
||||
|
||||
Example: `https://test-notify-api.timesafari.app`
|
||||
|
||||
| Setting | Value |
|
||||
|---------|-------|
|
||||
| **Notification Backend URL** | `https://test-notify-api.timesafari.app` |
|
||||
| **Test Mode** | **ON** (if the server expects `testMode: true`) |
|
||||
| **Skip JWT Authentication** | **OFF** |
|
||||
|
||||
Ensure the app has an **active identity (DID)** with a valid endorser session so JWT headers can be built.
|
||||
|
||||
### Local localhost / ngrok development
|
||||
|
||||
Example: `https://abc123.ngrok-free.app` or `http://127.0.0.1:3000`
|
||||
|
||||
| Setting | Value |
|
||||
|---------|-------|
|
||||
| **Notification Backend URL** | Your local or ngrok URL |
|
||||
| **Test Mode** | **ON** or **OFF** — match what your local **notification-wakeup-service** expects |
|
||||
| **Skip JWT Authentication** | **ON** only if the local server accepts unauthenticated requests; **OFF** if it validates JWT like production |
|
||||
|
||||
---
|
||||
|
||||
## Backend Testing actions
|
||||
|
||||
| Action | What it does |
|
||||
|--------|----------------|
|
||||
| **Register Token Now** | `POST {backend}/notifications/register` with current FCM token, `deviceId`, `platform`, and `testMode`. Forces re-registration (bypasses duplicate-token skip). |
|
||||
| **Refresh Notifications** | `POST {backend}/notifications/refresh` — same path used after a real WAKEUP_PING. Applies returned schedule to the native plugin. |
|
||||
| **Simulate WAKEUP_PING (Local)** | Calls the refresh API directly (no FCM). Quick test of backend URL + auth + refresh parsing without push delivery. |
|
||||
| **Send Real WAKEUP_PING** | `POST {backend}/debug/send-wakeup`; server sends a real FCM data message with `data.type = "WAKEUP_PING"`. Exercises backend → FCM → Capacitor listener → refresh → reschedule. Background the app before expecting delivery. |
|
||||
|
||||
**Current FCM Token** displays the last token from Capacitor/Firebase registration. **Event Log** shows the last 100 `[Notifications]` messages (also visible in logcat / Xcode console on native).
|
||||
|
||||
---
|
||||
|
||||
## Other panel sections
|
||||
|
||||
| Section | Purpose |
|
||||
|---------|---------|
|
||||
| **Mock Timing Presets** | Interval for mock refresh timestamps (30 sec – 10 min). |
|
||||
| **Trigger Mock Refresh** | Applies synthetic future timestamps locally — no backend call. |
|
||||
| **Wakeup Ping Simulator** | Runs the production push handler with a synthetic `WAKEUP_PING` payload (no FCM, no backend). |
|
||||
| **Flood Test** | Runs 20 sequential mock refreshes (stress test). |
|
||||
| **Pending Notification Inspector** | Lists locally scheduled notifications (iOS; Android may show unavailable). |
|
||||
| **Clear Notifications** | Clears/cancels all plugin-scheduled notifications on native. |
|
||||
|
||||
---
|
||||
|
||||
## Programmatic override (optional)
|
||||
|
||||
From a WebView dev console (`chrome://inspect` on Android, Safari Web Inspector on iOS):
|
||||
|
||||
```javascript
|
||||
import {
|
||||
setBackendBaseUrl,
|
||||
setTestMode,
|
||||
setBypassAuth,
|
||||
getNotificationApiBaseUrl,
|
||||
} from "@/services/notifications";
|
||||
|
||||
setBackendBaseUrl("https://abc123.ngrok-free.app");
|
||||
setTestMode(true);
|
||||
setBypassAuth(true); // local dev only
|
||||
getNotificationApiBaseUrl();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### 401 Unauthorized (`registerToken failed: unauthorized`)
|
||||
|
||||
**Likely causes:** JWT required but **Skip JWT Authentication** is off and the session is missing or expired; or JWT sent but the server rejected it.
|
||||
|
||||
**Checks:**
|
||||
|
||||
1. Panel **Backend Status** → `bypassAuth: false` for hosted servers.
|
||||
2. App has an active DID and endorser login.
|
||||
3. Event Log: look for `Using authenticated notification request` vs `Using debug unauthenticated notification request`.
|
||||
4. For hosted test server: keep **Skip JWT Authentication** **OFF**.
|
||||
|
||||
**Fixes:** Sign in / restore identity; refresh endorser session; for local ngrok without JWT support, enable **Skip JWT Authentication**.
|
||||
|
||||
### `registerToken auth unavailable` / `Waiting for auth before registration`
|
||||
|
||||
The app deferred registration because JWT could not be built (no active DID or empty token) and **Skip JWT Authentication** is **off**.
|
||||
|
||||
**Fixes:** Complete identity setup in the app, or enable **Skip JWT Authentication** only for an intentionally unauthenticated local backend.
|
||||
|
||||
### Failed to fetch / network error
|
||||
|
||||
**Likely causes:** Backend down, wrong URL, stale ngrok tunnel, device offline, or TLS/certificate issues.
|
||||
|
||||
**Checks:** Panel **Backend Status** URL; `curl -sS "$URL/health"` from your machine; ngrok inspect UI for incoming requests.
|
||||
|
||||
**Fixes:** Restart backend and ngrok; **Save Backend URL** with the current HTTPS forwarding URL (no trailing slash).
|
||||
|
||||
### Backend unreachable / no requests in ngrok
|
||||
|
||||
Same as above. Confirm the **Active** URL in the panel matches your running tunnel or local server port.
|
||||
|
||||
### Register succeeds but Send Real WAKEUP_PING does not trigger refresh
|
||||
|
||||
**Real WAKEUP_PING success** only means the backend accepted the wakeup request and attempted FCM delivery. Missing `pushNotificationReceived` / `Refresh completed (WAKEUP_PING)` indicates an FCM delivery or background execution issue — not necessarily a bad wakeup API call.
|
||||
|
||||
**Checks:** App backgrounded (not force-stopped); FCM token matches registration; **Simulate WAKEUP_PING (Local)** works (isolates FCM from refresh API).
|
||||
|
||||
See platform-specific guides for extended ngrok and FCM workflows:
|
||||
|
||||
- [local-android-testing-ngrok.md](./local-android-testing-ngrok.md)
|
||||
- [local-ios-testing-ngrok.md](./local-ios-testing-ngrok.md)
|
||||
|
||||
---
|
||||
|
||||
## Key source files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `src/components/dev/NotificationDebugPanel.vue` | Dev UI |
|
||||
| `src/services/notifications/NotificationDebugConfig.ts` | Backend URL, testMode, bypassAuth persistence |
|
||||
| `src/services/notifications/notificationApiAuth.ts` | JWT vs unauthenticated headers |
|
||||
| `src/services/notifications/notificationApiDebugMode.ts` | Auth bypass gate |
|
||||
| `src/services/notifications/NotificationDebugService.ts` | Panel action handlers |
|
||||
| `src/services/notifications/NotificationService.ts` | `POST /notifications/register` |
|
||||
| `src/services/notifications/NativeNotificationService.ts` | `POST /notifications/refresh`, WAKEUP_PING handler |
|
||||
|
||||
---
|
||||
|
||||
## Related docs
|
||||
|
||||
- [notification-system-overview.md](./notification-system-overview.md)
|
||||
- [notification-from-api-call.md](./notification-from-api-call.md)
|
||||
- [local-android-testing-ngrok.md](./local-android-testing-ngrok.md)
|
||||
- [local-ios-testing-ngrok.md](./local-ios-testing-ngrok.md)
|
||||
Reference in New Issue
Block a user