fix(messaging): resolve getToken() when observed service worker becomes redundant - #10246
fix(messaging): resolve getToken() when observed service worker becomes redundant#10246chan-mai wants to merge 2 commits into
Conversation
🦋 Changeset detectedLatest commit: c9d81c2 The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Code Review
This pull request fixes an issue where getToken() intermittently fails with a service worker registration timeout. The waitForRegistrationActive function was refactored to resolve as soon as any active worker is present, follow replacement workers via the updatefound event, and transition to watching a new worker if the currently watched worker becomes redundant. Comprehensive unit tests were also added to verify these scenarios. I have no feedback to provide as there are no review comments.
Discussion
Fixes #10197.
getToken()intermittently fails with:even though the service worker registers and activates successfully.
Root cause
waitForRegistrationActive(added in #8661) captures a single worker(
registration.installing || registration.waiting) at call time and resolvesonly when that specific worker fires
statechange→'activated'.registerDefaultSwcallsregistration.update()immediately before awaitingwaitForRegistrationActive. When that update installs a replacement worker —common right after a redeploy, when the SW script or one of its
importScriptsdependencies changed — the originally observed workertransitions to
'redundant'and never fires'activated'. The promise thenhangs until the 10s timeout, even though the replacement worker activates
successfully in the meantime. The
'redundant'transition is never handled,so the call can neither recover nor fail fast.
Fix
waitForRegistrationActivenow:registration.activeis set, regardless of whichspecific worker reached the
'activated'state;updatefoundevent; andbecomes
'redundant'.All listeners and the timeout are cleaned up once the promise settles.
This also removes the previous immediate
'No incoming service worker found.'rejection: a worker can still arrive via
updatefoundafterregister()resolves, so the wait now relies on the existing timeout for the genuine
"nothing ever activates" case.
No public API changes.
Testing
@firebase/messagingtests pass.packages/messaging/src/helpers/registerDefaultSw.test.tscovering:worker becomes redundant (the regression, which previously timed out);
updatefound;API Changes
None