diff --git a/common/api-review/messaging-exp.api.md b/common/api-review/messaging-exp.api.md index c923c2e4b11..517e8acbdad 100644 --- a/common/api-review/messaging-exp.api.md +++ b/common/api-review/messaging-exp.api.md @@ -59,11 +59,6 @@ export interface NotificationPayload { export { Observer } -// Warning: (ae-internal-missing-underscore) The name "onBackgroundMessage" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export function onBackgroundMessage(messaging: FirebaseMessaging, nextOrObserver: NextFn | Observer): Unsubscribe; - // @public export function onMessage(messaging: FirebaseMessaging, nextOrObserver: NextFn | Observer): Unsubscribe; diff --git a/packages-exp/messaging-compat/src/messaging-compat.ts b/packages-exp/messaging-compat/src/messaging-compat.ts index 16f11162652..b54e61c798e 100644 --- a/packages-exp/messaging-compat/src/messaging-compat.ts +++ b/packages-exp/messaging-compat/src/messaging-compat.ts @@ -24,11 +24,12 @@ import { MessagePayload, deleteToken, getToken, - onBackgroundMessage, onMessage } from '@firebase/messaging-exp'; import { NextFn, Observer, Unsubscribe } from '@firebase/util'; +import { onBackgroundMessage } from '@firebase/messaging-exp/sw'; + export interface MessagingCompat { getToken(options?: { vapidKey?: string; @@ -88,19 +89,6 @@ function isSwSupported(): boolean { } export class MessagingCompatImpl implements MessagingCompat, _FirebaseService { - swRegistration?: ServiceWorkerRegistration; - vapidKey?: string; - - onBackgroundMessageHandler: - | NextFn - | Observer - | null = null; - - onMessageHandler: - | NextFn - | Observer - | null = null; - constructor(readonly app: AppCompat, readonly _delegate: FirebaseMessaging) { this.app = app; this._delegate = _delegate; diff --git a/packages-exp/messaging-compat/src/registerMessagingCompat.ts b/packages-exp/messaging-compat/src/registerMessagingCompat.ts index abe11de9ff8..0dbd5d1ceef 100644 --- a/packages-exp/messaging-compat/src/registerMessagingCompat.ts +++ b/packages-exp/messaging-compat/src/registerMessagingCompat.ts @@ -22,6 +22,7 @@ import { InstanceFactory } from '@firebase/component'; import firebase, { _FirebaseNamespace } from '@firebase/app-compat'; + import { MessagingCompatImpl } from './messaging-compat'; declare module '@firebase/component' { @@ -33,10 +34,19 @@ declare module '@firebase/component' { const messagingCompatFactory: InstanceFactory<'messaging-compat'> = ( container: ComponentContainer ) => { - return new MessagingCompatImpl( - container.getProvider('app-compat').getImmediate(), - container.getProvider('messaging-exp').getImmediate() - ); + if (!!navigator) { + // in window + return new MessagingCompatImpl( + container.getProvider('app-compat').getImmediate(), + container.getProvider('messaging-exp').getImmediate() + ); + } else { + // in sw + return new MessagingCompatImpl( + container.getProvider('app-compat').getImmediate(), + container.getProvider('messaging-sw-exp').getImmediate() + ); + } }; export function registerMessagingCompat(): void { diff --git a/packages-exp/messaging-compat/test/messaging-compat.test.ts b/packages-exp/messaging-compat/test/messaging-compat.test.ts index d948d2432cb..9c76fe1ce10 100644 --- a/packages-exp/messaging-compat/test/messaging-compat.test.ts +++ b/packages-exp/messaging-compat/test/messaging-compat.test.ts @@ -16,6 +16,7 @@ */ import * as messagingModule from '@firebase/messaging-exp'; +import * as messagingModuleInSw from '@firebase/messaging-exp/sw'; import { getFakeApp, getFakeModularMessaging } from './fakes'; @@ -33,7 +34,10 @@ describe('messagingCompat', () => { const getTokenStub = stub(messagingModule, 'getToken'); const deleteTokenStub = stub(messagingModule, 'deleteToken'); const onMessageStub = stub(messagingModule, 'onMessage'); - const onBackgroundMessageStub = stub(messagingModule, 'onBackgroundMessage'); + const onBackgroundMessageStub = stub( + messagingModuleInSw, + 'onBackgroundMessage' + ); it('routes messagingCompat.getToken to modular SDK', () => { void messagingCompat.getToken(); diff --git a/packages-exp/messaging-exp/src/api.ts b/packages-exp/messaging-exp/src/api.ts index 0963ae43f5a..3b47ec88c95 100644 --- a/packages-exp/messaging-exp/src/api.ts +++ b/packages-exp/messaging-exp/src/api.ts @@ -23,20 +23,12 @@ import { Unsubscribe, getModularInstance } from '@firebase/util'; -import { - onNotificationClick, - onPush, - onSubChange -} from './listeners/sw-listeners'; import { MessagingService } from './messaging-service'; -import { Provider } from '@firebase/component'; -import { ServiceWorkerGlobalScope } from './util/sw-types'; import { deleteToken as _deleteToken } from './api/deleteToken'; import { getToken as _getToken } from './api/getToken'; import { onBackgroundMessage as _onBackgroundMessage } from './api/onBackgroundMessage'; import { onMessage as _onMessage } from './api/onMessage'; -import { messageEventListener } from './listeners/window-listener'; /** * Retrieves a Firebase Cloud Messaging instance. @@ -48,45 +40,23 @@ import { messageEventListener } from './listeners/window-listener'; export function getMessagingInWindow( app: FirebaseApp = getApp() ): FirebaseMessaging { - app = getModularInstance(app); - const messagingProvider: Provider<'messaging-exp'> = _getProvider( - app, - 'messaging-exp' - ); - const messaging = messagingProvider.getImmediate(); - - navigator.serviceWorker.addEventListener('message', e => - messageEventListener(messaging as MessagingService, e) - ); - - return messaging; + return _getProvider(getModularInstance(app), 'messaging-exp').getImmediate(); } /** - * Retrieves a firebase messaging instance. + * Retrieves a Firebase Cloud Messaging instance. * - * @returns the firebase messaging instance associated with the provided firebase app. + * @returns The Firebase Cloud Messaging instance associated with the provided firebase app. * + * @public */ -declare const self: ServiceWorkerGlobalScope; -export function getMessagingInSw(app: FirebaseApp): FirebaseMessaging { - const messagingProvider: Provider<'messaging-exp'> = _getProvider( - app, - 'messaging-exp' - ); - const messaging = messagingProvider.getImmediate(); - - self.addEventListener('push', e => { - e.waitUntil(onPush(e, messaging as MessagingService)); - }); - self.addEventListener('pushsubscriptionchange', e => { - e.waitUntil(onSubChange(e, messaging as MessagingService)); - }); - self.addEventListener('notificationclick', e => { - e.waitUntil(onNotificationClick(e)); - }); - - return messagingProvider.getImmediate(); +export function getMessagingInSw( + app: FirebaseApp = getApp() +): FirebaseMessaging { + return _getProvider( + getModularInstance(app), + 'messaging-sw-exp' + ).getImmediate(); } /** @@ -172,8 +142,7 @@ export function onMessage( * * @returns To stop listening for messages execute this returned function * - * make it internal to hide it from the browser entry point. - * @internal + * @public */ export function onBackgroundMessage( messaging: FirebaseMessaging, diff --git a/packages-exp/messaging-exp/src/helpers/register.ts b/packages-exp/messaging-exp/src/helpers/register.ts index ed79d6513c9..edb2e81e32f 100644 --- a/packages-exp/messaging-exp/src/helpers/register.ts +++ b/packages-exp/messaging-exp/src/helpers/register.ts @@ -23,9 +23,16 @@ import { } from '@firebase/component'; import { ERROR_FACTORY, ErrorCode } from '../util/errors'; import { isSwSupported, isWindowSupported } from '../api/isSupported'; +import { + onNotificationClick, + onPush, + onSubChange +} from '../listeners/sw-listeners'; import { MessagingService } from '../messaging-service'; +import { ServiceWorkerGlobalScope } from '../util/sw-types'; import { _registerComponent } from '@firebase/app-exp'; +import { messageEventListener } from '../listeners/window-listener'; const WindowMessagingFactory: InstanceFactory<'messaging-exp'> = ( container: ComponentContainer @@ -44,13 +51,20 @@ const WindowMessagingFactory: InstanceFactory<'messaging-exp'> = ( throw ERROR_FACTORY.create(ErrorCode.INDEXED_DB_UNSUPPORTED); }); - return new MessagingService( + const messaging = new MessagingService( container.getProvider('app-exp').getImmediate(), container.getProvider('installations-exp-internal').getImmediate(), container.getProvider('analytics-internal') ); + + navigator.serviceWorker.addEventListener('message', e => + messageEventListener(messaging as MessagingService, e) + ); + + return messaging; }; +declare const self: ServiceWorkerGlobalScope; const SwMessagingFactory: InstanceFactory<'messaging-exp'> = ( container: ComponentContainer ) => { @@ -68,11 +82,23 @@ const SwMessagingFactory: InstanceFactory<'messaging-exp'> = ( throw ERROR_FACTORY.create(ErrorCode.INDEXED_DB_UNSUPPORTED); }); - return new MessagingService( + const messaging = new MessagingService( container.getProvider('app-exp').getImmediate(), container.getProvider('installations-exp-internal').getImmediate(), container.getProvider('analytics-internal') ); + + self.addEventListener('push', e => { + e.waitUntil(onPush(e, messaging as MessagingService)); + }); + self.addEventListener('pushsubscriptionchange', e => { + e.waitUntil(onSubChange(e, messaging as MessagingService)); + }); + self.addEventListener('notificationclick', e => { + e.waitUntil(onNotificationClick(e)); + }); + + return messaging; }; export function registerMessagingInWindow(): void { @@ -81,8 +107,13 @@ export function registerMessagingInWindow(): void { ); } +/** + * The messaging instance registered in sw is named differently than that of in client. This is + * because both `registerMessagingInWindow` and `registerMessagingInSw` would be called in + * `messaging-compat` and component with the same name can only be registered once. + */ export function registerMessagingInSw(): void { _registerComponent( - new Component('messaging-exp', SwMessagingFactory, ComponentType.PUBLIC) + new Component('messaging-sw-exp', SwMessagingFactory, ComponentType.PUBLIC) ); } diff --git a/packages-exp/messaging-exp/src/index.sw.ts b/packages-exp/messaging-exp/src/index.sw.ts index 47bd1aff8b2..0aa3d7130d9 100644 --- a/packages-exp/messaging-exp/src/index.sw.ts +++ b/packages-exp/messaging-exp/src/index.sw.ts @@ -25,7 +25,7 @@ export { isSwSupported as isSupported } from './api/isSupported'; declare module '@firebase/component' { interface NameServiceMapping { - 'messaging-exp': FirebaseMessaging; + 'messaging-sw-exp': FirebaseMessaging; } } diff --git a/packages-exp/messaging-exp/src/index.ts b/packages-exp/messaging-exp/src/index.ts index c82af63762b..f2a2e1ae202 100644 --- a/packages-exp/messaging-exp/src/index.ts +++ b/packages-exp/messaging-exp/src/index.ts @@ -30,8 +30,7 @@ export { getToken, deleteToken, onMessage, - getMessagingInWindow as getMessaging, - onBackgroundMessage + getMessagingInWindow as getMessaging } from './api'; export { isWindowSupported as isSupported } from './api/isSupported'; export * from './interfaces/public-types';