fix: per-device push tokens, and an update prompt that actually clears - #308
Merged
Conversation
…logout Push stopped reaching a signed-in phone and never came back. Two causes: users.fcm_token_web held one token for the whole account, so signing in on a second device overwrote the first and signing out anywhere cleared it for every device. It is replaced by an fcm_tokens table with a row per browser; logout now removes only the token it names, and sends fan out to every device. The client then never recovered, because it skipped the POST whenever localStorage said the token was already synced. FCM returns the same token for the life of a browser install, so that cache never invalidated while the server value could change behind its back. It now posts on every load. Also: prune tokens FCM reports as Unregistered/SenderIdMismatch instead of swallowing the error, and log when a push is skipped for want of a token — that early return was silent, which is why the logs showed nothing at all. Signed-off-by: chattermate <admin@chattermate.chat>
Clicking Reload never applied the update, so the "new version available" toast came back on every page load until an unrelated manual refresh happened to activate the worker. One prompt per release is intended; an unclearable one is not. registerSW's updateSW ignores its reloadPage argument and only posts SKIP_WAITING, without awaiting activation, so it resolves within a tick. Reloading on that resolution beat the handshake every time: the document came back under the old worker with the new one still in `waiting`, and the next load re-dispatched `waiting`. Leave the refresh to the `controlling` listener registerSW arms just before calling onNeedRefresh, and keep a short fallback reload so a worker that never takes control cannot strand anyone on the old build. Signed-off-by: chattermate <admin@chattermate.chat>
Three issues from reviewing the branch: Logout awaited the push-unregister before clearing the session, and that waits on getSWRegistration(), which only settles after an 8s timeout when no worker is ready — so signing out appeared to hang. Bound it to 3s; giving up early is safe, since a browser with no ready worker cannot display a push anyway and the row is pruned on its next failed send. register() did check-then-insert. The client now posts on every app load, so two tabs opening together both insert and the loser hit the unique constraint, leaving that browser unregistered for the session. Retry against the winner's row instead. send_each rejects more than 500 messages outright, and pruning only reads responses from a successful call — so an account over that limit could never send or recover. Chunk the sends, carrying the token offset so dead tokens in later chunks still map to the right row. Signed-off-by: chattermate <admin@chattermate.chat>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Push notifications stopped reaching a signed-in phone and never came back. Two causes.
users.fcm_token_webheld one token for the whole account, so signing in on a second device overwrote the first one's token and signing out anywhere cleared it for every device. Replaced with anfcm_tokenstable, one row per browser: logout removes only the token it names, and sends fan out to every device. Tokens FCM reports as dead are now pruned instead of being swallowed, and a push skipped for want of a token is logged — that early return was silent, which is why the logs showed nothing.The client then never recovered, because it skipped the POST whenever localStorage said the token was already synced. FCM returns the same token for the life of a browser install, so that cache never invalidated while the server value could change behind its back. It now posts on every load, so devices that are already stuck fix themselves on their next visit.
Also in here: the "new version of ChatterMate is available" toast reappearing on every page load.
registerSW'supdateSWignores itsreloadPageargument and only posts SKIP_WAITING without awaiting activation, so the explicit reload beat the handshake — the page came back on the old worker with the new one still waiting. The reload belongs to registerSW's owncontrollinglistener.Deploy note: migration
fcm_tokens_per_device_001copies existing tokens across and then dropsusers.fcm_token_web, so the backend has to go out with it. Anyone currently seeing the update toast will get it once more with the old handler and need a single manual refresh before the fix takes effect.Related issues
Type of change
Checklist
git commit -s(see CONTRIBUTING.md)