Implement register() and FID-based registration with onRegistered / onUnregistered#9714
Implement register() and FID-based registration with onRegistered / onUnregistered#9714zwu52 wants to merge 5 commits intofeat/messaging-api-seriesfrom
Conversation
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
…llback (draft) Made-with: Cursor
- Restore copyright year to 2020; add JSDoc for FID-dedupe behavior - Serialize get FID + compare + notify to avoid duplicate callback on concurrent register() - Add lastNotifiedFid assertion and three-call FID-change test Made-with: Cursor
182879a to
39f546b
Compare
| @@ -0,0 +1,200 @@ | |||
| /** | |||
| * @license | |||
| * Copyright 2020 Google LLC | |||
There was a problem hiding this comment.
nit: the copyright on these new files should be 2026
| * limitations under the License. | ||
| */ | ||
|
|
||
| import { SubscriptionOptions } from '../interfaces/token-details'; |
There was a problem hiding this comment.
nit: Maybe rename this file to registration-details if easy
| // `FID_REGISTRATION_FAILED` to keep the error surface uniform. | ||
| // Best-effort extraction of error details; the main signal is response.ok / status. | ||
| try { | ||
| const responseData = (await response.json()) as ApiResponse; |
There was a problem hiding this comment.
If only this line could throw an error, can we just surround it with try-catch?
The current structure is a bit confusing.
| getEndpoint(firebaseDependencies.appConfig), | ||
| subscribeOptions | ||
| ); | ||
| } catch (err) { |
There was a problem hiding this comment.
Shall we retry a few times on a retriable error?
There was a problem hiding this comment.
implemented a exponential backup for max 3 times retry.
…lint Made-with: Cursor
| 'called before calling getToken() to ensure your VAPID key is used.' | ||
| 'called before calling getToken() to ensure your VAPID key is used.', | ||
| [ErrorCode.INVALID_ON_REGISTERED_HANDLER]: | ||
| 'No onRegistered callback handler was provided or registered. Call onRegistered() before register().' |
There was a problem hiding this comment.
| 'No onRegistered callback handler was provided or registered. Call onRegistered() before register().' | |
| 'No onRegistered callback handler was provided or registered. Implement onRegistered() before register().' |
| if (err instanceof Error) { | ||
| throw err; | ||
| } |
There was a problem hiding this comment.
Do we need this based on the above comment?
// Best-effort parse the body to extract `error.message`, but always fail with
// `FID_REGISTRATION_FAILED` to keep the error surface uniform.
| * For the new FID-based register path: | ||
| * - Create (or refresh) an FCM Web registration in the backend via CreateRegistration. | ||
| * - Use the FIS auth token produced by the installations instance (implicitly associated with FID). | ||
| * - Only rely on HTTP success/failure (do not depend on returned FCM token). |
There was a problem hiding this comment.
nit: It's unclear to me what "returned FCM token" means. Do you mean FID?
| import { arrayToBase64 } from './array-base64-translator'; | ||
|
|
||
| // https://github.com/firebase/firebase-js-sdk/blob/7857c212f944a2a9eb421fd4cb7370181bc034b5/packages/messaging/src/interfaces/token-details.ts | ||
| // https://github.com/firebase/firebase-js-sdk/blob/7857c212f944a2a9eb421fd4cb7370181bc034b5/packages/messaging/src/interfaces/registration-details.ts |
There was a problem hiding this comment.
Revert this change as the updated link is invalid. Same for the following changes.
| if (!navigator) { | ||
| throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_WINDOW); | ||
| } | ||
|
|
||
| if (Notification.permission === 'default') { | ||
| await Notification.requestPermission(); | ||
| } | ||
|
|
||
| if (Notification.permission !== 'granted') { | ||
| throw ERROR_FACTORY.create(ErrorCode.PERMISSION_BLOCKED); | ||
| } |
There was a problem hiding this comment.
Do we need unit tests to cover these logics?
Implements Phase 2 of FCM Web modernization: a new register() API that links the app to its Firebase Installation ID (FID) and delivers it via the onRegistered callback, plus onUnregistered for when a FID is deactivated. This supports moving from legacy FCM tokens to FID as the primary send target.
register(messaging, options?) ensures VAPID and service worker are set, gets the FID from Installations, and invokes onRegistered with it (same options as getToken). When register() is called multiple times, onRegistered is only invoked when the FID changes from the last notified value (or on first call). The “get FID → compare → notify” step is serialized so concurrent register() calls do not trigger duplicate callbacks for the same FID.
New surface: onRegistered(messaging, nextOrObserver) and onUnregistered(messaging, nextOrObserver) for subscribing to FID delivery and deactivation. Unit tests cover options passthrough, observer vs function handler, FID source, and the dedupe and three-call FID-change behavior. All 78 messaging tests pass.