diff --git a/.changeset/cyan-rats-itch.md b/.changeset/cyan-rats-itch.md new file mode 100644 index 00000000000..5631b3a59dd --- /dev/null +++ b/.changeset/cyan-rats-itch.md @@ -0,0 +1,5 @@ +--- +'@firebase/messaging': patch +--- + +Revised token update logic to keep existing tokens during update failures, preventing unnecessary deletions for transient issues. diff --git a/packages/messaging/src/internals/token-manager.test.ts b/packages/messaging/src/internals/token-manager.test.ts index fd2bcf1105d..a8817327d35 100644 --- a/packages/messaging/src/internals/token-manager.test.ts +++ b/packages/messaging/src/internals/token-manager.test.ts @@ -128,38 +128,29 @@ describe('Token Manager', () => { expect(tokenFromDb).to.deep.equal(expectedTokenDetails); }); - it('deletes the token if the update fails', async () => { + it('retains the token upon update failure due to potential server error, allowing for future update attempts', async () => { // Arrange - // Change create time to be older than a week. - tokenDetails.createTime = Date.now() - 8 * 24 * 60 * 60 * 1000; // 8 days - + tokenDetails.createTime = Date.now() - 8 * 24 * 60 * 60 * 1000; // 8 days ago, triggering an update await dbSet(messaging.firebaseDependencies, tokenDetails); - - requestUpdateTokenStub.rejects(new Error('Update failed.')); + requestUpdateTokenStub.rejects(new Error('Temporary server error')); // Act await expect(getTokenInternal(messaging)).to.be.rejectedWith( - 'Update failed.' + 'Temporary server error' ); // Assert - const expectedTokenDetails: TokenDetails = { - ...tokenDetails, - createTime: Date.now() - }; + expect(requestUpdateTokenStub).to.have.been.called; + expect(requestDeleteTokenStub).not.to.have.been.called; // Verify delete was not called - expect(requestGetTokenStub).not.to.have.been.called; - expect(requestUpdateTokenStub).to.have.been.calledOnceWith( - messaging.firebaseDependencies, - expectedTokenDetails - ); - expect(requestDeleteTokenStub).to.have.been.calledOnceWith( - messaging.firebaseDependencies, - tokenDetails.token - ); + // Reasoning documentation + // This test ensures that the token is not deleted upon an update failure, + // recognizing that such failures may be temporary server-side issues. + // By not deleting the token, we allow the system to retry the update in the future, + // avoiding unnecessary token churn and preserving continuity for the user. const tokenFromDb = await dbGet(messaging.firebaseDependencies); - expect(tokenFromDb).to.be.undefined; + expect(tokenFromDb).to.not.be.null; // Ensure the token still exists }); }); diff --git a/packages/messaging/src/internals/token-manager.ts b/packages/messaging/src/internals/token-manager.ts index bac15a59c51..ca854c9cfd3 100644 --- a/packages/messaging/src/internals/token-manager.ts +++ b/packages/messaging/src/internals/token-manager.ts @@ -127,7 +127,6 @@ async function updateToken( await dbSet(messaging.firebaseDependencies, updatedTokenDetails); return updatedToken; } catch (e) { - await deleteTokenInternal(messaging); throw e; } }