An empty alert token must not discard a VoIP token #187

Merged
paulhitt merged 2 commits from fix/half-registered-push-token into main 2026-09-10 11:30:23 +00:00
paulhitt commented 2026-09-10 11:29:50 +00:00 (Migrated from gitlab.com)

Diagnosed live: a call placed from Android reached /e2e/turn, an envelope was sent, and no push was ever attempted.

The chain. PushKit issues the VoIP token before APNs issues the alert token. The iOS upload closure sends PushRegistrar.shared.currentToken ?? "" — an empty alert token — beside a perfectly good voip_token. The route treated an empty token as "forget this device", deleted the row, and returned 200. The device then had no push row at all, so pushToDevices found nothing and never called Apple. No APNs error, because there was no APNs call.

The evidence lined up exactly: four /e2e/push/token calls today all returning 200, updated_at on both surviving rows still yesterday (the model has @Timestamp(on: .update), so a write would have moved it), call setup reaching /e2e/turn, and zero APNs errors in 24h.

Two changes. Deleting is gated on there being no VoIP token either, and neither token is overwritten with an empty string — so whichever half arrives second cannot wipe the half that arrived first.

This is the half that repairs existing installs without another build. The iOS side should also stop sending "" at all, which is a separate change and needs a release.

Tests: 697 swift-testing, 2 new XCTest, 0 failures.

Diagnosed live: a call placed from Android reached `/e2e/turn`, an envelope was sent, and **no push was ever attempted**. **The chain.** PushKit issues the VoIP token before APNs issues the alert token. The iOS upload closure sends `PushRegistrar.shared.currentToken ?? ""` — an empty alert token — beside a perfectly good `voip_token`. The route treated an empty `token` as "forget this device", deleted the row, and returned **200**. The device then had no push row at all, so `pushToDevices` found nothing and never called Apple. No APNs error, because there was no APNs call. **The evidence lined up exactly:** four `/e2e/push/token` calls today all returning 200, `updated_at` on both surviving rows still yesterday (the model has `@Timestamp(on: .update)`, so a write would have moved it), call setup reaching `/e2e/turn`, and zero APNs errors in 24h. **Two changes.** Deleting is gated on there being no VoIP token either, and neither token is overwritten with an empty string — so whichever half arrives second cannot wipe the half that arrived first. **This is the half that repairs existing installs without another build.** The iOS side should also stop sending `""` at all, which is a separate change and needs a release. Tests: 697 swift-testing, 2 new XCTest, 0 failures.
paulhitt commented 2026-09-10 11:30:23 +00:00 (Migrated from gitlab.com)

mentioned in commit bbd20df74d

mentioned in commit bbd20df74ddcdcecea780d0ca7c40956bb3f1ec8
paulhitt (Migrated from gitlab.com) merged commit bbd20df74d into main 2026-09-10 11:30:23 +00:00
Sign in to join this conversation.