No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.sw.esm2017.js 50KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265
  1. import '@firebase/installations';
  2. import { Component } from '@firebase/component';
  3. import { openDB, deleteDB } from 'idb';
  4. import { ErrorFactory, isIndexedDBAvailable, validateIndexedDBOpenable, getModularInstance } from '@firebase/util';
  5. import { _registerComponent, _getProvider, getApp } from '@firebase/app';
  6. /**
  7. * @license
  8. * Copyright 2019 Google LLC
  9. *
  10. * Licensed under the Apache License, Version 2.0 (the "License");
  11. * you may not use this file except in compliance with the License.
  12. * You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an "AS IS" BASIS,
  18. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. * See the License for the specific language governing permissions and
  20. * limitations under the License.
  21. */
  22. const DEFAULT_VAPID_KEY = 'BDOU99-h67HcA6JeFXHbSNMu7e2yNNu3RzoMj8TM4W88jITfq7ZmPvIM1Iv-4_l2LxQcYwhqby2xGpWwzjfAnG4';
  23. const ENDPOINT = 'https://fcmregistrations.googleapis.com/v1';
  24. /** Key of FCM Payload in Notification's data field. */
  25. const FCM_MSG = 'FCM_MSG';
  26. const CONSOLE_CAMPAIGN_ID = 'google.c.a.c_id';
  27. // Defined as in proto/messaging_event.proto. Neglecting fields that are supported.
  28. const SDK_PLATFORM_WEB = 3;
  29. const EVENT_MESSAGE_DELIVERED = 1;
  30. var MessageType$1;
  31. (function (MessageType) {
  32. MessageType[MessageType["DATA_MESSAGE"] = 1] = "DATA_MESSAGE";
  33. MessageType[MessageType["DISPLAY_NOTIFICATION"] = 3] = "DISPLAY_NOTIFICATION";
  34. })(MessageType$1 || (MessageType$1 = {}));
  35. /**
  36. * @license
  37. * Copyright 2018 Google LLC
  38. *
  39. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
  40. * in compliance with the License. You may obtain a copy of the License at
  41. *
  42. * http://www.apache.org/licenses/LICENSE-2.0
  43. *
  44. * Unless required by applicable law or agreed to in writing, software distributed under the License
  45. * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
  46. * or implied. See the License for the specific language governing permissions and limitations under
  47. * the License.
  48. */
  49. var MessageType;
  50. (function (MessageType) {
  51. MessageType["PUSH_RECEIVED"] = "push-received";
  52. MessageType["NOTIFICATION_CLICKED"] = "notification-clicked";
  53. })(MessageType || (MessageType = {}));
  54. /**
  55. * @license
  56. * Copyright 2017 Google LLC
  57. *
  58. * Licensed under the Apache License, Version 2.0 (the "License");
  59. * you may not use this file except in compliance with the License.
  60. * You may obtain a copy of the License at
  61. *
  62. * http://www.apache.org/licenses/LICENSE-2.0
  63. *
  64. * Unless required by applicable law or agreed to in writing, software
  65. * distributed under the License is distributed on an "AS IS" BASIS,
  66. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  67. * See the License for the specific language governing permissions and
  68. * limitations under the License.
  69. */
  70. function arrayToBase64(array) {
  71. const uint8Array = new Uint8Array(array);
  72. const base64String = btoa(String.fromCharCode(...uint8Array));
  73. return base64String.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
  74. }
  75. function base64ToArray(base64String) {
  76. const padding = '='.repeat((4 - (base64String.length % 4)) % 4);
  77. const base64 = (base64String + padding)
  78. .replace(/\-/g, '+')
  79. .replace(/_/g, '/');
  80. const rawData = atob(base64);
  81. const outputArray = new Uint8Array(rawData.length);
  82. for (let i = 0; i < rawData.length; ++i) {
  83. outputArray[i] = rawData.charCodeAt(i);
  84. }
  85. return outputArray;
  86. }
  87. /**
  88. * @license
  89. * Copyright 2019 Google LLC
  90. *
  91. * Licensed under the Apache License, Version 2.0 (the "License");
  92. * you may not use this file except in compliance with the License.
  93. * You may obtain a copy of the License at
  94. *
  95. * http://www.apache.org/licenses/LICENSE-2.0
  96. *
  97. * Unless required by applicable law or agreed to in writing, software
  98. * distributed under the License is distributed on an "AS IS" BASIS,
  99. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  100. * See the License for the specific language governing permissions and
  101. * limitations under the License.
  102. */
  103. const OLD_DB_NAME = 'fcm_token_details_db';
  104. /**
  105. * The last DB version of 'fcm_token_details_db' was 4. This is one higher, so that the upgrade
  106. * callback is called for all versions of the old DB.
  107. */
  108. const OLD_DB_VERSION = 5;
  109. const OLD_OBJECT_STORE_NAME = 'fcm_token_object_Store';
  110. async function migrateOldDatabase(senderId) {
  111. if ('databases' in indexedDB) {
  112. // indexedDb.databases() is an IndexedDB v3 API and does not exist in all browsers. TODO: Remove
  113. // typecast when it lands in TS types.
  114. const databases = await indexedDB.databases();
  115. const dbNames = databases.map(db => db.name);
  116. if (!dbNames.includes(OLD_DB_NAME)) {
  117. // old DB didn't exist, no need to open.
  118. return null;
  119. }
  120. }
  121. let tokenDetails = null;
  122. const db = await openDB(OLD_DB_NAME, OLD_DB_VERSION, {
  123. upgrade: async (db, oldVersion, newVersion, upgradeTransaction) => {
  124. var _a;
  125. if (oldVersion < 2) {
  126. // Database too old, skip migration.
  127. return;
  128. }
  129. if (!db.objectStoreNames.contains(OLD_OBJECT_STORE_NAME)) {
  130. // Database did not exist. Nothing to do.
  131. return;
  132. }
  133. const objectStore = upgradeTransaction.objectStore(OLD_OBJECT_STORE_NAME);
  134. const value = await objectStore.index('fcmSenderId').get(senderId);
  135. await objectStore.clear();
  136. if (!value) {
  137. // No entry in the database, nothing to migrate.
  138. return;
  139. }
  140. if (oldVersion === 2) {
  141. const oldDetails = value;
  142. if (!oldDetails.auth || !oldDetails.p256dh || !oldDetails.endpoint) {
  143. return;
  144. }
  145. tokenDetails = {
  146. token: oldDetails.fcmToken,
  147. createTime: (_a = oldDetails.createTime) !== null && _a !== void 0 ? _a : Date.now(),
  148. subscriptionOptions: {
  149. auth: oldDetails.auth,
  150. p256dh: oldDetails.p256dh,
  151. endpoint: oldDetails.endpoint,
  152. swScope: oldDetails.swScope,
  153. vapidKey: typeof oldDetails.vapidKey === 'string'
  154. ? oldDetails.vapidKey
  155. : arrayToBase64(oldDetails.vapidKey)
  156. }
  157. };
  158. }
  159. else if (oldVersion === 3) {
  160. const oldDetails = value;
  161. tokenDetails = {
  162. token: oldDetails.fcmToken,
  163. createTime: oldDetails.createTime,
  164. subscriptionOptions: {
  165. auth: arrayToBase64(oldDetails.auth),
  166. p256dh: arrayToBase64(oldDetails.p256dh),
  167. endpoint: oldDetails.endpoint,
  168. swScope: oldDetails.swScope,
  169. vapidKey: arrayToBase64(oldDetails.vapidKey)
  170. }
  171. };
  172. }
  173. else if (oldVersion === 4) {
  174. const oldDetails = value;
  175. tokenDetails = {
  176. token: oldDetails.fcmToken,
  177. createTime: oldDetails.createTime,
  178. subscriptionOptions: {
  179. auth: arrayToBase64(oldDetails.auth),
  180. p256dh: arrayToBase64(oldDetails.p256dh),
  181. endpoint: oldDetails.endpoint,
  182. swScope: oldDetails.swScope,
  183. vapidKey: arrayToBase64(oldDetails.vapidKey)
  184. }
  185. };
  186. }
  187. }
  188. });
  189. db.close();
  190. // Delete all old databases.
  191. await deleteDB(OLD_DB_NAME);
  192. await deleteDB('fcm_vapid_details_db');
  193. await deleteDB('undefined');
  194. return checkTokenDetails(tokenDetails) ? tokenDetails : null;
  195. }
  196. function checkTokenDetails(tokenDetails) {
  197. if (!tokenDetails || !tokenDetails.subscriptionOptions) {
  198. return false;
  199. }
  200. const { subscriptionOptions } = tokenDetails;
  201. return (typeof tokenDetails.createTime === 'number' &&
  202. tokenDetails.createTime > 0 &&
  203. typeof tokenDetails.token === 'string' &&
  204. tokenDetails.token.length > 0 &&
  205. typeof subscriptionOptions.auth === 'string' &&
  206. subscriptionOptions.auth.length > 0 &&
  207. typeof subscriptionOptions.p256dh === 'string' &&
  208. subscriptionOptions.p256dh.length > 0 &&
  209. typeof subscriptionOptions.endpoint === 'string' &&
  210. subscriptionOptions.endpoint.length > 0 &&
  211. typeof subscriptionOptions.swScope === 'string' &&
  212. subscriptionOptions.swScope.length > 0 &&
  213. typeof subscriptionOptions.vapidKey === 'string' &&
  214. subscriptionOptions.vapidKey.length > 0);
  215. }
  216. /**
  217. * @license
  218. * Copyright 2019 Google LLC
  219. *
  220. * Licensed under the Apache License, Version 2.0 (the "License");
  221. * you may not use this file except in compliance with the License.
  222. * You may obtain a copy of the License at
  223. *
  224. * http://www.apache.org/licenses/LICENSE-2.0
  225. *
  226. * Unless required by applicable law or agreed to in writing, software
  227. * distributed under the License is distributed on an "AS IS" BASIS,
  228. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  229. * See the License for the specific language governing permissions and
  230. * limitations under the License.
  231. */
  232. // Exported for tests.
  233. const DATABASE_NAME = 'firebase-messaging-database';
  234. const DATABASE_VERSION = 1;
  235. const OBJECT_STORE_NAME = 'firebase-messaging-store';
  236. let dbPromise = null;
  237. function getDbPromise() {
  238. if (!dbPromise) {
  239. dbPromise = openDB(DATABASE_NAME, DATABASE_VERSION, {
  240. upgrade: (upgradeDb, oldVersion) => {
  241. // We don't use 'break' in this switch statement, the fall-through behavior is what we want,
  242. // because if there are multiple versions between the old version and the current version, we
  243. // want ALL the migrations that correspond to those versions to run, not only the last one.
  244. // eslint-disable-next-line default-case
  245. switch (oldVersion) {
  246. case 0:
  247. upgradeDb.createObjectStore(OBJECT_STORE_NAME);
  248. }
  249. }
  250. });
  251. }
  252. return dbPromise;
  253. }
  254. /** Gets record(s) from the objectStore that match the given key. */
  255. async function dbGet(firebaseDependencies) {
  256. const key = getKey(firebaseDependencies);
  257. const db = await getDbPromise();
  258. const tokenDetails = (await db
  259. .transaction(OBJECT_STORE_NAME)
  260. .objectStore(OBJECT_STORE_NAME)
  261. .get(key));
  262. if (tokenDetails) {
  263. return tokenDetails;
  264. }
  265. else {
  266. // Check if there is a tokenDetails object in the old DB.
  267. const oldTokenDetails = await migrateOldDatabase(firebaseDependencies.appConfig.senderId);
  268. if (oldTokenDetails) {
  269. await dbSet(firebaseDependencies, oldTokenDetails);
  270. return oldTokenDetails;
  271. }
  272. }
  273. }
  274. /** Assigns or overwrites the record for the given key with the given value. */
  275. async function dbSet(firebaseDependencies, tokenDetails) {
  276. const key = getKey(firebaseDependencies);
  277. const db = await getDbPromise();
  278. const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
  279. await tx.objectStore(OBJECT_STORE_NAME).put(tokenDetails, key);
  280. await tx.done;
  281. return tokenDetails;
  282. }
  283. /** Removes record(s) from the objectStore that match the given key. */
  284. async function dbRemove(firebaseDependencies) {
  285. const key = getKey(firebaseDependencies);
  286. const db = await getDbPromise();
  287. const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
  288. await tx.objectStore(OBJECT_STORE_NAME).delete(key);
  289. await tx.done;
  290. }
  291. function getKey({ appConfig }) {
  292. return appConfig.appId;
  293. }
  294. /**
  295. * @license
  296. * Copyright 2017 Google LLC
  297. *
  298. * Licensed under the Apache License, Version 2.0 (the "License");
  299. * you may not use this file except in compliance with the License.
  300. * You may obtain a copy of the License at
  301. *
  302. * http://www.apache.org/licenses/LICENSE-2.0
  303. *
  304. * Unless required by applicable law or agreed to in writing, software
  305. * distributed under the License is distributed on an "AS IS" BASIS,
  306. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  307. * See the License for the specific language governing permissions and
  308. * limitations under the License.
  309. */
  310. const ERROR_MAP = {
  311. ["missing-app-config-values" /* ErrorCode.MISSING_APP_CONFIG_VALUES */]: 'Missing App configuration value: "{$valueName}"',
  312. ["only-available-in-window" /* ErrorCode.AVAILABLE_IN_WINDOW */]: 'This method is available in a Window context.',
  313. ["only-available-in-sw" /* ErrorCode.AVAILABLE_IN_SW */]: 'This method is available in a service worker context.',
  314. ["permission-default" /* ErrorCode.PERMISSION_DEFAULT */]: 'The notification permission was not granted and dismissed instead.',
  315. ["permission-blocked" /* ErrorCode.PERMISSION_BLOCKED */]: 'The notification permission was not granted and blocked instead.',
  316. ["unsupported-browser" /* ErrorCode.UNSUPPORTED_BROWSER */]: "This browser doesn't support the API's required to use the Firebase SDK.",
  317. ["indexed-db-unsupported" /* ErrorCode.INDEXED_DB_UNSUPPORTED */]: "This browser doesn't support indexedDb.open() (ex. Safari iFrame, Firefox Private Browsing, etc)",
  318. ["failed-service-worker-registration" /* ErrorCode.FAILED_DEFAULT_REGISTRATION */]: 'We are unable to register the default service worker. {$browserErrorMessage}',
  319. ["token-subscribe-failed" /* ErrorCode.TOKEN_SUBSCRIBE_FAILED */]: 'A problem occurred while subscribing the user to FCM: {$errorInfo}',
  320. ["token-subscribe-no-token" /* ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN */]: 'FCM returned no token when subscribing the user to push.',
  321. ["token-unsubscribe-failed" /* ErrorCode.TOKEN_UNSUBSCRIBE_FAILED */]: 'A problem occurred while unsubscribing the ' +
  322. 'user from FCM: {$errorInfo}',
  323. ["token-update-failed" /* ErrorCode.TOKEN_UPDATE_FAILED */]: 'A problem occurred while updating the user from FCM: {$errorInfo}',
  324. ["token-update-no-token" /* ErrorCode.TOKEN_UPDATE_NO_TOKEN */]: 'FCM returned no token when updating the user to push.',
  325. ["use-sw-after-get-token" /* ErrorCode.USE_SW_AFTER_GET_TOKEN */]: 'The useServiceWorker() method may only be called once and must be ' +
  326. 'called before calling getToken() to ensure your service worker is used.',
  327. ["invalid-sw-registration" /* ErrorCode.INVALID_SW_REGISTRATION */]: 'The input to useServiceWorker() must be a ServiceWorkerRegistration.',
  328. ["invalid-bg-handler" /* ErrorCode.INVALID_BG_HANDLER */]: 'The input to setBackgroundMessageHandler() must be a function.',
  329. ["invalid-vapid-key" /* ErrorCode.INVALID_VAPID_KEY */]: 'The public VAPID key must be a string.',
  330. ["use-vapid-key-after-get-token" /* ErrorCode.USE_VAPID_KEY_AFTER_GET_TOKEN */]: 'The usePublicVapidKey() method may only be called once and must be ' +
  331. 'called before calling getToken() to ensure your VAPID key is used.'
  332. };
  333. const ERROR_FACTORY = new ErrorFactory('messaging', 'Messaging', ERROR_MAP);
  334. /**
  335. * @license
  336. * Copyright 2019 Google LLC
  337. *
  338. * Licensed under the Apache License, Version 2.0 (the "License");
  339. * you may not use this file except in compliance with the License.
  340. * You may obtain a copy of the License at
  341. *
  342. * http://www.apache.org/licenses/LICENSE-2.0
  343. *
  344. * Unless required by applicable law or agreed to in writing, software
  345. * distributed under the License is distributed on an "AS IS" BASIS,
  346. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  347. * See the License for the specific language governing permissions and
  348. * limitations under the License.
  349. */
  350. async function requestGetToken(firebaseDependencies, subscriptionOptions) {
  351. const headers = await getHeaders(firebaseDependencies);
  352. const body = getBody(subscriptionOptions);
  353. const subscribeOptions = {
  354. method: 'POST',
  355. headers,
  356. body: JSON.stringify(body)
  357. };
  358. let responseData;
  359. try {
  360. const response = await fetch(getEndpoint(firebaseDependencies.appConfig), subscribeOptions);
  361. responseData = await response.json();
  362. }
  363. catch (err) {
  364. throw ERROR_FACTORY.create("token-subscribe-failed" /* ErrorCode.TOKEN_SUBSCRIBE_FAILED */, {
  365. errorInfo: err === null || err === void 0 ? void 0 : err.toString()
  366. });
  367. }
  368. if (responseData.error) {
  369. const message = responseData.error.message;
  370. throw ERROR_FACTORY.create("token-subscribe-failed" /* ErrorCode.TOKEN_SUBSCRIBE_FAILED */, {
  371. errorInfo: message
  372. });
  373. }
  374. if (!responseData.token) {
  375. throw ERROR_FACTORY.create("token-subscribe-no-token" /* ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN */);
  376. }
  377. return responseData.token;
  378. }
  379. async function requestUpdateToken(firebaseDependencies, tokenDetails) {
  380. const headers = await getHeaders(firebaseDependencies);
  381. const body = getBody(tokenDetails.subscriptionOptions);
  382. const updateOptions = {
  383. method: 'PATCH',
  384. headers,
  385. body: JSON.stringify(body)
  386. };
  387. let responseData;
  388. try {
  389. const response = await fetch(`${getEndpoint(firebaseDependencies.appConfig)}/${tokenDetails.token}`, updateOptions);
  390. responseData = await response.json();
  391. }
  392. catch (err) {
  393. throw ERROR_FACTORY.create("token-update-failed" /* ErrorCode.TOKEN_UPDATE_FAILED */, {
  394. errorInfo: err === null || err === void 0 ? void 0 : err.toString()
  395. });
  396. }
  397. if (responseData.error) {
  398. const message = responseData.error.message;
  399. throw ERROR_FACTORY.create("token-update-failed" /* ErrorCode.TOKEN_UPDATE_FAILED */, {
  400. errorInfo: message
  401. });
  402. }
  403. if (!responseData.token) {
  404. throw ERROR_FACTORY.create("token-update-no-token" /* ErrorCode.TOKEN_UPDATE_NO_TOKEN */);
  405. }
  406. return responseData.token;
  407. }
  408. async function requestDeleteToken(firebaseDependencies, token) {
  409. const headers = await getHeaders(firebaseDependencies);
  410. const unsubscribeOptions = {
  411. method: 'DELETE',
  412. headers
  413. };
  414. try {
  415. const response = await fetch(`${getEndpoint(firebaseDependencies.appConfig)}/${token}`, unsubscribeOptions);
  416. const responseData = await response.json();
  417. if (responseData.error) {
  418. const message = responseData.error.message;
  419. throw ERROR_FACTORY.create("token-unsubscribe-failed" /* ErrorCode.TOKEN_UNSUBSCRIBE_FAILED */, {
  420. errorInfo: message
  421. });
  422. }
  423. }
  424. catch (err) {
  425. throw ERROR_FACTORY.create("token-unsubscribe-failed" /* ErrorCode.TOKEN_UNSUBSCRIBE_FAILED */, {
  426. errorInfo: err === null || err === void 0 ? void 0 : err.toString()
  427. });
  428. }
  429. }
  430. function getEndpoint({ projectId }) {
  431. return `${ENDPOINT}/projects/${projectId}/registrations`;
  432. }
  433. async function getHeaders({ appConfig, installations }) {
  434. const authToken = await installations.getToken();
  435. return new Headers({
  436. 'Content-Type': 'application/json',
  437. Accept: 'application/json',
  438. 'x-goog-api-key': appConfig.apiKey,
  439. 'x-goog-firebase-installations-auth': `FIS ${authToken}`
  440. });
  441. }
  442. function getBody({ p256dh, auth, endpoint, vapidKey }) {
  443. const body = {
  444. web: {
  445. endpoint,
  446. auth,
  447. p256dh
  448. }
  449. };
  450. if (vapidKey !== DEFAULT_VAPID_KEY) {
  451. body.web.applicationPubKey = vapidKey;
  452. }
  453. return body;
  454. }
  455. /**
  456. * @license
  457. * Copyright 2019 Google LLC
  458. *
  459. * Licensed under the Apache License, Version 2.0 (the "License");
  460. * you may not use this file except in compliance with the License.
  461. * You may obtain a copy of the License at
  462. *
  463. * http://www.apache.org/licenses/LICENSE-2.0
  464. *
  465. * Unless required by applicable law or agreed to in writing, software
  466. * distributed under the License is distributed on an "AS IS" BASIS,
  467. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  468. * See the License for the specific language governing permissions and
  469. * limitations under the License.
  470. */
  471. // UpdateRegistration will be called once every week.
  472. const TOKEN_EXPIRATION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
  473. async function getTokenInternal(messaging) {
  474. const pushSubscription = await getPushSubscription(messaging.swRegistration, messaging.vapidKey);
  475. const subscriptionOptions = {
  476. vapidKey: messaging.vapidKey,
  477. swScope: messaging.swRegistration.scope,
  478. endpoint: pushSubscription.endpoint,
  479. auth: arrayToBase64(pushSubscription.getKey('auth')),
  480. p256dh: arrayToBase64(pushSubscription.getKey('p256dh'))
  481. };
  482. const tokenDetails = await dbGet(messaging.firebaseDependencies);
  483. if (!tokenDetails) {
  484. // No token, get a new one.
  485. return getNewToken(messaging.firebaseDependencies, subscriptionOptions);
  486. }
  487. else if (!isTokenValid(tokenDetails.subscriptionOptions, subscriptionOptions)) {
  488. // Invalid token, get a new one.
  489. try {
  490. await requestDeleteToken(messaging.firebaseDependencies, tokenDetails.token);
  491. }
  492. catch (e) {
  493. // Suppress errors because of #2364
  494. console.warn(e);
  495. }
  496. return getNewToken(messaging.firebaseDependencies, subscriptionOptions);
  497. }
  498. else if (Date.now() >= tokenDetails.createTime + TOKEN_EXPIRATION_MS) {
  499. // Weekly token refresh
  500. return updateToken(messaging, {
  501. token: tokenDetails.token,
  502. createTime: Date.now(),
  503. subscriptionOptions
  504. });
  505. }
  506. else {
  507. // Valid token, nothing to do.
  508. return tokenDetails.token;
  509. }
  510. }
  511. /**
  512. * This method deletes the token from the database, unsubscribes the token from FCM, and unregisters
  513. * the push subscription if it exists.
  514. */
  515. async function deleteTokenInternal(messaging) {
  516. const tokenDetails = await dbGet(messaging.firebaseDependencies);
  517. if (tokenDetails) {
  518. await requestDeleteToken(messaging.firebaseDependencies, tokenDetails.token);
  519. await dbRemove(messaging.firebaseDependencies);
  520. }
  521. // Unsubscribe from the push subscription.
  522. const pushSubscription = await messaging.swRegistration.pushManager.getSubscription();
  523. if (pushSubscription) {
  524. return pushSubscription.unsubscribe();
  525. }
  526. // If there's no SW, consider it a success.
  527. return true;
  528. }
  529. async function updateToken(messaging, tokenDetails) {
  530. try {
  531. const updatedToken = await requestUpdateToken(messaging.firebaseDependencies, tokenDetails);
  532. const updatedTokenDetails = Object.assign(Object.assign({}, tokenDetails), { token: updatedToken, createTime: Date.now() });
  533. await dbSet(messaging.firebaseDependencies, updatedTokenDetails);
  534. return updatedToken;
  535. }
  536. catch (e) {
  537. await deleteTokenInternal(messaging);
  538. throw e;
  539. }
  540. }
  541. async function getNewToken(firebaseDependencies, subscriptionOptions) {
  542. const token = await requestGetToken(firebaseDependencies, subscriptionOptions);
  543. const tokenDetails = {
  544. token,
  545. createTime: Date.now(),
  546. subscriptionOptions
  547. };
  548. await dbSet(firebaseDependencies, tokenDetails);
  549. return tokenDetails.token;
  550. }
  551. /**
  552. * Gets a PushSubscription for the current user.
  553. */
  554. async function getPushSubscription(swRegistration, vapidKey) {
  555. const subscription = await swRegistration.pushManager.getSubscription();
  556. if (subscription) {
  557. return subscription;
  558. }
  559. return swRegistration.pushManager.subscribe({
  560. userVisibleOnly: true,
  561. // Chrome <= 75 doesn't support base64-encoded VAPID key. For backward compatibility, VAPID key
  562. // submitted to pushManager#subscribe must be of type Uint8Array.
  563. applicationServerKey: base64ToArray(vapidKey)
  564. });
  565. }
  566. /**
  567. * Checks if the saved tokenDetails object matches the configuration provided.
  568. */
  569. function isTokenValid(dbOptions, currentOptions) {
  570. const isVapidKeyEqual = currentOptions.vapidKey === dbOptions.vapidKey;
  571. const isEndpointEqual = currentOptions.endpoint === dbOptions.endpoint;
  572. const isAuthEqual = currentOptions.auth === dbOptions.auth;
  573. const isP256dhEqual = currentOptions.p256dh === dbOptions.p256dh;
  574. return isVapidKeyEqual && isEndpointEqual && isAuthEqual && isP256dhEqual;
  575. }
  576. /**
  577. * @license
  578. * Copyright 2020 Google LLC
  579. *
  580. * Licensed under the Apache License, Version 2.0 (the "License");
  581. * you may not use this file except in compliance with the License.
  582. * You may obtain a copy of the License at
  583. *
  584. * http://www.apache.org/licenses/LICENSE-2.0
  585. *
  586. * Unless required by applicable law or agreed to in writing, software
  587. * distributed under the License is distributed on an "AS IS" BASIS,
  588. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  589. * See the License for the specific language governing permissions and
  590. * limitations under the License.
  591. */
  592. function externalizePayload(internalPayload) {
  593. const payload = {
  594. from: internalPayload.from,
  595. // eslint-disable-next-line camelcase
  596. collapseKey: internalPayload.collapse_key,
  597. // eslint-disable-next-line camelcase
  598. messageId: internalPayload.fcmMessageId
  599. };
  600. propagateNotificationPayload(payload, internalPayload);
  601. propagateDataPayload(payload, internalPayload);
  602. propagateFcmOptions(payload, internalPayload);
  603. return payload;
  604. }
  605. function propagateNotificationPayload(payload, messagePayloadInternal) {
  606. if (!messagePayloadInternal.notification) {
  607. return;
  608. }
  609. payload.notification = {};
  610. const title = messagePayloadInternal.notification.title;
  611. if (!!title) {
  612. payload.notification.title = title;
  613. }
  614. const body = messagePayloadInternal.notification.body;
  615. if (!!body) {
  616. payload.notification.body = body;
  617. }
  618. const image = messagePayloadInternal.notification.image;
  619. if (!!image) {
  620. payload.notification.image = image;
  621. }
  622. const icon = messagePayloadInternal.notification.icon;
  623. if (!!icon) {
  624. payload.notification.icon = icon;
  625. }
  626. }
  627. function propagateDataPayload(payload, messagePayloadInternal) {
  628. if (!messagePayloadInternal.data) {
  629. return;
  630. }
  631. payload.data = messagePayloadInternal.data;
  632. }
  633. function propagateFcmOptions(payload, messagePayloadInternal) {
  634. var _a, _b, _c, _d, _e;
  635. // fcmOptions.link value is written into notification.click_action. see more in b/232072111
  636. if (!messagePayloadInternal.fcmOptions &&
  637. !((_a = messagePayloadInternal.notification) === null || _a === void 0 ? void 0 : _a.click_action)) {
  638. return;
  639. }
  640. payload.fcmOptions = {};
  641. const link = (_c = (_b = messagePayloadInternal.fcmOptions) === null || _b === void 0 ? void 0 : _b.link) !== null && _c !== void 0 ? _c : (_d = messagePayloadInternal.notification) === null || _d === void 0 ? void 0 : _d.click_action;
  642. if (!!link) {
  643. payload.fcmOptions.link = link;
  644. }
  645. // eslint-disable-next-line camelcase
  646. const analyticsLabel = (_e = messagePayloadInternal.fcmOptions) === null || _e === void 0 ? void 0 : _e.analytics_label;
  647. if (!!analyticsLabel) {
  648. payload.fcmOptions.analyticsLabel = analyticsLabel;
  649. }
  650. }
  651. /**
  652. * @license
  653. * Copyright 2019 Google LLC
  654. *
  655. * Licensed under the Apache License, Version 2.0 (the "License");
  656. * you may not use this file except in compliance with the License.
  657. * You may obtain a copy of the License at
  658. *
  659. * http://www.apache.org/licenses/LICENSE-2.0
  660. *
  661. * Unless required by applicable law or agreed to in writing, software
  662. * distributed under the License is distributed on an "AS IS" BASIS,
  663. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  664. * See the License for the specific language governing permissions and
  665. * limitations under the License.
  666. */
  667. function isConsoleMessage(data) {
  668. // This message has a campaign ID, meaning it was sent using the Firebase Console.
  669. return typeof data === 'object' && !!data && CONSOLE_CAMPAIGN_ID in data;
  670. }
  671. /**
  672. * @license
  673. * Copyright 2019 Google LLC
  674. *
  675. * Licensed under the Apache License, Version 2.0 (the "License");
  676. * you may not use this file except in compliance with the License.
  677. * You may obtain a copy of the License at
  678. *
  679. * http://www.apache.org/licenses/LICENSE-2.0
  680. *
  681. * Unless required by applicable law or agreed to in writing, software
  682. * distributed under the License is distributed on an "AS IS" BASIS,
  683. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  684. * See the License for the specific language governing permissions and
  685. * limitations under the License.
  686. */
  687. /** Returns a promise that resolves after given time passes. */
  688. function sleep(ms) {
  689. return new Promise(resolve => {
  690. setTimeout(resolve, ms);
  691. });
  692. }
  693. /**
  694. * @license
  695. * Copyright 2019 Google LLC
  696. *
  697. * Licensed under the Apache License, Version 2.0 (the "License");
  698. * you may not use this file except in compliance with the License.
  699. * You may obtain a copy of the License at
  700. *
  701. * http://www.apache.org/licenses/LICENSE-2.0
  702. *
  703. * Unless required by applicable law or agreed to in writing, software
  704. * distributed under the License is distributed on an "AS IS" BASIS,
  705. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  706. * See the License for the specific language governing permissions and
  707. * limitations under the License.
  708. */
  709. _mergeStrings('hts/frbslgigp.ogepscmv/ieo/eaylg', 'tp:/ieaeogn-agolai.o/1frlglgc/o');
  710. _mergeStrings('AzSCbw63g1R0nCw85jG8', 'Iaya3yLKwmgvh7cF0q4');
  711. async function stageLog(messaging, internalPayload) {
  712. const fcmEvent = createFcmEvent(internalPayload, await messaging.firebaseDependencies.installations.getId());
  713. createAndEnqueueLogEvent(messaging, fcmEvent);
  714. }
  715. function createFcmEvent(internalPayload, fid) {
  716. var _a, _b;
  717. const fcmEvent = {};
  718. /* eslint-disable camelcase */
  719. // some fields should always be non-null. Still check to ensure.
  720. if (!!internalPayload.from) {
  721. fcmEvent.project_number = internalPayload.from;
  722. }
  723. if (!!internalPayload.fcmMessageId) {
  724. fcmEvent.message_id = internalPayload.fcmMessageId;
  725. }
  726. fcmEvent.instance_id = fid;
  727. if (!!internalPayload.notification) {
  728. fcmEvent.message_type = MessageType$1.DISPLAY_NOTIFICATION.toString();
  729. }
  730. else {
  731. fcmEvent.message_type = MessageType$1.DATA_MESSAGE.toString();
  732. }
  733. fcmEvent.sdk_platform = SDK_PLATFORM_WEB.toString();
  734. fcmEvent.package_name = self.origin.replace(/(^\w+:|^)\/\//, '');
  735. if (!!internalPayload.collapse_key) {
  736. fcmEvent.collapse_key = internalPayload.collapse_key;
  737. }
  738. fcmEvent.event = EVENT_MESSAGE_DELIVERED.toString();
  739. if (!!((_a = internalPayload.fcmOptions) === null || _a === void 0 ? void 0 : _a.analytics_label)) {
  740. fcmEvent.analytics_label = (_b = internalPayload.fcmOptions) === null || _b === void 0 ? void 0 : _b.analytics_label;
  741. }
  742. /* eslint-enable camelcase */
  743. return fcmEvent;
  744. }
  745. function createAndEnqueueLogEvent(messaging, fcmEvent) {
  746. const logEvent = {};
  747. /* eslint-disable camelcase */
  748. logEvent.event_time_ms = Math.floor(Date.now()).toString();
  749. logEvent.source_extension_json_proto3 = JSON.stringify(fcmEvent);
  750. // eslint-disable-next-line camelcase
  751. messaging.logEvents.push(logEvent);
  752. }
  753. function _mergeStrings(s1, s2) {
  754. const resultArray = [];
  755. for (let i = 0; i < s1.length; i++) {
  756. resultArray.push(s1.charAt(i));
  757. if (i < s2.length) {
  758. resultArray.push(s2.charAt(i));
  759. }
  760. }
  761. return resultArray.join('');
  762. }
  763. /**
  764. * @license
  765. * Copyright 2017 Google LLC
  766. *
  767. * Licensed under the Apache License, Version 2.0 (the "License");
  768. * you may not use this file except in compliance with the License.
  769. * You may obtain a copy of the License at
  770. *
  771. * http://www.apache.org/licenses/LICENSE-2.0
  772. *
  773. * Unless required by applicable law or agreed to in writing, software
  774. * distributed under the License is distributed on an "AS IS" BASIS,
  775. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  776. * See the License for the specific language governing permissions and
  777. * limitations under the License.
  778. */
  779. async function onSubChange(event, messaging) {
  780. var _a, _b;
  781. const { newSubscription } = event;
  782. if (!newSubscription) {
  783. // Subscription revoked, delete token
  784. await deleteTokenInternal(messaging);
  785. return;
  786. }
  787. const tokenDetails = await dbGet(messaging.firebaseDependencies);
  788. await deleteTokenInternal(messaging);
  789. messaging.vapidKey =
  790. (_b = (_a = tokenDetails === null || tokenDetails === void 0 ? void 0 : tokenDetails.subscriptionOptions) === null || _a === void 0 ? void 0 : _a.vapidKey) !== null && _b !== void 0 ? _b : DEFAULT_VAPID_KEY;
  791. await getTokenInternal(messaging);
  792. }
  793. async function onPush(event, messaging) {
  794. const internalPayload = getMessagePayloadInternal(event);
  795. if (!internalPayload) {
  796. // Failed to get parsed MessagePayload from the PushEvent. Skip handling the push.
  797. return;
  798. }
  799. // log to Firelog with user consent
  800. if (messaging.deliveryMetricsExportedToBigQueryEnabled) {
  801. await stageLog(messaging, internalPayload);
  802. }
  803. // foreground handling: eventually passed to onMessage hook
  804. const clientList = await getClientList();
  805. if (hasVisibleClients(clientList)) {
  806. return sendMessagePayloadInternalToWindows(clientList, internalPayload);
  807. }
  808. // background handling: display if possible and pass to onBackgroundMessage hook
  809. if (!!internalPayload.notification) {
  810. await showNotification(wrapInternalPayload(internalPayload));
  811. }
  812. if (!messaging) {
  813. return;
  814. }
  815. if (!!messaging.onBackgroundMessageHandler) {
  816. const payload = externalizePayload(internalPayload);
  817. if (typeof messaging.onBackgroundMessageHandler === 'function') {
  818. await messaging.onBackgroundMessageHandler(payload);
  819. }
  820. else {
  821. messaging.onBackgroundMessageHandler.next(payload);
  822. }
  823. }
  824. }
  825. async function onNotificationClick(event) {
  826. var _a, _b;
  827. const internalPayload = (_b = (_a = event.notification) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b[FCM_MSG];
  828. if (!internalPayload) {
  829. return;
  830. }
  831. else if (event.action) {
  832. // User clicked on an action button. This will allow developers to act on action button clicks
  833. // by using a custom onNotificationClick listener that they define.
  834. return;
  835. }
  836. // Prevent other listeners from receiving the event
  837. event.stopImmediatePropagation();
  838. event.notification.close();
  839. // Note clicking on a notification with no link set will focus the Chrome's current tab.
  840. const link = getLink(internalPayload);
  841. if (!link) {
  842. return;
  843. }
  844. // FM should only open/focus links from app's origin.
  845. const url = new URL(link, self.location.href);
  846. const originUrl = new URL(self.location.origin);
  847. if (url.host !== originUrl.host) {
  848. return;
  849. }
  850. let client = await getWindowClient(url);
  851. if (!client) {
  852. client = await self.clients.openWindow(link);
  853. // Wait three seconds for the client to initialize and set up the message handler so that it
  854. // can receive the message.
  855. await sleep(3000);
  856. }
  857. else {
  858. client = await client.focus();
  859. }
  860. if (!client) {
  861. // Window Client will not be returned if it's for a third party origin.
  862. return;
  863. }
  864. internalPayload.messageType = MessageType.NOTIFICATION_CLICKED;
  865. internalPayload.isFirebaseMessaging = true;
  866. return client.postMessage(internalPayload);
  867. }
  868. function wrapInternalPayload(internalPayload) {
  869. const wrappedInternalPayload = Object.assign({}, internalPayload.notification);
  870. // Put the message payload under FCM_MSG name so we can identify the notification as being an FCM
  871. // notification vs a notification from somewhere else (i.e. normal web push or developer generated
  872. // notification).
  873. wrappedInternalPayload.data = {
  874. [FCM_MSG]: internalPayload
  875. };
  876. return wrappedInternalPayload;
  877. }
  878. function getMessagePayloadInternal({ data }) {
  879. if (!data) {
  880. return null;
  881. }
  882. try {
  883. return data.json();
  884. }
  885. catch (err) {
  886. // Not JSON so not an FCM message.
  887. return null;
  888. }
  889. }
  890. /**
  891. * @param url The URL to look for when focusing a client.
  892. * @return Returns an existing window client or a newly opened WindowClient.
  893. */
  894. async function getWindowClient(url) {
  895. const clientList = await getClientList();
  896. for (const client of clientList) {
  897. const clientUrl = new URL(client.url, self.location.href);
  898. if (url.host === clientUrl.host) {
  899. return client;
  900. }
  901. }
  902. return null;
  903. }
  904. /**
  905. * @returns If there is currently a visible WindowClient, this method will resolve to true,
  906. * otherwise false.
  907. */
  908. function hasVisibleClients(clientList) {
  909. return clientList.some(client => client.visibilityState === 'visible' &&
  910. // Ignore chrome-extension clients as that matches the background pages of extensions, which
  911. // are always considered visible for some reason.
  912. !client.url.startsWith('chrome-extension://'));
  913. }
  914. function sendMessagePayloadInternalToWindows(clientList, internalPayload) {
  915. internalPayload.isFirebaseMessaging = true;
  916. internalPayload.messageType = MessageType.PUSH_RECEIVED;
  917. for (const client of clientList) {
  918. client.postMessage(internalPayload);
  919. }
  920. }
  921. function getClientList() {
  922. return self.clients.matchAll({
  923. type: 'window',
  924. includeUncontrolled: true
  925. // TS doesn't know that "type: 'window'" means it'll return WindowClient[]
  926. });
  927. }
  928. function showNotification(notificationPayloadInternal) {
  929. var _a;
  930. // Note: Firefox does not support the maxActions property.
  931. // https://developer.mozilla.org/en-US/docs/Web/API/notification/maxActions
  932. const { actions } = notificationPayloadInternal;
  933. const { maxActions } = Notification;
  934. if (actions && maxActions && actions.length > maxActions) {
  935. console.warn(`This browser only supports ${maxActions} actions. The remaining actions will not be displayed.`);
  936. }
  937. return self.registration.showNotification(
  938. /* title= */ (_a = notificationPayloadInternal.title) !== null && _a !== void 0 ? _a : '', notificationPayloadInternal);
  939. }
  940. function getLink(payload) {
  941. var _a, _b, _c;
  942. // eslint-disable-next-line camelcase
  943. const link = (_b = (_a = payload.fcmOptions) === null || _a === void 0 ? void 0 : _a.link) !== null && _b !== void 0 ? _b : (_c = payload.notification) === null || _c === void 0 ? void 0 : _c.click_action;
  944. if (link) {
  945. return link;
  946. }
  947. if (isConsoleMessage(payload.data)) {
  948. // Notification created in the Firebase Console. Redirect to origin.
  949. return self.location.origin;
  950. }
  951. else {
  952. return null;
  953. }
  954. }
  955. /**
  956. * @license
  957. * Copyright 2019 Google LLC
  958. *
  959. * Licensed under the Apache License, Version 2.0 (the "License");
  960. * you may not use this file except in compliance with the License.
  961. * You may obtain a copy of the License at
  962. *
  963. * http://www.apache.org/licenses/LICENSE-2.0
  964. *
  965. * Unless required by applicable law or agreed to in writing, software
  966. * distributed under the License is distributed on an "AS IS" BASIS,
  967. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  968. * See the License for the specific language governing permissions and
  969. * limitations under the License.
  970. */
  971. function extractAppConfig(app) {
  972. if (!app || !app.options) {
  973. throw getMissingValueError('App Configuration Object');
  974. }
  975. if (!app.name) {
  976. throw getMissingValueError('App Name');
  977. }
  978. // Required app config keys
  979. const configKeys = [
  980. 'projectId',
  981. 'apiKey',
  982. 'appId',
  983. 'messagingSenderId'
  984. ];
  985. const { options } = app;
  986. for (const keyName of configKeys) {
  987. if (!options[keyName]) {
  988. throw getMissingValueError(keyName);
  989. }
  990. }
  991. return {
  992. appName: app.name,
  993. projectId: options.projectId,
  994. apiKey: options.apiKey,
  995. appId: options.appId,
  996. senderId: options.messagingSenderId
  997. };
  998. }
  999. function getMissingValueError(valueName) {
  1000. return ERROR_FACTORY.create("missing-app-config-values" /* ErrorCode.MISSING_APP_CONFIG_VALUES */, {
  1001. valueName
  1002. });
  1003. }
  1004. /**
  1005. * @license
  1006. * Copyright 2020 Google LLC
  1007. *
  1008. * Licensed under the Apache License, Version 2.0 (the "License");
  1009. * you may not use this file except in compliance with the License.
  1010. * You may obtain a copy of the License at
  1011. *
  1012. * http://www.apache.org/licenses/LICENSE-2.0
  1013. *
  1014. * Unless required by applicable law or agreed to in writing, software
  1015. * distributed under the License is distributed on an "AS IS" BASIS,
  1016. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1017. * See the License for the specific language governing permissions and
  1018. * limitations under the License.
  1019. */
  1020. class MessagingService {
  1021. constructor(app, installations, analyticsProvider) {
  1022. // logging is only done with end user consent. Default to false.
  1023. this.deliveryMetricsExportedToBigQueryEnabled = false;
  1024. this.onBackgroundMessageHandler = null;
  1025. this.onMessageHandler = null;
  1026. this.logEvents = [];
  1027. this.isLogServiceStarted = false;
  1028. const appConfig = extractAppConfig(app);
  1029. this.firebaseDependencies = {
  1030. app,
  1031. appConfig,
  1032. installations,
  1033. analyticsProvider
  1034. };
  1035. }
  1036. _delete() {
  1037. return Promise.resolve();
  1038. }
  1039. }
  1040. /**
  1041. * @license
  1042. * Copyright 2020 Google LLC
  1043. *
  1044. * Licensed under the Apache License, Version 2.0 (the "License");
  1045. * you may not use this file except in compliance with the License.
  1046. * You may obtain a copy of the License at
  1047. *
  1048. * http://www.apache.org/licenses/LICENSE-2.0
  1049. *
  1050. * Unless required by applicable law or agreed to in writing, software
  1051. * distributed under the License is distributed on an "AS IS" BASIS,
  1052. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1053. * See the License for the specific language governing permissions and
  1054. * limitations under the License.
  1055. */
  1056. const SwMessagingFactory = (container) => {
  1057. const messaging = new MessagingService(container.getProvider('app').getImmediate(), container.getProvider('installations-internal').getImmediate(), container.getProvider('analytics-internal'));
  1058. self.addEventListener('push', e => {
  1059. e.waitUntil(onPush(e, messaging));
  1060. });
  1061. self.addEventListener('pushsubscriptionchange', e => {
  1062. e.waitUntil(onSubChange(e, messaging));
  1063. });
  1064. self.addEventListener('notificationclick', e => {
  1065. e.waitUntil(onNotificationClick(e));
  1066. });
  1067. return messaging;
  1068. };
  1069. /**
  1070. * The messaging instance registered in sw is named differently than that of in client. This is
  1071. * because both `registerMessagingInWindow` and `registerMessagingInSw` would be called in
  1072. * `messaging-compat` and component with the same name can only be registered once.
  1073. */
  1074. function registerMessagingInSw() {
  1075. _registerComponent(new Component('messaging-sw', SwMessagingFactory, "PUBLIC" /* ComponentType.PUBLIC */));
  1076. }
  1077. /**
  1078. * @license
  1079. * Copyright 2020 Google LLC
  1080. *
  1081. * Licensed under the Apache License, Version 2.0 (the "License");
  1082. * you may not use this file except in compliance with the License.
  1083. * You may obtain a copy of the License at
  1084. *
  1085. * http://www.apache.org/licenses/LICENSE-2.0
  1086. *
  1087. * Unless required by applicable law or agreed to in writing, software
  1088. * distributed under the License is distributed on an "AS IS" BASIS,
  1089. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1090. * See the License for the specific language governing permissions and
  1091. * limitations under the License.
  1092. */
  1093. /**
  1094. * Checks whether all required APIs exist within SW Context
  1095. * @returns a Promise that resolves to a boolean.
  1096. *
  1097. * @public
  1098. */
  1099. async function isSwSupported() {
  1100. // firebase-js-sdk/issues/2393 reveals that idb#open in Safari iframe and Firefox private browsing
  1101. // might be prohibited to run. In these contexts, an error would be thrown during the messaging
  1102. // instantiating phase, informing the developers to import/call isSupported for special handling.
  1103. return (isIndexedDBAvailable() &&
  1104. (await validateIndexedDBOpenable()) &&
  1105. 'PushManager' in self &&
  1106. 'Notification' in self &&
  1107. ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&
  1108. PushSubscription.prototype.hasOwnProperty('getKey'));
  1109. }
  1110. /**
  1111. * @license
  1112. * Copyright 2020 Google LLC
  1113. *
  1114. * Licensed under the Apache License, Version 2.0 (the "License");
  1115. * you may not use this file except in compliance with the License.
  1116. * You may obtain a copy of the License at
  1117. *
  1118. * http://www.apache.org/licenses/LICENSE-2.0
  1119. *
  1120. * Unless required by applicable law or agreed to in writing, software
  1121. * distributed under the License is distributed on an "AS IS" BASIS,
  1122. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1123. * See the License for the specific language governing permissions and
  1124. * limitations under the License.
  1125. */
  1126. function onBackgroundMessage$1(messaging, nextOrObserver) {
  1127. if (self.document !== undefined) {
  1128. throw ERROR_FACTORY.create("only-available-in-sw" /* ErrorCode.AVAILABLE_IN_SW */);
  1129. }
  1130. messaging.onBackgroundMessageHandler = nextOrObserver;
  1131. return () => {
  1132. messaging.onBackgroundMessageHandler = null;
  1133. };
  1134. }
  1135. /**
  1136. * @license
  1137. * Copyright 2020 Google LLC
  1138. *
  1139. * Licensed under the Apache License, Version 2.0 (the "License");
  1140. * you may not use this file except in compliance with the License.
  1141. * You may obtain a copy of the License at
  1142. *
  1143. * http://www.apache.org/licenses/LICENSE-2.0
  1144. *
  1145. * Unless required by applicable law or agreed to in writing, software
  1146. * distributed under the License is distributed on an "AS IS" BASIS,
  1147. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1148. * See the License for the specific language governing permissions and
  1149. * limitations under the License.
  1150. */
  1151. function _setDeliveryMetricsExportedToBigQueryEnabled(messaging, enable) {
  1152. messaging.deliveryMetricsExportedToBigQueryEnabled =
  1153. enable;
  1154. }
  1155. /**
  1156. * @license
  1157. * Copyright 2017 Google LLC
  1158. *
  1159. * Licensed under the Apache License, Version 2.0 (the "License");
  1160. * you may not use this file except in compliance with the License.
  1161. * You may obtain a copy of the License at
  1162. *
  1163. * http://www.apache.org/licenses/LICENSE-2.0
  1164. *
  1165. * Unless required by applicable law or agreed to in writing, software
  1166. * distributed under the License is distributed on an "AS IS" BASIS,
  1167. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1168. * See the License for the specific language governing permissions and
  1169. * limitations under the License.
  1170. */
  1171. /**
  1172. * Retrieves a Firebase Cloud Messaging instance.
  1173. *
  1174. * @returns The Firebase Cloud Messaging instance associated with the provided firebase app.
  1175. *
  1176. * @public
  1177. */
  1178. function getMessagingInSw(app = getApp()) {
  1179. // Conscious decision to make this async check non-blocking during the messaging instance
  1180. // initialization phase for performance consideration. An error would be thrown latter for
  1181. // developer's information. Developers can then choose to import and call `isSupported` for
  1182. // special handling.
  1183. isSwSupported().then(isSupported => {
  1184. // If `isSwSupported()` resolved, but returned false.
  1185. if (!isSupported) {
  1186. throw ERROR_FACTORY.create("unsupported-browser" /* ErrorCode.UNSUPPORTED_BROWSER */);
  1187. }
  1188. }, _ => {
  1189. // If `isSwSupported()` rejected.
  1190. throw ERROR_FACTORY.create("indexed-db-unsupported" /* ErrorCode.INDEXED_DB_UNSUPPORTED */);
  1191. });
  1192. return _getProvider(getModularInstance(app), 'messaging-sw').getImmediate();
  1193. }
  1194. /**
  1195. * Called when a message is received while the app is in the background. An app is considered to be
  1196. * in the background if no active window is displayed.
  1197. *
  1198. * @param messaging - The {@link Messaging} instance.
  1199. * @param nextOrObserver - This function, or observer object with `next` defined, is called when a
  1200. * message is received and the app is currently in the background.
  1201. *
  1202. * @returns To stop listening for messages execute this returned function
  1203. *
  1204. * @public
  1205. */
  1206. function onBackgroundMessage(messaging, nextOrObserver) {
  1207. messaging = getModularInstance(messaging);
  1208. return onBackgroundMessage$1(messaging, nextOrObserver);
  1209. }
  1210. /**
  1211. * Enables or disables Firebase Cloud Messaging message delivery metrics export to BigQuery. By
  1212. * default, message delivery metrics are not exported to BigQuery. Use this method to enable or
  1213. * disable the export at runtime.
  1214. *
  1215. * @param messaging - The `FirebaseMessaging` instance.
  1216. * @param enable - Whether Firebase Cloud Messaging should export message delivery metrics to
  1217. * BigQuery.
  1218. *
  1219. * @public
  1220. */
  1221. function experimentalSetDeliveryMetricsExportedToBigQueryEnabled(messaging, enable) {
  1222. messaging = getModularInstance(messaging);
  1223. return _setDeliveryMetricsExportedToBigQueryEnabled(messaging, enable);
  1224. }
  1225. /**
  1226. * @license
  1227. * Copyright 2017 Google LLC
  1228. *
  1229. * Licensed under the Apache License, Version 2.0 (the "License");
  1230. * you may not use this file except in compliance with the License.
  1231. * You may obtain a copy of the License at
  1232. *
  1233. * http://www.apache.org/licenses/LICENSE-2.0
  1234. *
  1235. * Unless required by applicable law or agreed to in writing, software
  1236. * distributed under the License is distributed on an "AS IS" BASIS,
  1237. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1238. * See the License for the specific language governing permissions and
  1239. * limitations under the License.
  1240. */
  1241. registerMessagingInSw();
  1242. export { experimentalSetDeliveryMetricsExportedToBigQueryEnabled, getMessagingInSw as getMessaging, isSwSupported as isSupported, onBackgroundMessage };
  1243. //# sourceMappingURL=index.sw.esm2017.js.map