{"version":3,"file":"firebase-messaging.js","sources":["../../node_modules/tslib/tslib.es6.js","../util/src/errors.ts","../component/src/component.ts","../../node_modules/idb/lib/idb.mjs","../installations/src/util/constants.ts","../installations/src/util/errors.ts","../installations/src/api/common.ts","../installations/src/util/sleep.ts","../installations/src/helpers/generate-fid.ts","../installations/src/helpers/buffer-to-base64-url-safe.ts","../installations/src/util/get-key.ts","../installations/src/helpers/fid-changed.ts","../installations/src/helpers/idb-manager.ts","../installations/src/index.ts","../installations/src/helpers/get-installation-entry.ts","../installations/src/api/create-installation-request.ts","../installations/src/api/generate-auth-token-request.ts","../installations/src/helpers/refresh-auth-token.ts","../installations/src/functions/get-token.ts","../installations/src/api/delete-installation-request.ts","../installations/src/functions/on-id-change.ts","../installations/src/helpers/extract-app-config.ts","../installations/src/functions/get-id.ts","../installations/src/functions/delete-installation.ts","../messaging/src/util/errors.ts","../messaging/src/interfaces/internal-message-payload.ts","../messaging/src/util/constants.ts","../messaging/src/helpers/array-base64-translator.ts","../messaging/src/helpers/migrate-old-database.ts","../messaging/src/helpers/idb-manager.ts","../messaging/src/core/api.ts","../messaging/src/core/token-management.ts","../messaging/src/helpers/externalizePayload.ts","../messaging/src/helpers/is-console-message.ts","../messaging/src/helpers/sleep.ts","../messaging/src/controllers/sw-controller.ts","../messaging/src/controllers/window-controller.ts","../messaging/src/helpers/extract-app-config.ts","../messaging/src/index.ts"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from) {\r\n for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)\r\n to[j] = from[i];\r\n return to;\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to get private field on non-instance\");\r\n }\r\n return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to set private field on non-instance\");\r\n }\r\n privateMap.set(receiver, value);\r\n return value;\r\n}\r\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * @fileoverview Standardized Firebase Error.\n *\n * Usage:\n *\n * // Typescript string literals for type-safe codes\n * type Err =\n * 'unknown' |\n * 'object-not-found'\n * ;\n *\n * // Closure enum for type-safe error codes\n * // at-enum {string}\n * var Err = {\n * UNKNOWN: 'unknown',\n * OBJECT_NOT_FOUND: 'object-not-found',\n * }\n *\n * let errors: Map = {\n * 'generic-error': \"Unknown error\",\n * 'file-not-found': \"Could not find file: {$file}\",\n * };\n *\n * // Type-safe function - must pass a valid error code as param.\n * let error = new ErrorFactory('service', 'Service', errors);\n *\n * ...\n * throw error.create(Err.GENERIC);\n * ...\n * throw error.create(Err.FILE_NOT_FOUND, {'file': fileName});\n * ...\n * // Service: Could not file file: foo.txt (service/file-not-found).\n *\n * catch (e) {\n * assert(e.message === \"Could not find file: foo.txt.\");\n * if (e.code === 'service/file-not-found') {\n * console.log(\"Could not read file: \" + e['file']);\n * }\n * }\n */\n\nexport type ErrorMap = {\n readonly [K in ErrorCode]: string;\n};\n\nconst ERROR_NAME = 'FirebaseError';\n\nexport interface StringLike {\n toString(): string;\n}\n\nexport interface ErrorData {\n [key: string]: unknown;\n}\n\n// Based on code from:\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types\nexport class FirebaseError extends Error {\n readonly name = ERROR_NAME;\n\n constructor(\n readonly code: string,\n message: string,\n public customData?: Record\n ) {\n super(message);\n\n // Fix For ES5\n // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, FirebaseError.prototype);\n\n // Maintains proper stack trace for where our error was thrown.\n // Only available on V8.\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ErrorFactory.prototype.create);\n }\n }\n}\n\nexport class ErrorFactory<\n ErrorCode extends string,\n ErrorParams extends { readonly [K in ErrorCode]?: ErrorData } = {}\n> {\n constructor(\n private readonly service: string,\n private readonly serviceName: string,\n private readonly errors: ErrorMap\n ) {}\n\n create(\n code: K,\n ...data: K extends keyof ErrorParams ? [ErrorParams[K]] : []\n ): FirebaseError {\n const customData = (data[0] as ErrorData) || {};\n const fullCode = `${this.service}/${code}`;\n const template = this.errors[code];\n\n const message = template ? replaceTemplate(template, customData) : 'Error';\n // Service Name: Error message (service/code).\n const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`;\n\n const error = new FirebaseError(fullCode, fullMessage, customData);\n\n return error;\n }\n}\n\nfunction replaceTemplate(template: string, data: ErrorData): string {\n return template.replace(PATTERN, (_, key) => {\n const value = data[key];\n return value != null ? String(value) : `<${key}?>`;\n });\n}\n\nconst PATTERN = /\\{\\$([^}]+)}/g;\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n InstantiationMode,\n InstanceFactory,\n ComponentType,\n Dictionary,\n Name,\n onInstanceCreatedCallback\n} from './types';\n\n/**\n * Component for service name T, e.g. `auth`, `auth-internal`\n */\nexport class Component {\n multipleInstances = false;\n /**\n * Properties to be added to the service namespace\n */\n serviceProps: Dictionary = {};\n\n instantiationMode = InstantiationMode.LAZY;\n\n onInstanceCreated: onInstanceCreatedCallback | null = null;\n\n /**\n *\n * @param name The public service name, e.g. app, auth, firestore, database\n * @param instanceFactory Service factory responsible for creating the public interface\n * @param type whether the service provided by the component is public or private\n */\n constructor(\n readonly name: T,\n readonly instanceFactory: InstanceFactory,\n readonly type: ComponentType\n ) {}\n\n setInstantiationMode(mode: InstantiationMode): this {\n this.instantiationMode = mode;\n return this;\n }\n\n setMultipleInstances(multipleInstances: boolean): this {\n this.multipleInstances = multipleInstances;\n return this;\n }\n\n setServiceProps(props: Dictionary): this {\n this.serviceProps = props;\n return this;\n }\n\n setInstanceCreatedCallback(callback: onInstanceCreatedCallback): this {\n this.onInstanceCreated = callback;\n return this;\n }\n}\n","function toArray(arr) {\n return Array.prototype.slice.call(arr);\n}\n\nfunction promisifyRequest(request) {\n return new Promise(function(resolve, reject) {\n request.onsuccess = function() {\n resolve(request.result);\n };\n\n request.onerror = function() {\n reject(request.error);\n };\n });\n}\n\nfunction promisifyRequestCall(obj, method, args) {\n var request;\n var p = new Promise(function(resolve, reject) {\n request = obj[method].apply(obj, args);\n promisifyRequest(request).then(resolve, reject);\n });\n\n p.request = request;\n return p;\n}\n\nfunction promisifyCursorRequestCall(obj, method, args) {\n var p = promisifyRequestCall(obj, method, args);\n return p.then(function(value) {\n if (!value) return;\n return new Cursor(value, p.request);\n });\n}\n\nfunction proxyProperties(ProxyClass, targetProp, properties) {\n properties.forEach(function(prop) {\n Object.defineProperty(ProxyClass.prototype, prop, {\n get: function() {\n return this[targetProp][prop];\n },\n set: function(val) {\n this[targetProp][prop] = val;\n }\n });\n });\n}\n\nfunction proxyRequestMethods(ProxyClass, targetProp, Constructor, properties) {\n properties.forEach(function(prop) {\n if (!(prop in Constructor.prototype)) return;\n ProxyClass.prototype[prop] = function() {\n return promisifyRequestCall(this[targetProp], prop, arguments);\n };\n });\n}\n\nfunction proxyMethods(ProxyClass, targetProp, Constructor, properties) {\n properties.forEach(function(prop) {\n if (!(prop in Constructor.prototype)) return;\n ProxyClass.prototype[prop] = function() {\n return this[targetProp][prop].apply(this[targetProp], arguments);\n };\n });\n}\n\nfunction proxyCursorRequestMethods(ProxyClass, targetProp, Constructor, properties) {\n properties.forEach(function(prop) {\n if (!(prop in Constructor.prototype)) return;\n ProxyClass.prototype[prop] = function() {\n return promisifyCursorRequestCall(this[targetProp], prop, arguments);\n };\n });\n}\n\nfunction Index(index) {\n this._index = index;\n}\n\nproxyProperties(Index, '_index', [\n 'name',\n 'keyPath',\n 'multiEntry',\n 'unique'\n]);\n\nproxyRequestMethods(Index, '_index', IDBIndex, [\n 'get',\n 'getKey',\n 'getAll',\n 'getAllKeys',\n 'count'\n]);\n\nproxyCursorRequestMethods(Index, '_index', IDBIndex, [\n 'openCursor',\n 'openKeyCursor'\n]);\n\nfunction Cursor(cursor, request) {\n this._cursor = cursor;\n this._request = request;\n}\n\nproxyProperties(Cursor, '_cursor', [\n 'direction',\n 'key',\n 'primaryKey',\n 'value'\n]);\n\nproxyRequestMethods(Cursor, '_cursor', IDBCursor, [\n 'update',\n 'delete'\n]);\n\n// proxy 'next' methods\n['advance', 'continue', 'continuePrimaryKey'].forEach(function(methodName) {\n if (!(methodName in IDBCursor.prototype)) return;\n Cursor.prototype[methodName] = function() {\n var cursor = this;\n var args = arguments;\n return Promise.resolve().then(function() {\n cursor._cursor[methodName].apply(cursor._cursor, args);\n return promisifyRequest(cursor._request).then(function(value) {\n if (!value) return;\n return new Cursor(value, cursor._request);\n });\n });\n };\n});\n\nfunction ObjectStore(store) {\n this._store = store;\n}\n\nObjectStore.prototype.createIndex = function() {\n return new Index(this._store.createIndex.apply(this._store, arguments));\n};\n\nObjectStore.prototype.index = function() {\n return new Index(this._store.index.apply(this._store, arguments));\n};\n\nproxyProperties(ObjectStore, '_store', [\n 'name',\n 'keyPath',\n 'indexNames',\n 'autoIncrement'\n]);\n\nproxyRequestMethods(ObjectStore, '_store', IDBObjectStore, [\n 'put',\n 'add',\n 'delete',\n 'clear',\n 'get',\n 'getAll',\n 'getKey',\n 'getAllKeys',\n 'count'\n]);\n\nproxyCursorRequestMethods(ObjectStore, '_store', IDBObjectStore, [\n 'openCursor',\n 'openKeyCursor'\n]);\n\nproxyMethods(ObjectStore, '_store', IDBObjectStore, [\n 'deleteIndex'\n]);\n\nfunction Transaction(idbTransaction) {\n this._tx = idbTransaction;\n this.complete = new Promise(function(resolve, reject) {\n idbTransaction.oncomplete = function() {\n resolve();\n };\n idbTransaction.onerror = function() {\n reject(idbTransaction.error);\n };\n idbTransaction.onabort = function() {\n reject(idbTransaction.error);\n };\n });\n}\n\nTransaction.prototype.objectStore = function() {\n return new ObjectStore(this._tx.objectStore.apply(this._tx, arguments));\n};\n\nproxyProperties(Transaction, '_tx', [\n 'objectStoreNames',\n 'mode'\n]);\n\nproxyMethods(Transaction, '_tx', IDBTransaction, [\n 'abort'\n]);\n\nfunction UpgradeDB(db, oldVersion, transaction) {\n this._db = db;\n this.oldVersion = oldVersion;\n this.transaction = new Transaction(transaction);\n}\n\nUpgradeDB.prototype.createObjectStore = function() {\n return new ObjectStore(this._db.createObjectStore.apply(this._db, arguments));\n};\n\nproxyProperties(UpgradeDB, '_db', [\n 'name',\n 'version',\n 'objectStoreNames'\n]);\n\nproxyMethods(UpgradeDB, '_db', IDBDatabase, [\n 'deleteObjectStore',\n 'close'\n]);\n\nfunction DB(db) {\n this._db = db;\n}\n\nDB.prototype.transaction = function() {\n return new Transaction(this._db.transaction.apply(this._db, arguments));\n};\n\nproxyProperties(DB, '_db', [\n 'name',\n 'version',\n 'objectStoreNames'\n]);\n\nproxyMethods(DB, '_db', IDBDatabase, [\n 'close'\n]);\n\n// Add cursor iterators\n// TODO: remove this once browsers do the right thing with promises\n['openCursor', 'openKeyCursor'].forEach(function(funcName) {\n [ObjectStore, Index].forEach(function(Constructor) {\n // Don't create iterateKeyCursor if openKeyCursor doesn't exist.\n if (!(funcName in Constructor.prototype)) return;\n\n Constructor.prototype[funcName.replace('open', 'iterate')] = function() {\n var args = toArray(arguments);\n var callback = args[args.length - 1];\n var nativeObject = this._store || this._index;\n var request = nativeObject[funcName].apply(nativeObject, args.slice(0, -1));\n request.onsuccess = function() {\n callback(request.result);\n };\n };\n });\n});\n\n// polyfill getAll\n[Index, ObjectStore].forEach(function(Constructor) {\n if (Constructor.prototype.getAll) return;\n Constructor.prototype.getAll = function(query, count) {\n var instance = this;\n var items = [];\n\n return new Promise(function(resolve) {\n instance.iterateCursor(query, function(cursor) {\n if (!cursor) {\n resolve(items);\n return;\n }\n items.push(cursor.value);\n\n if (count !== undefined && items.length == count) {\n resolve(items);\n return;\n }\n cursor.continue();\n });\n });\n };\n});\n\nexport function openDb(name, version, upgradeCallback) {\n var p = promisifyRequestCall(indexedDB, 'open', [name, version]);\n var request = p.request;\n\n if (request) {\n request.onupgradeneeded = function(event) {\n if (upgradeCallback) {\n upgradeCallback(new UpgradeDB(request.result, event.oldVersion, request.transaction));\n }\n };\n }\n\n return p.then(function(db) {\n return new DB(db);\n });\n}\n\nexport function deleteDb(name) {\n return promisifyRequestCall(indexedDB, 'deleteDatabase', [name]);\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { version } from '../../package.json';\n\nexport const PENDING_TIMEOUT_MS = 10000;\n\nexport const PACKAGE_VERSION = `w:${version}`;\nexport const INTERNAL_AUTH_VERSION = 'FIS_v2';\n\nexport const INSTALLATIONS_API_URL =\n 'https://firebaseinstallations.googleapis.com/v1';\n\nexport const TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour\n\nexport const SERVICE = 'installations';\nexport const SERVICE_NAME = 'Installations';\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, FirebaseError } from '@firebase/util';\nimport { SERVICE, SERVICE_NAME } from './constants';\n\nexport const enum ErrorCode {\n MISSING_APP_CONFIG_VALUES = 'missing-app-config-values',\n NOT_REGISTERED = 'not-registered',\n INSTALLATION_NOT_FOUND = 'installation-not-found',\n REQUEST_FAILED = 'request-failed',\n APP_OFFLINE = 'app-offline',\n DELETE_PENDING_REGISTRATION = 'delete-pending-registration'\n}\n\nconst ERROR_DESCRIPTION_MAP: { readonly [key in ErrorCode]: string } = {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]:\n 'Missing App configuration value: \"{$valueName}\"',\n [ErrorCode.NOT_REGISTERED]: 'Firebase Installation is not registered.',\n [ErrorCode.INSTALLATION_NOT_FOUND]: 'Firebase Installation not found.',\n [ErrorCode.REQUEST_FAILED]:\n '{$requestName} request failed with error \"{$serverCode} {$serverStatus}: {$serverMessage}\"',\n [ErrorCode.APP_OFFLINE]: 'Could not process request. Application offline.',\n [ErrorCode.DELETE_PENDING_REGISTRATION]:\n \"Can't delete installation while there is a pending registration request.\"\n};\n\ninterface ErrorParams {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]: {\n valueName: string;\n };\n [ErrorCode.REQUEST_FAILED]: {\n requestName: string;\n [index: string]: string | number; // to make Typescript 3.8 happy\n } & ServerErrorData;\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n SERVICE,\n SERVICE_NAME,\n ERROR_DESCRIPTION_MAP\n);\n\nexport interface ServerErrorData {\n serverCode: number;\n serverMessage: string;\n serverStatus: string;\n}\n\nexport type ServerError = FirebaseError & { customData: ServerErrorData };\n\n/** Returns true if error is a FirebaseError that is based on an error from the server. */\nexport function isServerError(error: unknown): error is ServerError {\n return (\n error instanceof FirebaseError &&\n error.code.includes(ErrorCode.REQUEST_FAILED)\n );\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseError } from '@firebase/util';\nimport { GenerateAuthTokenResponse } from '../interfaces/api-response';\nimport { AppConfig } from '../interfaces/app-config';\nimport {\n CompletedAuthToken,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport {\n INSTALLATIONS_API_URL,\n INTERNAL_AUTH_VERSION\n} from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nexport function getInstallationsEndpoint({ projectId }: AppConfig): string {\n return `${INSTALLATIONS_API_URL}/projects/${projectId}/installations`;\n}\n\nexport function extractAuthTokenInfoFromResponse(\n response: GenerateAuthTokenResponse\n): CompletedAuthToken {\n return {\n token: response.token,\n requestStatus: RequestStatus.COMPLETED,\n expiresIn: getExpiresInFromResponseExpiresIn(response.expiresIn),\n creationTime: Date.now()\n };\n}\n\nexport async function getErrorFromResponse(\n requestName: string,\n response: Response\n): Promise {\n const responseJson: ErrorResponse = await response.json();\n const errorData = responseJson.error;\n return ERROR_FACTORY.create(ErrorCode.REQUEST_FAILED, {\n requestName,\n serverCode: errorData.code,\n serverMessage: errorData.message,\n serverStatus: errorData.status\n });\n}\n\nexport function getHeaders({ apiKey }: AppConfig): Headers {\n return new Headers({\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'x-goog-api-key': apiKey\n });\n}\n\nexport function getHeadersWithAuth(\n appConfig: AppConfig,\n { refreshToken }: RegisteredInstallationEntry\n): Headers {\n const headers = getHeaders(appConfig);\n headers.append('Authorization', getAuthorizationHeader(refreshToken));\n return headers;\n}\n\nexport interface ErrorResponse {\n error: {\n code: number;\n message: string;\n status: string;\n };\n}\n\n/**\n * Calls the passed in fetch wrapper and returns the response.\n * If the returned response has a status of 5xx, re-runs the function once and\n * returns the response.\n */\nexport async function retryIfServerError(\n fn: () => Promise\n): Promise {\n const result = await fn();\n\n if (result.status >= 500 && result.status < 600) {\n // Internal Server Error. Retry request.\n return fn();\n }\n\n return result;\n}\n\nfunction getExpiresInFromResponseExpiresIn(responseExpiresIn: string): number {\n // This works because the server will never respond with fractions of a second.\n return Number(responseExpiresIn.replace('s', '000'));\n}\n\nfunction getAuthorizationHeader(refreshToken: string): string {\n return `${INTERNAL_AUTH_VERSION} ${refreshToken}`;\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** Returns a promise that resolves after given time passes. */\nexport function sleep(ms: number): Promise {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bufferToBase64UrlSafe } from './buffer-to-base64-url-safe';\n\nexport const VALID_FID_PATTERN = /^[cdef][\\w-]{21}$/;\nexport const INVALID_FID = '';\n\n/**\n * Generates a new FID using random values from Web Crypto API.\n * Returns an empty string if FID generation fails for any reason.\n */\nexport function generateFid(): string {\n try {\n // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5\n // bytes. our implementation generates a 17 byte array instead.\n const fidByteArray = new Uint8Array(17);\n const crypto =\n self.crypto || ((self as unknown) as { msCrypto: Crypto }).msCrypto;\n crypto.getRandomValues(fidByteArray);\n\n // Replace the first 4 random bits with the constant FID header of 0b0111.\n fidByteArray[0] = 0b01110000 + (fidByteArray[0] % 0b00010000);\n\n const fid = encode(fidByteArray);\n\n return VALID_FID_PATTERN.test(fid) ? fid : INVALID_FID;\n } catch {\n // FID generation errored\n return INVALID_FID;\n }\n}\n\n/** Converts a FID Uint8Array to a base64 string representation. */\nfunction encode(fidByteArray: Uint8Array): string {\n const b64String = bufferToBase64UrlSafe(fidByteArray);\n\n // Remove the 23rd character that was added because of the extra 4 bits at the\n // end of our 17 byte array, and the '=' padding.\n return b64String.substr(0, 22);\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function bufferToBase64UrlSafe(array: Uint8Array): string {\n const b64 = btoa(String.fromCharCode(...array));\n return b64.replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AppConfig } from '../interfaces/app-config';\n\n/** Returns a string key that can be used to identify the app. */\nexport function getKey(appConfig: AppConfig): string {\n return `${appConfig.appName}!${appConfig.appId}`;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getKey } from '../util/get-key';\nimport { AppConfig } from '../interfaces/app-config';\nimport { IdChangeCallbackFn } from '../functions';\n\nconst fidChangeCallbacks: Map> = new Map();\n\n/**\n * Calls the onIdChange callbacks with the new FID value, and broadcasts the\n * change to other tabs.\n */\nexport function fidChanged(appConfig: AppConfig, fid: string): void {\n const key = getKey(appConfig);\n\n callFidChangeCallbacks(key, fid);\n broadcastFidChange(key, fid);\n}\n\nexport function addCallback(\n appConfig: AppConfig,\n callback: IdChangeCallbackFn\n): void {\n // Open the broadcast channel if it's not already open,\n // to be able to listen to change events from other tabs.\n getBroadcastChannel();\n\n const key = getKey(appConfig);\n\n let callbackSet = fidChangeCallbacks.get(key);\n if (!callbackSet) {\n callbackSet = new Set();\n fidChangeCallbacks.set(key, callbackSet);\n }\n callbackSet.add(callback);\n}\n\nexport function removeCallback(\n appConfig: AppConfig,\n callback: IdChangeCallbackFn\n): void {\n const key = getKey(appConfig);\n\n const callbackSet = fidChangeCallbacks.get(key);\n\n if (!callbackSet) {\n return;\n }\n\n callbackSet.delete(callback);\n if (callbackSet.size === 0) {\n fidChangeCallbacks.delete(key);\n }\n\n // Close broadcast channel if there are no more callbacks.\n closeBroadcastChannel();\n}\n\nfunction callFidChangeCallbacks(key: string, fid: string): void {\n const callbacks = fidChangeCallbacks.get(key);\n if (!callbacks) {\n return;\n }\n\n for (const callback of callbacks) {\n callback(fid);\n }\n}\n\nfunction broadcastFidChange(key: string, fid: string): void {\n const channel = getBroadcastChannel();\n if (channel) {\n channel.postMessage({ key, fid });\n }\n closeBroadcastChannel();\n}\n\nlet broadcastChannel: BroadcastChannel | null = null;\n/** Opens and returns a BroadcastChannel if it is supported by the browser. */\nfunction getBroadcastChannel(): BroadcastChannel | null {\n if (!broadcastChannel && 'BroadcastChannel' in self) {\n broadcastChannel = new BroadcastChannel('[Firebase] FID Change');\n broadcastChannel.onmessage = e => {\n callFidChangeCallbacks(e.data.key, e.data.fid);\n };\n }\n return broadcastChannel;\n}\n\nfunction closeBroadcastChannel(): void {\n if (fidChangeCallbacks.size === 0 && broadcastChannel) {\n broadcastChannel.close();\n broadcastChannel = null;\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DB, openDb } from 'idb';\nimport { AppConfig } from '../interfaces/app-config';\nimport { InstallationEntry } from '../interfaces/installation-entry';\nimport { getKey } from '../util/get-key';\nimport { fidChanged } from './fid-changed';\n\nconst DATABASE_NAME = 'firebase-installations-database';\nconst DATABASE_VERSION = 1;\nconst OBJECT_STORE_NAME = 'firebase-installations-store';\n\nlet dbPromise: Promise | null = null;\nfunction getDbPromise(): Promise {\n if (!dbPromise) {\n dbPromise = openDb(DATABASE_NAME, DATABASE_VERSION, upgradeDB => {\n // We don't use 'break' in this switch statement, the fall-through\n // behavior is what we want, because if there are multiple versions between\n // the old version and the current version, we want ALL the migrations\n // that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (upgradeDB.oldVersion) {\n case 0:\n upgradeDB.createObjectStore(OBJECT_STORE_NAME);\n }\n });\n }\n return dbPromise;\n}\n\n/** Gets record(s) from the objectStore that match the given key. */\nexport async function get(\n appConfig: AppConfig\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n return db\n .transaction(OBJECT_STORE_NAME)\n .objectStore(OBJECT_STORE_NAME)\n .get(key);\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function set(\n appConfig: AppConfig,\n value: ValueType\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n const objectStore = tx.objectStore(OBJECT_STORE_NAME);\n const oldValue = await objectStore.get(key);\n await objectStore.put(value, key);\n await tx.complete;\n\n if (!oldValue || oldValue.fid !== value.fid) {\n fidChanged(appConfig, value.fid);\n }\n\n return value;\n}\n\n/** Removes record(s) from the objectStore that match the given key. */\nexport async function remove(appConfig: AppConfig): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).delete(key);\n await tx.complete;\n}\n\n/**\n * Atomically updates a record with the result of updateFn, which gets\n * called with the current value. If newValue is undefined, the record is\n * deleted instead.\n * @return Updated value\n */\nexport async function update(\n appConfig: AppConfig,\n updateFn: (previousValue: InstallationEntry | undefined) => ValueType\n): Promise {\n const key = getKey(appConfig);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n const store = tx.objectStore(OBJECT_STORE_NAME);\n const oldValue: InstallationEntry | undefined = await store.get(key);\n const newValue = updateFn(oldValue);\n\n if (newValue === undefined) {\n await store.delete(key);\n } else {\n await store.put(newValue, key);\n }\n await tx.complete;\n\n if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) {\n fidChanged(appConfig, newValue.fid);\n }\n\n return newValue;\n}\n\nexport async function clear(): Promise {\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).clear();\n await tx.complete;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport firebase from '@firebase/app';\nimport {\n _FirebaseNamespace,\n FirebaseService\n} from '@firebase/app-types/private';\nimport { Component, ComponentType } from '@firebase/component';\nimport { FirebaseInstallations } from '@firebase/installations-types';\nimport {\n deleteInstallation,\n getId,\n getToken,\n IdChangeCallbackFn,\n IdChangeUnsubscribeFn,\n onIdChange\n} from './functions';\nimport { extractAppConfig } from './helpers/extract-app-config';\nimport { FirebaseDependencies } from './interfaces/firebase-dependencies';\n\nimport { name, version } from '../package.json';\n\nexport function registerInstallations(instance: _FirebaseNamespace): void {\n const installationsName = 'installations';\n\n instance.INTERNAL.registerComponent(\n new Component(\n installationsName,\n container => {\n const app = container.getProvider('app').getImmediate();\n\n // Throws if app isn't configured properly.\n const appConfig = extractAppConfig(app);\n const platformLoggerProvider = container.getProvider('platform-logger');\n const dependencies: FirebaseDependencies = {\n appConfig,\n platformLoggerProvider\n };\n\n const installations: FirebaseInstallations & FirebaseService = {\n app,\n getId: () => getId(dependencies),\n getToken: (forceRefresh?: boolean) =>\n getToken(dependencies, forceRefresh),\n delete: () => deleteInstallation(dependencies),\n onIdChange: (callback: IdChangeCallbackFn): IdChangeUnsubscribeFn =>\n onIdChange(dependencies, callback)\n };\n return installations;\n },\n ComponentType.PUBLIC\n )\n );\n\n instance.registerVersion(name, version);\n}\n\nregisterInstallations(firebase as _FirebaseNamespace);\n\n/**\n * Define extension behavior of `registerInstallations`\n */\ndeclare module '@firebase/app-types' {\n interface FirebaseNamespace {\n installations(app?: FirebaseApp): FirebaseInstallations;\n }\n interface FirebaseApp {\n installations(): FirebaseInstallations;\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createInstallationRequest } from '../api/create-installation-request';\nimport { AppConfig } from '../interfaces/app-config';\nimport {\n InProgressInstallationEntry,\n InstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { PENDING_TIMEOUT_MS } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';\nimport { sleep } from '../util/sleep';\nimport { generateFid, INVALID_FID } from './generate-fid';\nimport { remove, set, update } from './idb-manager';\n\nexport interface InstallationEntryWithRegistrationPromise {\n installationEntry: InstallationEntry;\n /** Exist iff the installationEntry is not registered. */\n registrationPromise?: Promise;\n}\n\n/**\n * Updates and returns the InstallationEntry from the database.\n * Also triggers a registration request if it is necessary and possible.\n */\nexport async function getInstallationEntry(\n appConfig: AppConfig\n): Promise {\n let registrationPromise: Promise | undefined;\n\n const installationEntry = await update(appConfig, oldEntry => {\n const installationEntry = updateOrCreateInstallationEntry(oldEntry);\n const entryWithPromise = triggerRegistrationIfNecessary(\n appConfig,\n installationEntry\n );\n registrationPromise = entryWithPromise.registrationPromise;\n return entryWithPromise.installationEntry;\n });\n\n if (installationEntry.fid === INVALID_FID) {\n // FID generation failed. Waiting for the FID from the server.\n return { installationEntry: await registrationPromise! };\n }\n\n return {\n installationEntry,\n registrationPromise\n };\n}\n\n/**\n * Creates a new Installation Entry if one does not exist.\n * Also clears timed out pending requests.\n */\nfunction updateOrCreateInstallationEntry(\n oldEntry: InstallationEntry | undefined\n): InstallationEntry {\n const entry: InstallationEntry = oldEntry || {\n fid: generateFid(),\n registrationStatus: RequestStatus.NOT_STARTED\n };\n\n return clearTimedOutRequest(entry);\n}\n\n/**\n * If the Firebase Installation is not registered yet, this will trigger the\n * registration and return an InProgressInstallationEntry.\n *\n * If registrationPromise does not exist, the installationEntry is guaranteed\n * to be registered.\n */\nfunction triggerRegistrationIfNecessary(\n appConfig: AppConfig,\n installationEntry: InstallationEntry\n): InstallationEntryWithRegistrationPromise {\n if (installationEntry.registrationStatus === RequestStatus.NOT_STARTED) {\n if (!navigator.onLine) {\n // Registration required but app is offline.\n const registrationPromiseWithError = Promise.reject(\n ERROR_FACTORY.create(ErrorCode.APP_OFFLINE)\n );\n return {\n installationEntry,\n registrationPromise: registrationPromiseWithError\n };\n }\n\n // Try registering. Change status to IN_PROGRESS.\n const inProgressEntry: InProgressInstallationEntry = {\n fid: installationEntry.fid,\n registrationStatus: RequestStatus.IN_PROGRESS,\n registrationTime: Date.now()\n };\n const registrationPromise = registerInstallation(\n appConfig,\n inProgressEntry\n );\n return { installationEntry: inProgressEntry, registrationPromise };\n } else if (\n installationEntry.registrationStatus === RequestStatus.IN_PROGRESS\n ) {\n return {\n installationEntry,\n registrationPromise: waitUntilFidRegistration(appConfig)\n };\n } else {\n return { installationEntry };\n }\n}\n\n/** This will be executed only once for each new Firebase Installation. */\nasync function registerInstallation(\n appConfig: AppConfig,\n installationEntry: InProgressInstallationEntry\n): Promise {\n try {\n const registeredInstallationEntry = await createInstallationRequest(\n appConfig,\n installationEntry\n );\n return set(appConfig, registeredInstallationEntry);\n } catch (e) {\n if (isServerError(e) && e.customData.serverCode === 409) {\n // Server returned a \"FID can not be used\" error.\n // Generate a new ID next time.\n await remove(appConfig);\n } else {\n // Registration failed. Set FID as not registered.\n await set(appConfig, {\n fid: installationEntry.fid,\n registrationStatus: RequestStatus.NOT_STARTED\n });\n }\n throw e;\n }\n}\n\n/** Call if FID registration is pending in another request. */\nasync function waitUntilFidRegistration(\n appConfig: AppConfig\n): Promise {\n // Unfortunately, there is no way of reliably observing when a value in\n // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),\n // so we need to poll.\n\n let entry: InstallationEntry = await updateInstallationRequest(appConfig);\n while (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n // createInstallation request still in progress.\n await sleep(100);\n\n entry = await updateInstallationRequest(appConfig);\n }\n\n if (entry.registrationStatus === RequestStatus.NOT_STARTED) {\n // The request timed out or failed in a different call. Try again.\n const {\n installationEntry,\n registrationPromise\n } = await getInstallationEntry(appConfig);\n\n if (registrationPromise) {\n return registrationPromise;\n } else {\n // if there is no registrationPromise, entry is registered.\n return installationEntry as RegisteredInstallationEntry;\n }\n }\n\n return entry;\n}\n\n/**\n * Called only if there is a CreateInstallation request in progress.\n *\n * Updates the InstallationEntry in the DB based on the status of the\n * CreateInstallation request.\n *\n * Returns the updated InstallationEntry.\n */\nfunction updateInstallationRequest(\n appConfig: AppConfig\n): Promise {\n return update(appConfig, oldEntry => {\n if (!oldEntry) {\n throw ERROR_FACTORY.create(ErrorCode.INSTALLATION_NOT_FOUND);\n }\n return clearTimedOutRequest(oldEntry);\n });\n}\n\nfunction clearTimedOutRequest(entry: InstallationEntry): InstallationEntry {\n if (hasInstallationRequestTimedOut(entry)) {\n return {\n fid: entry.fid,\n registrationStatus: RequestStatus.NOT_STARTED\n };\n }\n\n return entry;\n}\n\nfunction hasInstallationRequestTimedOut(\n installationEntry: InstallationEntry\n): boolean {\n return (\n installationEntry.registrationStatus === RequestStatus.IN_PROGRESS &&\n installationEntry.registrationTime + PENDING_TIMEOUT_MS < Date.now()\n );\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CreateInstallationResponse } from '../interfaces/api-response';\nimport { AppConfig } from '../interfaces/app-config';\nimport {\n InProgressInstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { INTERNAL_AUTH_VERSION, PACKAGE_VERSION } from '../util/constants';\nimport {\n extractAuthTokenInfoFromResponse,\n getErrorFromResponse,\n getHeaders,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\n\nexport async function createInstallationRequest(\n appConfig: AppConfig,\n { fid }: InProgressInstallationEntry\n): Promise {\n const endpoint = getInstallationsEndpoint(appConfig);\n\n const headers = getHeaders(appConfig);\n const body = {\n fid,\n authVersion: INTERNAL_AUTH_VERSION,\n appId: appConfig.appId,\n sdkVersion: PACKAGE_VERSION\n };\n\n const request: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (response.ok) {\n const responseValue: CreateInstallationResponse = await response.json();\n const registeredInstallationEntry: RegisteredInstallationEntry = {\n fid: responseValue.fid || fid,\n registrationStatus: RequestStatus.COMPLETED,\n refreshToken: responseValue.refreshToken,\n authToken: extractAuthTokenInfoFromResponse(responseValue.authToken)\n };\n return registeredInstallationEntry;\n } else {\n throw await getErrorFromResponse('Create Installation', response);\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { GenerateAuthTokenResponse } from '../interfaces/api-response';\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\nimport {\n CompletedAuthToken,\n RegisteredInstallationEntry\n} from '../interfaces/installation-entry';\nimport { PACKAGE_VERSION } from '../util/constants';\nimport {\n extractAuthTokenInfoFromResponse,\n getErrorFromResponse,\n getHeadersWithAuth,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\n\nexport async function generateAuthTokenRequest(\n { appConfig, platformLoggerProvider }: FirebaseDependencies,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n const endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);\n\n const headers = getHeadersWithAuth(appConfig, installationEntry);\n\n // If platform logger exists, add the platform info string to the header.\n const platformLogger = platformLoggerProvider.getImmediate({\n optional: true\n });\n if (platformLogger) {\n headers.append('x-firebase-client', platformLogger.getPlatformInfoString());\n }\n\n const body = {\n installation: {\n sdkVersion: PACKAGE_VERSION\n }\n };\n\n const request: RequestInit = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (response.ok) {\n const responseValue: GenerateAuthTokenResponse = await response.json();\n const completedAuthToken: CompletedAuthToken = extractAuthTokenInfoFromResponse(\n responseValue\n );\n return completedAuthToken;\n } else {\n throw await getErrorFromResponse('Generate Auth Token', response);\n }\n}\n\nfunction getGenerateAuthTokenEndpoint(\n appConfig: AppConfig,\n { fid }: RegisteredInstallationEntry\n): string {\n return `${getInstallationsEndpoint(appConfig)}/${fid}/authTokens:generate`;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { generateAuthTokenRequest } from '../api/generate-auth-token-request';\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\nimport {\n AuthToken,\n CompletedAuthToken,\n InProgressAuthToken,\n InstallationEntry,\n RegisteredInstallationEntry,\n RequestStatus\n} from '../interfaces/installation-entry';\nimport { PENDING_TIMEOUT_MS, TOKEN_EXPIRATION_BUFFER } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';\nimport { sleep } from '../util/sleep';\nimport { remove, set, update } from './idb-manager';\n\n/**\n * Returns a valid authentication token for the installation. Generates a new\n * token if one doesn't exist, is expired or about to expire.\n *\n * Should only be called if the Firebase Installation is registered.\n */\nexport async function refreshAuthToken(\n dependencies: FirebaseDependencies,\n forceRefresh = false\n): Promise {\n let tokenPromise: Promise | undefined;\n const entry = await update(dependencies.appConfig, oldEntry => {\n if (!isEntryRegistered(oldEntry)) {\n throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);\n }\n\n const oldAuthToken = oldEntry.authToken;\n if (!forceRefresh && isAuthTokenValid(oldAuthToken)) {\n // There is a valid token in the DB.\n return oldEntry;\n } else if (oldAuthToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // There already is a token request in progress.\n tokenPromise = waitUntilAuthTokenRequest(dependencies, forceRefresh);\n return oldEntry;\n } else {\n // No token or token expired.\n if (!navigator.onLine) {\n throw ERROR_FACTORY.create(ErrorCode.APP_OFFLINE);\n }\n\n const inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry);\n tokenPromise = fetchAuthTokenFromServer(dependencies, inProgressEntry);\n return inProgressEntry;\n }\n });\n\n const authToken = tokenPromise\n ? await tokenPromise\n : (entry.authToken as CompletedAuthToken);\n return authToken;\n}\n\n/**\n * Call only if FID is registered and Auth Token request is in progress.\n *\n * Waits until the current pending request finishes. If the request times out,\n * tries once in this thread as well.\n */\nasync function waitUntilAuthTokenRequest(\n dependencies: FirebaseDependencies,\n forceRefresh: boolean\n): Promise {\n // Unfortunately, there is no way of reliably observing when a value in\n // IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),\n // so we need to poll.\n\n let entry = await updateAuthTokenRequest(dependencies.appConfig);\n while (entry.authToken.requestStatus === RequestStatus.IN_PROGRESS) {\n // generateAuthToken still in progress.\n await sleep(100);\n\n entry = await updateAuthTokenRequest(dependencies.appConfig);\n }\n\n const authToken = entry.authToken;\n if (authToken.requestStatus === RequestStatus.NOT_STARTED) {\n // The request timed out or failed in a different call. Try again.\n return refreshAuthToken(dependencies, forceRefresh);\n } else {\n return authToken;\n }\n}\n\n/**\n * Called only if there is a GenerateAuthToken request in progress.\n *\n * Updates the InstallationEntry in the DB based on the status of the\n * GenerateAuthToken request.\n *\n * Returns the updated InstallationEntry.\n */\nfunction updateAuthTokenRequest(\n appConfig: AppConfig\n): Promise {\n return update(appConfig, oldEntry => {\n if (!isEntryRegistered(oldEntry)) {\n throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);\n }\n\n const oldAuthToken = oldEntry.authToken;\n if (hasAuthTokenRequestTimedOut(oldAuthToken)) {\n return {\n ...oldEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n }\n\n return oldEntry;\n });\n}\n\nasync function fetchAuthTokenFromServer(\n dependencies: FirebaseDependencies,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n try {\n const authToken = await generateAuthTokenRequest(\n dependencies,\n installationEntry\n );\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken\n };\n await set(dependencies.appConfig, updatedInstallationEntry);\n return authToken;\n } catch (e) {\n if (\n isServerError(e) &&\n (e.customData.serverCode === 401 || e.customData.serverCode === 404)\n ) {\n // Server returned a \"FID not found\" or a \"Invalid authentication\" error.\n // Generate a new ID next time.\n await remove(dependencies.appConfig);\n } else {\n const updatedInstallationEntry: RegisteredInstallationEntry = {\n ...installationEntry,\n authToken: { requestStatus: RequestStatus.NOT_STARTED }\n };\n await set(dependencies.appConfig, updatedInstallationEntry);\n }\n throw e;\n }\n}\n\nfunction isEntryRegistered(\n installationEntry: InstallationEntry | undefined\n): installationEntry is RegisteredInstallationEntry {\n return (\n installationEntry !== undefined &&\n installationEntry.registrationStatus === RequestStatus.COMPLETED\n );\n}\n\nfunction isAuthTokenValid(authToken: AuthToken): boolean {\n return (\n authToken.requestStatus === RequestStatus.COMPLETED &&\n !isAuthTokenExpired(authToken)\n );\n}\n\nfunction isAuthTokenExpired(authToken: CompletedAuthToken): boolean {\n const now = Date.now();\n return (\n now < authToken.creationTime ||\n authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER\n );\n}\n\n/** Returns an updated InstallationEntry with an InProgressAuthToken. */\nfunction makeAuthTokenRequestInProgressEntry(\n oldEntry: RegisteredInstallationEntry\n): RegisteredInstallationEntry {\n const inProgressAuthToken: InProgressAuthToken = {\n requestStatus: RequestStatus.IN_PROGRESS,\n requestTime: Date.now()\n };\n return {\n ...oldEntry,\n authToken: inProgressAuthToken\n };\n}\n\nfunction hasAuthTokenRequestTimedOut(authToken: AuthToken): boolean {\n return (\n authToken.requestStatus === RequestStatus.IN_PROGRESS &&\n authToken.requestTime + PENDING_TIMEOUT_MS < Date.now()\n );\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInstallationEntry } from '../helpers/get-installation-entry';\nimport { refreshAuthToken } from '../helpers/refresh-auth-token';\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\n\nexport async function getToken(\n dependencies: FirebaseDependencies,\n forceRefresh = false\n): Promise {\n await completeInstallationRegistration(dependencies.appConfig);\n\n // At this point we either have a Registered Installation in the DB, or we've\n // already thrown an error.\n const authToken = await refreshAuthToken(dependencies, forceRefresh);\n return authToken.token;\n}\n\nasync function completeInstallationRegistration(\n appConfig: AppConfig\n): Promise {\n const { registrationPromise } = await getInstallationEntry(appConfig);\n\n if (registrationPromise) {\n // A createInstallation request is in progress. Wait until it finishes.\n await registrationPromise;\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AppConfig } from '../interfaces/app-config';\nimport { RegisteredInstallationEntry } from '../interfaces/installation-entry';\nimport {\n getErrorFromResponse,\n getHeadersWithAuth,\n getInstallationsEndpoint,\n retryIfServerError\n} from './common';\n\nexport async function deleteInstallationRequest(\n appConfig: AppConfig,\n installationEntry: RegisteredInstallationEntry\n): Promise {\n const endpoint = getDeleteEndpoint(appConfig, installationEntry);\n\n const headers = getHeadersWithAuth(appConfig, installationEntry);\n const request: RequestInit = {\n method: 'DELETE',\n headers\n };\n\n const response = await retryIfServerError(() => fetch(endpoint, request));\n if (!response.ok) {\n throw await getErrorFromResponse('Delete Installation', response);\n }\n}\n\nfunction getDeleteEndpoint(\n appConfig: AppConfig,\n { fid }: RegisteredInstallationEntry\n): string {\n return `${getInstallationsEndpoint(appConfig)}/${fid}`;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { addCallback, removeCallback } from '../helpers/fid-changed';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\n\nexport type IdChangeCallbackFn = (installationId: string) => void;\nexport type IdChangeUnsubscribeFn = () => void;\n\n/**\n * Sets a new callback that will get called when Installation ID changes.\n * Returns an unsubscribe function that will remove the callback when called.\n */\nexport function onIdChange(\n { appConfig }: FirebaseDependencies,\n callback: IdChangeCallbackFn\n): IdChangeUnsubscribeFn {\n addCallback(appConfig, callback);\n\n return () => {\n removeCallback(appConfig, callback);\n };\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, FirebaseOptions } from '@firebase/app-types';\nimport { FirebaseError } from '@firebase/util';\nimport { AppConfig } from '../interfaces/app-config';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nexport function extractAppConfig(app: FirebaseApp): AppConfig {\n if (!app || !app.options) {\n throw getMissingValueError('App Configuration');\n }\n\n if (!app.name) {\n throw getMissingValueError('App Name');\n }\n\n // Required app config keys\n const configKeys: Array = [\n 'projectId',\n 'apiKey',\n 'appId'\n ];\n\n for (const keyName of configKeys) {\n if (!app.options[keyName]) {\n throw getMissingValueError(keyName);\n }\n }\n\n return {\n appName: app.name,\n projectId: app.options.projectId!,\n apiKey: app.options.apiKey!,\n appId: app.options.appId!\n };\n}\n\nfunction getMissingValueError(valueName: string): FirebaseError {\n return ERROR_FACTORY.create(ErrorCode.MISSING_APP_CONFIG_VALUES, {\n valueName\n });\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { getInstallationEntry } from '../helpers/get-installation-entry';\nimport { refreshAuthToken } from '../helpers/refresh-auth-token';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\n\nexport async function getId(\n dependencies: FirebaseDependencies\n): Promise {\n const { installationEntry, registrationPromise } = await getInstallationEntry(\n dependencies.appConfig\n );\n\n if (registrationPromise) {\n registrationPromise.catch(console.error);\n } else {\n // If the installation is already registered, update the authentication\n // token if needed.\n refreshAuthToken(dependencies).catch(console.error);\n }\n\n return installationEntry.fid;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { deleteInstallationRequest } from '../api/delete-installation-request';\nimport { remove, update } from '../helpers/idb-manager';\nimport { FirebaseDependencies } from '../interfaces/firebase-dependencies';\nimport { RequestStatus } from '../interfaces/installation-entry';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\n\nexport async function deleteInstallation(\n dependencies: FirebaseDependencies\n): Promise {\n const { appConfig } = dependencies;\n\n const entry = await update(appConfig, oldEntry => {\n if (oldEntry && oldEntry.registrationStatus === RequestStatus.NOT_STARTED) {\n // Delete the unregistered entry without sending a deleteInstallation request.\n return undefined;\n }\n return oldEntry;\n });\n\n if (entry) {\n if (entry.registrationStatus === RequestStatus.IN_PROGRESS) {\n // Can't delete while trying to register.\n throw ERROR_FACTORY.create(ErrorCode.DELETE_PENDING_REGISTRATION);\n } else if (entry.registrationStatus === RequestStatus.COMPLETED) {\n if (!navigator.onLine) {\n throw ERROR_FACTORY.create(ErrorCode.APP_OFFLINE);\n } else {\n await deleteInstallationRequest(appConfig, entry);\n await remove(appConfig);\n }\n }\n }\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum ErrorCode {\n MISSING_APP_CONFIG_VALUES = 'missing-app-config-values',\n AVAILABLE_IN_WINDOW = 'only-available-in-window',\n AVAILABLE_IN_SW = 'only-available-in-sw',\n PERMISSION_DEFAULT = 'permission-default',\n PERMISSION_BLOCKED = 'permission-blocked',\n UNSUPPORTED_BROWSER = 'unsupported-browser',\n FAILED_DEFAULT_REGISTRATION = 'failed-service-worker-registration',\n TOKEN_SUBSCRIBE_FAILED = 'token-subscribe-failed',\n TOKEN_SUBSCRIBE_NO_TOKEN = 'token-subscribe-no-token',\n TOKEN_UNSUBSCRIBE_FAILED = 'token-unsubscribe-failed',\n TOKEN_UPDATE_FAILED = 'token-update-failed',\n TOKEN_UPDATE_NO_TOKEN = 'token-update-no-token',\n INVALID_BG_HANDLER = 'invalid-bg-handler',\n USE_SW_AFTER_GET_TOKEN = 'use-sw-after-get-token',\n INVALID_SW_REGISTRATION = 'invalid-sw-registration',\n USE_VAPID_KEY_AFTER_GET_TOKEN = 'use-vapid-key-after-get-token',\n INVALID_VAPID_KEY = 'invalid-vapid-key'\n}\n\nexport const ERROR_MAP: ErrorMap = {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]:\n 'Missing App configuration value: \"{$valueName}\"',\n [ErrorCode.AVAILABLE_IN_WINDOW]:\n 'This method is available in a Window context.',\n [ErrorCode.AVAILABLE_IN_SW]:\n 'This method is available in a service worker context.',\n [ErrorCode.PERMISSION_DEFAULT]:\n 'The notification permission was not granted and dismissed instead.',\n [ErrorCode.PERMISSION_BLOCKED]:\n 'The notification permission was not granted and blocked instead.',\n [ErrorCode.UNSUPPORTED_BROWSER]:\n \"This browser doesn't support the API's required to use the firebase SDK.\",\n [ErrorCode.FAILED_DEFAULT_REGISTRATION]:\n 'We are unable to register the default service worker. {$browserErrorMessage}',\n [ErrorCode.TOKEN_SUBSCRIBE_FAILED]:\n 'A problem occurred while subscribing the user to FCM: {$errorInfo}',\n [ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN]:\n 'FCM returned no token when subscribing the user to push.',\n [ErrorCode.TOKEN_UNSUBSCRIBE_FAILED]:\n 'A problem occurred while unsubscribing the ' +\n 'user from FCM: {$errorInfo}',\n [ErrorCode.TOKEN_UPDATE_FAILED]:\n 'A problem occurred while updating the user from FCM: {$errorInfo}',\n [ErrorCode.TOKEN_UPDATE_NO_TOKEN]:\n 'FCM returned no token when updating the user to push.',\n [ErrorCode.USE_SW_AFTER_GET_TOKEN]:\n 'The useServiceWorker() method may only be called once and must be ' +\n 'called before calling getToken() to ensure your service worker is used.',\n [ErrorCode.INVALID_SW_REGISTRATION]:\n 'The input to useServiceWorker() must be a ServiceWorkerRegistration.',\n [ErrorCode.INVALID_BG_HANDLER]:\n 'The input to setBackgroundMessageHandler() must be a function.',\n [ErrorCode.INVALID_VAPID_KEY]: 'The public VAPID key must be a string.',\n [ErrorCode.USE_VAPID_KEY_AFTER_GET_TOKEN]:\n 'The usePublicVapidKey() method may only be called once and must be ' +\n 'called before calling getToken() to ensure your VAPID key is used.'\n};\n\ninterface ErrorParams {\n [ErrorCode.MISSING_APP_CONFIG_VALUES]: {\n valueName: string;\n };\n [ErrorCode.FAILED_DEFAULT_REGISTRATION]: { browserErrorMessage: string };\n [ErrorCode.TOKEN_SUBSCRIBE_FAILED]: { errorInfo: string };\n [ErrorCode.TOKEN_UNSUBSCRIBE_FAILED]: { errorInfo: string };\n [ErrorCode.TOKEN_UPDATE_FAILED]: { errorInfo: string };\n}\n\nexport const ERROR_FACTORY = new ErrorFactory(\n 'messaging',\n 'Messaging',\n ERROR_MAP\n);\n","/**\n * @license\n * Copyright 2018 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under the License\n * is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\n * or implied. See the License for the specific language governing permissions and limitations under\n * the License.\n */\n\nimport {\n CONSOLE_CAMPAIGN_ANALYTICS_ENABLED,\n CONSOLE_CAMPAIGN_ID,\n CONSOLE_CAMPAIGN_NAME,\n CONSOLE_CAMPAIGN_TIME\n} from '../util/constants';\n\nexport interface MessagePayloadInternal {\n notification?: NotificationPayloadInternal;\n data?: unknown;\n fcmOptions?: FcmOptionsInternal;\n messageType?: MessageType;\n isFirebaseMessaging?: boolean;\n from: string;\n // eslint-disable-next-line camelcase\n collapse_key: string;\n}\n\nexport interface NotificationPayloadInternal extends NotificationOptions {\n title: string;\n // Supported in the Legacy Send API.\n // See:https://firebase.google.com/docs/cloud-messaging/xmpp-server-ref.\n // eslint-disable-next-line camelcase\n click_action?: string;\n}\n\n// Defined in\n// https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#webpushfcmoptions. Note\n// that the keys are sent to the clients in snake cases which we need to convert to camel so it can\n// be exposed as a type to match the Firebase API convention.\nexport interface FcmOptionsInternal {\n link?: string;\n\n // eslint-disable-next-line camelcase\n analytics_label?: string;\n}\n\nexport enum MessageType {\n PUSH_RECEIVED = 'push-received',\n NOTIFICATION_CLICKED = 'notification-clicked'\n}\n\n/** Additional data of a message sent from the FN Console. */\nexport interface ConsoleMessageData {\n [CONSOLE_CAMPAIGN_ID]: string;\n [CONSOLE_CAMPAIGN_TIME]: string;\n [CONSOLE_CAMPAIGN_NAME]?: string;\n [CONSOLE_CAMPAIGN_ANALYTICS_ENABLED]?: '1';\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const DEFAULT_SW_PATH = '/firebase-messaging-sw.js';\nexport const DEFAULT_SW_SCOPE = '/firebase-cloud-messaging-push-scope';\n\nexport const DEFAULT_VAPID_KEY =\n 'BDOU99-h67HcA6JeFXHbSNMu7e2yNNu3RzoMj8TM4W88jITfq7ZmPvIM1Iv-4_l2LxQcYwhqby2xGpWwzjfAnG4';\n\nexport const ENDPOINT = 'https://fcmregistrations.googleapis.com/v1';\n\n// Key of FCM Payload in Notification's data field.\nexport const FCM_MSG = 'FCM_MSG';\nexport const TAG = 'FirebaseMessaging: ';\n\n// Set to '1' if Analytics is enabled for the campaign\nexport const CONSOLE_CAMPAIGN_ANALYTICS_ENABLED = 'google.c.a.e';\nexport const CONSOLE_CAMPAIGN_ID = 'google.c.a.c_id';\nexport const CONSOLE_CAMPAIGN_TIME = 'google.c.a.ts';\nexport const CONSOLE_CAMPAIGN_NAME = 'google.c.a.c_l';\n\n// Due to the fact that onBackgroundMessage can't be awaited (to support rxjs), a silent push\n// warning might be shown by the browser if the callback fails to completes by the end of onPush.\n// Experiments were ran to determine the majority onBackground message clock time. This brief\n// blocking time would allow majority of the onBackgroundMessage callback to finish.\nexport const BACKGROUND_HANDLE_EXECUTION_TIME_LIMIT_MS = 1000;\n\n// Preparation time for client to initialize and set up the message handler.\nexport const FOREGROUND_HANDLE_PREPARATION_TIME_MS = 3000;\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function arrayToBase64(array: Uint8Array | ArrayBuffer): string {\n const uint8Array = new Uint8Array(array);\n const base64String = btoa(String.fromCharCode(...uint8Array));\n return base64String.replace(/=/g, '').replace(/\\+/g, '-').replace(/\\//g, '_');\n}\n\nexport function base64ToArray(base64String: string): Uint8Array {\n const padding = '='.repeat((4 - (base64String.length % 4)) % 4);\n const base64 = (base64String + padding)\n .replace(/\\-/g, '+')\n .replace(/_/g, '/');\n\n const rawData = atob(base64);\n const outputArray = new Uint8Array(rawData.length);\n\n for (let i = 0; i < rawData.length; ++i) {\n outputArray[i] = rawData.charCodeAt(i);\n }\n return outputArray;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { deleteDb, openDb } from 'idb';\n\nimport { TokenDetails } from '../interfaces/token-details';\nimport { arrayToBase64 } from './array-base64-translator';\n\n// https://github.com/firebase/firebase-js-sdk/blob/7857c212f944a2a9eb421fd4cb7370181bc034b5/packages/messaging/src/interfaces/token-details.ts\nexport interface V2TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: string | Uint8Array;\n subscription: PushSubscription;\n fcmSenderId: string;\n fcmPushSet: string;\n createTime?: number;\n endpoint?: string;\n auth?: string;\n p256dh?: string;\n}\n\n// https://github.com/firebase/firebase-js-sdk/blob/6b5b15ce4ea3df5df5df8a8b33a4e41e249c7715/packages/messaging/src/interfaces/token-details.ts\nexport interface V3TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: Uint8Array;\n fcmSenderId: string;\n fcmPushSet: string;\n endpoint: string;\n auth: ArrayBuffer;\n p256dh: ArrayBuffer;\n createTime: number;\n}\n\n// https://github.com/firebase/firebase-js-sdk/blob/9567dba664732f681fa7fe60f5b7032bb1daf4c9/packages/messaging/src/interfaces/token-details.ts\nexport interface V4TokenDetails {\n fcmToken: string;\n swScope: string;\n vapidKey: Uint8Array;\n fcmSenderId: string;\n endpoint: string;\n auth: ArrayBufferLike;\n p256dh: ArrayBufferLike;\n createTime: number;\n}\n\nconst OLD_DB_NAME = 'fcm_token_details_db';\n/**\n * The last DB version of 'fcm_token_details_db' was 4. This is one higher, so that the upgrade\n * callback is called for all versions of the old DB.\n */\nconst OLD_DB_VERSION = 5;\nconst OLD_OBJECT_STORE_NAME = 'fcm_token_object_Store';\n\nexport async function migrateOldDatabase(\n senderId: string\n): Promise {\n if ('databases' in indexedDB) {\n // indexedDb.databases() is an IndexedDB v3 API and does not exist in all browsers. TODO: Remove\n // typecast when it lands in TS types.\n const databases = await (indexedDB as {\n databases(): Promise>;\n }).databases();\n const dbNames = databases.map(db => db.name);\n\n if (!dbNames.includes(OLD_DB_NAME)) {\n // old DB didn't exist, no need to open.\n return null;\n }\n }\n\n let tokenDetails: TokenDetails | null = null;\n\n const db = await openDb(OLD_DB_NAME, OLD_DB_VERSION, async db => {\n if (db.oldVersion < 2) {\n // Database too old, skip migration.\n return;\n }\n\n if (!db.objectStoreNames.contains(OLD_OBJECT_STORE_NAME)) {\n // Database did not exist. Nothing to do.\n return;\n }\n\n const objectStore = db.transaction.objectStore(OLD_OBJECT_STORE_NAME);\n const value = await objectStore.index('fcmSenderId').get(senderId);\n await objectStore.clear();\n\n if (!value) {\n // No entry in the database, nothing to migrate.\n return;\n }\n\n if (db.oldVersion === 2) {\n const oldDetails = value as V2TokenDetails;\n\n if (!oldDetails.auth || !oldDetails.p256dh || !oldDetails.endpoint) {\n return;\n }\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime ?? Date.now(),\n subscriptionOptions: {\n auth: oldDetails.auth,\n p256dh: oldDetails.p256dh,\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey:\n typeof oldDetails.vapidKey === 'string'\n ? oldDetails.vapidKey\n : arrayToBase64(oldDetails.vapidKey)\n }\n };\n } else if (db.oldVersion === 3) {\n const oldDetails = value as V3TokenDetails;\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime,\n subscriptionOptions: {\n auth: arrayToBase64(oldDetails.auth),\n p256dh: arrayToBase64(oldDetails.p256dh),\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey: arrayToBase64(oldDetails.vapidKey)\n }\n };\n } else if (db.oldVersion === 4) {\n const oldDetails = value as V4TokenDetails;\n\n tokenDetails = {\n token: oldDetails.fcmToken,\n createTime: oldDetails.createTime,\n subscriptionOptions: {\n auth: arrayToBase64(oldDetails.auth),\n p256dh: arrayToBase64(oldDetails.p256dh),\n endpoint: oldDetails.endpoint,\n swScope: oldDetails.swScope,\n vapidKey: arrayToBase64(oldDetails.vapidKey)\n }\n };\n }\n });\n db.close();\n\n // Delete all old databases.\n await deleteDb(OLD_DB_NAME);\n await deleteDb('fcm_vapid_details_db');\n await deleteDb('undefined');\n\n return checkTokenDetails(tokenDetails) ? tokenDetails : null;\n}\n\nfunction checkTokenDetails(\n tokenDetails: TokenDetails | null\n): tokenDetails is TokenDetails {\n if (!tokenDetails || !tokenDetails.subscriptionOptions) {\n return false;\n }\n const { subscriptionOptions } = tokenDetails;\n return (\n typeof tokenDetails.createTime === 'number' &&\n tokenDetails.createTime > 0 &&\n typeof tokenDetails.token === 'string' &&\n tokenDetails.token.length > 0 &&\n typeof subscriptionOptions.auth === 'string' &&\n subscriptionOptions.auth.length > 0 &&\n typeof subscriptionOptions.p256dh === 'string' &&\n subscriptionOptions.p256dh.length > 0 &&\n typeof subscriptionOptions.endpoint === 'string' &&\n subscriptionOptions.endpoint.length > 0 &&\n typeof subscriptionOptions.swScope === 'string' &&\n subscriptionOptions.swScope.length > 0 &&\n typeof subscriptionOptions.vapidKey === 'string' &&\n subscriptionOptions.vapidKey.length > 0\n );\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DB, deleteDb, openDb } from 'idb';\n\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { TokenDetails } from '../interfaces/token-details';\nimport { migrateOldDatabase } from './migrate-old-database';\n\n// Exported for tests.\nexport const DATABASE_NAME = 'firebase-messaging-database';\nconst DATABASE_VERSION = 1;\nconst OBJECT_STORE_NAME = 'firebase-messaging-store';\n\nlet dbPromise: Promise | null = null;\nfunction getDbPromise(): Promise {\n if (!dbPromise) {\n dbPromise = openDb(DATABASE_NAME, DATABASE_VERSION, upgradeDb => {\n // We don't use 'break' in this switch statement, the fall-through behavior is what we want,\n // because if there are multiple versions between the old version and the current version, we\n // want ALL the migrations that correspond to those versions to run, not only the last one.\n // eslint-disable-next-line default-case\n switch (upgradeDb.oldVersion) {\n case 0:\n upgradeDb.createObjectStore(OBJECT_STORE_NAME);\n }\n });\n }\n return dbPromise;\n}\n\n/** Gets record(s) from the objectStore that match the given key. */\nexport async function dbGet(\n firebaseDependencies: FirebaseInternalDependencies\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tokenDetails = await db\n .transaction(OBJECT_STORE_NAME)\n .objectStore(OBJECT_STORE_NAME)\n .get(key);\n\n if (tokenDetails) {\n return tokenDetails;\n } else {\n // Check if there is a tokenDetails object in the old DB.\n const oldTokenDetails = await migrateOldDatabase(\n firebaseDependencies.appConfig.senderId\n );\n if (oldTokenDetails) {\n await dbSet(firebaseDependencies, oldTokenDetails);\n return oldTokenDetails;\n }\n }\n}\n\n/** Assigns or overwrites the record for the given key with the given value. */\nexport async function dbSet(\n firebaseDependencies: FirebaseInternalDependencies,\n tokenDetails: TokenDetails\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).put(tokenDetails, key);\n await tx.complete;\n return tokenDetails;\n}\n\n/** Removes record(s) from the objectStore that match the given key. */\nexport async function dbRemove(\n firebaseDependencies: FirebaseInternalDependencies\n): Promise {\n const key = getKey(firebaseDependencies);\n const db = await getDbPromise();\n const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');\n await tx.objectStore(OBJECT_STORE_NAME).delete(key);\n await tx.complete;\n}\n\n/** Deletes the DB. Useful for tests. */\nexport async function dbDelete(): Promise {\n if (dbPromise) {\n (await dbPromise).close();\n await deleteDb(DATABASE_NAME);\n dbPromise = null;\n }\n}\n\nfunction getKey({ appConfig }: FirebaseInternalDependencies): string {\n return appConfig.appId;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { DEFAULT_VAPID_KEY, ENDPOINT } from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { SubscriptionOptions, TokenDetails } from '../interfaces/token-details';\n\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\n\nexport interface ApiResponse {\n token?: string;\n error?: { message: string };\n}\n\nexport interface ApiRequestBody {\n web: {\n endpoint: string;\n p256dh: string;\n auth: string;\n applicationPubKey?: string;\n };\n}\n\nexport async function requestGetToken(\n firebaseDependencies: FirebaseInternalDependencies,\n subscriptionOptions: SubscriptionOptions\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n const body = getBody(subscriptionOptions);\n\n const subscribeOptions = {\n method: 'POST',\n headers,\n body: JSON.stringify(body)\n };\n\n let responseData: ApiResponse;\n try {\n const response = await fetch(\n getEndpoint(firebaseDependencies.appConfig),\n subscribeOptions\n );\n responseData = await response.json();\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, {\n errorInfo: err\n });\n }\n\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, {\n errorInfo: message\n });\n }\n\n if (!responseData.token) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN);\n }\n\n return responseData.token;\n}\n\nexport async function requestUpdateToken(\n firebaseDependencies: FirebaseInternalDependencies,\n tokenDetails: TokenDetails\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n const body = getBody(tokenDetails.subscriptionOptions!);\n\n const updateOptions = {\n method: 'PATCH',\n headers,\n body: JSON.stringify(body)\n };\n\n let responseData: ApiResponse;\n try {\n const response = await fetch(\n `${getEndpoint(firebaseDependencies.appConfig)}/${tokenDetails.token}`,\n updateOptions\n );\n responseData = await response.json();\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_FAILED, {\n errorInfo: err\n });\n }\n\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_FAILED, {\n errorInfo: message\n });\n }\n\n if (!responseData.token) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UPDATE_NO_TOKEN);\n }\n\n return responseData.token;\n}\n\nexport async function requestDeleteToken(\n firebaseDependencies: FirebaseInternalDependencies,\n token: string\n): Promise {\n const headers = await getHeaders(firebaseDependencies);\n\n const unsubscribeOptions = {\n method: 'DELETE',\n headers\n };\n\n try {\n const response = await fetch(\n `${getEndpoint(firebaseDependencies.appConfig)}/${token}`,\n unsubscribeOptions\n );\n const responseData: ApiResponse = await response.json();\n if (responseData.error) {\n const message = responseData.error.message;\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED, {\n errorInfo: message\n });\n }\n } catch (err) {\n throw ERROR_FACTORY.create(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED, {\n errorInfo: err\n });\n }\n}\n\nfunction getEndpoint({ projectId }: AppConfig): string {\n return `${ENDPOINT}/projects/${projectId!}/registrations`;\n}\n\nasync function getHeaders({\n appConfig,\n installations\n}: FirebaseInternalDependencies): Promise {\n const authToken = await installations.getToken();\n\n return new Headers({\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'x-goog-api-key': appConfig.apiKey!,\n 'x-goog-firebase-installations-auth': `FIS ${authToken}`\n });\n}\n\nfunction getBody({\n p256dh,\n auth,\n endpoint,\n vapidKey\n}: SubscriptionOptions): ApiRequestBody {\n const body: ApiRequestBody = {\n web: {\n endpoint,\n auth,\n p256dh\n }\n };\n\n if (vapidKey !== DEFAULT_VAPID_KEY) {\n body.web.applicationPubKey = vapidKey;\n }\n\n return body;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { SubscriptionOptions, TokenDetails } from '../interfaces/token-details';\nimport {\n arrayToBase64,\n base64ToArray\n} from '../helpers/array-base64-translator';\nimport { dbGet, dbRemove, dbSet } from '../helpers/idb-manager';\nimport { requestDeleteToken, requestGetToken, requestUpdateToken } from './api';\n\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\n\n/** UpdateRegistration will be called once every week. */\nconst TOKEN_EXPIRATION_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\nexport async function getToken(\n firebaseDependencies: FirebaseInternalDependencies,\n swRegistration: ServiceWorkerRegistration,\n vapidKey: string\n): Promise {\n if (Notification.permission !== 'granted') {\n throw ERROR_FACTORY.create(ErrorCode.PERMISSION_BLOCKED);\n }\n\n // If a PushSubscription exists it's returned, otherwise a new subscription is generated and\n // returned.\n const pushSubscription = await getPushSubscription(swRegistration, vapidKey);\n const tokenDetails = await dbGet(firebaseDependencies);\n\n const subscriptionOptions: SubscriptionOptions = {\n vapidKey,\n swScope: swRegistration.scope,\n endpoint: pushSubscription.endpoint,\n auth: arrayToBase64(pushSubscription.getKey('auth')!),\n p256dh: arrayToBase64(pushSubscription.getKey('p256dh')!)\n };\n\n if (!tokenDetails) {\n // No token, get a new one.\n return getNewToken(firebaseDependencies, subscriptionOptions);\n } else if (\n !isTokenValid(tokenDetails.subscriptionOptions!, subscriptionOptions)\n ) {\n // Invalid token, get a new one.\n try {\n await requestDeleteToken(firebaseDependencies, tokenDetails.token);\n } catch (e) {\n // Suppress errors because of #2364\n console.warn(e);\n }\n\n return getNewToken(firebaseDependencies, subscriptionOptions);\n } else if (Date.now() >= tokenDetails.createTime + TOKEN_EXPIRATION_MS) {\n // Weekly token refresh\n return updateToken(\n {\n token: tokenDetails.token,\n createTime: Date.now(),\n subscriptionOptions\n },\n firebaseDependencies,\n swRegistration\n );\n } else {\n // Valid token, nothing to do.\n return tokenDetails.token;\n }\n}\n\n/**\n * This method deletes the token from the database, unsubscribes the token from FCM, and unregisters\n * the push subscription if it exists.\n */\nexport async function deleteToken(\n firebaseDependencies: FirebaseInternalDependencies,\n swRegistration: ServiceWorkerRegistration\n): Promise {\n const tokenDetails = await dbGet(firebaseDependencies);\n if (tokenDetails) {\n await requestDeleteToken(firebaseDependencies, tokenDetails.token);\n await dbRemove(firebaseDependencies);\n }\n\n // Unsubscribe from the push subscription.\n const pushSubscription = await swRegistration.pushManager.getSubscription();\n if (pushSubscription) {\n return pushSubscription.unsubscribe();\n }\n\n // If there's no SW, consider it a success.\n return true;\n}\n\nasync function updateToken(\n tokenDetails: TokenDetails,\n firebaseDependencies: FirebaseInternalDependencies,\n swRegistration: ServiceWorkerRegistration\n): Promise {\n try {\n const updatedToken = await requestUpdateToken(\n firebaseDependencies,\n tokenDetails\n );\n\n const updatedTokenDetails: TokenDetails = {\n ...tokenDetails,\n token: updatedToken,\n createTime: Date.now()\n };\n\n await dbSet(firebaseDependencies, updatedTokenDetails);\n return updatedToken;\n } catch (e) {\n await deleteToken(firebaseDependencies, swRegistration);\n throw e;\n }\n}\n\nasync function getNewToken(\n firebaseDependencies: FirebaseInternalDependencies,\n subscriptionOptions: SubscriptionOptions\n): Promise {\n const token = await requestGetToken(\n firebaseDependencies,\n subscriptionOptions\n );\n const tokenDetails: TokenDetails = {\n token,\n createTime: Date.now(),\n subscriptionOptions\n };\n await dbSet(firebaseDependencies, tokenDetails);\n return tokenDetails.token;\n}\n\n/**\n * Gets a PushSubscription for the current user.\n */\nasync function getPushSubscription(\n swRegistration: ServiceWorkerRegistration,\n vapidKey: string\n): Promise {\n const subscription = await swRegistration.pushManager.getSubscription();\n if (subscription) {\n return subscription;\n }\n return swRegistration.pushManager.subscribe({\n userVisibleOnly: true,\n // Chrome <= 75 doesn't support base64-encoded VAPID key. For backward compatibility, VAPID key\n // submitted to pushManager#subscribe must be of type Uint8Array.\n applicationServerKey: base64ToArray(vapidKey)\n });\n}\n\n/**\n * Checks if the saved tokenDetails object matches the configuration provided.\n */\nfunction isTokenValid(\n dbOptions: SubscriptionOptions,\n currentOptions: SubscriptionOptions\n): boolean {\n const isVapidKeyEqual = currentOptions.vapidKey === dbOptions.vapidKey;\n const isEndpointEqual = currentOptions.endpoint === dbOptions.endpoint;\n const isAuthEqual = currentOptions.auth === dbOptions.auth;\n const isP256dhEqual = currentOptions.p256dh === dbOptions.p256dh;\n\n return isVapidKeyEqual && isEndpointEqual && isAuthEqual && isP256dhEqual;\n}\n","/**\n * @license\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MessagePayload } from '@firebase/messaging-types';\nimport { MessagePayloadInternal } from '../interfaces/internal-message-payload';\n\nexport function externalizePayload(\n internalPayload: MessagePayloadInternal\n): MessagePayload {\n const payload: MessagePayload = {\n from: internalPayload.from,\n // eslint-disable-next-line camelcase\n collapseKey: internalPayload.collapse_key\n } as MessagePayload;\n\n propagateNotificationPayload(payload, internalPayload);\n propagateDataPayload(payload, internalPayload);\n propagateFcmOptions(payload, internalPayload);\n\n return payload;\n}\n\nfunction propagateNotificationPayload(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n if (!messagePayloadInternal.notification) {\n return;\n }\n\n payload.notification = {};\n\n const title = messagePayloadInternal.notification!.title;\n if (!!title) {\n payload.notification!.title = title;\n }\n\n const body = messagePayloadInternal.notification!.body;\n if (!!body) {\n payload.notification!.body = body;\n }\n\n const image = messagePayloadInternal.notification!.image;\n if (!!image) {\n payload.notification!.image = image;\n }\n}\n\nfunction propagateDataPayload(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n if (!messagePayloadInternal.data) {\n return;\n }\n\n payload.data = messagePayloadInternal.data as { [key: string]: string };\n}\n\nfunction propagateFcmOptions(\n payload: MessagePayload,\n messagePayloadInternal: MessagePayloadInternal\n): void {\n if (!messagePayloadInternal.fcmOptions) {\n return;\n }\n\n payload.fcmOptions = {};\n\n const link = messagePayloadInternal.fcmOptions!.link;\n if (!!link) {\n payload.fcmOptions!.link = link;\n }\n\n // eslint-disable-next-line camelcase\n const analyticsLabel = messagePayloadInternal.fcmOptions!.analytics_label;\n if (!!analyticsLabel) {\n payload.fcmOptions!.analyticsLabel = analyticsLabel;\n }\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { CONSOLE_CAMPAIGN_ID } from '../util/constants';\nimport { ConsoleMessageData } from '../interfaces/internal-message-payload';\n\nexport function isConsoleMessage(data: unknown): data is ConsoleMessageData {\n // This message has a campaign ID, meaning it was sent using the Firebase Console.\n return typeof data === 'object' && !!data && CONSOLE_CAMPAIGN_ID in data;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/** Returns a promise that resolves after given time passes. */\nexport function sleep(ms: number): Promise {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n BACKGROUND_HANDLE_EXECUTION_TIME_LIMIT_MS,\n DEFAULT_VAPID_KEY,\n FCM_MSG,\n FOREGROUND_HANDLE_PREPARATION_TIME_MS,\n TAG\n} from '../util/constants';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { FirebaseMessaging, MessagePayload } from '@firebase/messaging-types';\nimport {\n MessagePayloadInternal,\n MessageType,\n NotificationPayloadInternal\n} from '../interfaces/internal-message-payload';\nimport { NextFn, Observer, Unsubscribe } from '@firebase/util';\nimport { deleteToken, getToken } from '../core/token-management';\n\nimport { FirebaseApp } from '@firebase/app-types';\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { FirebaseService } from '@firebase/app-types/private';\nimport { dbGet } from '../helpers/idb-manager';\nimport { externalizePayload } from '../helpers/externalizePayload';\nimport { isConsoleMessage } from '../helpers/is-console-message';\nimport { sleep } from '../helpers/sleep';\n\n// Let TS know that this is a service worker\ndeclare const self: ServiceWorkerGlobalScope;\n\nexport type BgMessageHandler = (payload: MessagePayload) => unknown;\n\nexport class SwController implements FirebaseMessaging, FirebaseService {\n // A boolean flag to determine wether an app is using onBackgroundMessage or\n // setBackgroundMessageHandler. onBackgroundMessage will receive a MessagePayload regardless of if\n // a notification is displayed. Whereas, setBackgroundMessageHandler will swallow the\n // MessagePayload if a NotificationPayload is included.\n private isOnBackgroundMessageUsed: boolean | null = null;\n private vapidKey: string | null = null;\n private bgMessageHandler:\n | null\n | BgMessageHandler\n | NextFn\n | Observer = null;\n\n constructor(\n private readonly firebaseDependencies: FirebaseInternalDependencies\n ) {\n self.addEventListener('push', e => {\n e.waitUntil(this.onPush(e));\n });\n self.addEventListener('pushsubscriptionchange', e => {\n e.waitUntil(this.onSubChange(e));\n });\n self.addEventListener('notificationclick', e => {\n e.waitUntil(this.onNotificationClick(e));\n });\n }\n\n get app(): FirebaseApp {\n return this.firebaseDependencies.app;\n }\n\n /**\n * @deprecated. Use onBackgroundMessage(nextOrObserver: NextFn | Observer):\n * Unsubscribe instead.\n *\n * Calling setBackgroundMessageHandler will opt in to some specific behaviors.\n *\n * 1.) If a notification doesn't need to be shown due to a window already being visible, then push\n * messages will be sent to the page. 2.) If a notification needs to be shown, and the message\n * contains no notification data this method will be called and the promise it returns will be\n * passed to event.waitUntil. If you do not set this callback then all push messages will let and\n * the developer can handle them in a their own 'push' event callback\n *\n * @param callback The callback to be called when a push message is received and a notification\n * must be shown. The callback will be given the data from the push message.\n */\n setBackgroundMessageHandler(callback: BgMessageHandler): void {\n this.isOnBackgroundMessageUsed = false;\n\n if (!callback || typeof callback !== 'function') {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_BG_HANDLER);\n }\n\n this.bgMessageHandler = callback;\n }\n\n onBackgroundMessage(\n nextOrObserver: NextFn | Observer\n ): Unsubscribe {\n this.isOnBackgroundMessageUsed = true;\n this.bgMessageHandler = nextOrObserver;\n\n return () => {\n this.bgMessageHandler = null;\n };\n }\n\n // TODO: Remove getToken from SW Controller. Calling this from an old SW can cause all kinds of\n // trouble.\n async getToken(): Promise {\n if (!this.vapidKey) {\n // Call getToken using the current VAPID key if there already is a token. This is needed\n // because usePublicVapidKey was not available in SW. It will be removed when vapidKey becomes\n // a parameter of getToken, or when getToken is removed from SW.\n const tokenDetails = await dbGet(this.firebaseDependencies);\n this.vapidKey =\n tokenDetails?.subscriptionOptions?.vapidKey ?? DEFAULT_VAPID_KEY;\n }\n\n return getToken(\n this.firebaseDependencies,\n self.registration,\n this.vapidKey\n );\n }\n\n // TODO: Remove deleteToken from SW Controller. Calling this from an old SW can cause all kinds of\n // trouble.\n deleteToken(): Promise {\n return deleteToken(this.firebaseDependencies, self.registration);\n }\n\n requestPermission(): Promise {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_WINDOW);\n }\n\n // TODO: Remove this together with getToken from SW Controller.\n usePublicVapidKey(vapidKey: string): void {\n if (this.vapidKey !== null) {\n throw ERROR_FACTORY.create(ErrorCode.USE_VAPID_KEY_AFTER_GET_TOKEN);\n }\n\n if (typeof vapidKey !== 'string' || vapidKey.length === 0) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_VAPID_KEY);\n }\n\n this.vapidKey = vapidKey;\n }\n\n useServiceWorker(): void {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_WINDOW);\n }\n\n onMessage(): Unsubscribe {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_WINDOW);\n }\n\n onTokenRefresh(): Unsubscribe {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_WINDOW);\n }\n\n /**\n * A handler for push events that shows notifications based on the content of the payload.\n *\n * The payload must be a JSON-encoded Object with a `notification` key. The value of the\n * `notification` property will be used as the NotificationOptions object passed to\n * showNotification. Additionally, the `title` property of the notification object will be used as\n * the title.\n *\n * If there is no notification data in the payload then no notification will be shown.\n */\n async onPush(event: PushEvent): Promise {\n const internalPayload = getMessagePayloadInternal(event);\n if (!internalPayload) {\n console.debug(\n TAG +\n 'failed to get parsed MessagePayload from the PushEvent. Skip handling the push.'\n );\n return;\n }\n\n // foreground handling: eventually passed to onMessage hook\n const clientList = await getClientList();\n if (hasVisibleClients(clientList)) {\n return sendMessagePayloadInternalToWindows(clientList, internalPayload);\n }\n\n // background handling: display and pass to onBackgroundMessage hook\n let isNotificationShown = false;\n if (!!internalPayload.notification) {\n await showNotification(wrapInternalPayload(internalPayload));\n isNotificationShown = true;\n }\n\n // MessagePayload is only passed to `onBackgroundMessage`. Skip passing MessagePayload for\n // the legacy `setBackgroundMessageHandler` to preserve the SDK behaviors.\n if (\n isNotificationShown === true &&\n this.isOnBackgroundMessageUsed === false\n ) {\n return;\n }\n\n if (!!this.bgMessageHandler) {\n const payload = externalizePayload(internalPayload);\n\n if (typeof this.bgMessageHandler === 'function') {\n this.bgMessageHandler(payload);\n } else {\n this.bgMessageHandler.next(payload);\n }\n }\n\n // wait briefly to allow onBackgroundMessage to complete\n await sleep(BACKGROUND_HANDLE_EXECUTION_TIME_LIMIT_MS);\n }\n\n async onSubChange(event: PushSubscriptionChangeEvent): Promise {\n const { newSubscription } = event;\n if (!newSubscription) {\n // Subscription revoked, delete token\n await deleteToken(this.firebaseDependencies, self.registration);\n return;\n }\n\n const tokenDetails = await dbGet(this.firebaseDependencies);\n await deleteToken(this.firebaseDependencies, self.registration);\n await getToken(\n this.firebaseDependencies,\n self.registration,\n tokenDetails?.subscriptionOptions?.vapidKey ?? DEFAULT_VAPID_KEY\n );\n }\n\n async onNotificationClick(event: NotificationEvent): Promise {\n const internalPayload: MessagePayloadInternal =\n event.notification?.data?.[FCM_MSG];\n\n if (!internalPayload) {\n return;\n } else if (event.action) {\n // User clicked on an action button. This will allow developers to act on action button clicks\n // by using a custom onNotificationClick listener that they define.\n return;\n }\n\n // Prevent other listeners from receiving the event\n event.stopImmediatePropagation();\n event.notification.close();\n\n // Note clicking on a notification with no link set will focus the Chrome's current tab.\n const link = getLink(internalPayload);\n if (!link) {\n return;\n }\n\n // FM should only open/focus links from app's origin.\n const url = new URL(link, self.location.href);\n const originUrl = new URL(self.location.origin);\n\n if (url.host !== originUrl.host) {\n return;\n }\n\n let client = await getWindowClient(url);\n\n if (!client) {\n client = await self.clients.openWindow(link);\n\n // Wait three seconds for the client to initialize and set up the message handler so that it\n // can receive the message.\n await sleep(FOREGROUND_HANDLE_PREPARATION_TIME_MS);\n } else {\n client = await client.focus();\n }\n\n if (!client) {\n // Window Client will not be returned if it's for a third party origin.\n return;\n }\n\n internalPayload.messageType = MessageType.NOTIFICATION_CLICKED;\n internalPayload.isFirebaseMessaging = true;\n return client.postMessage(internalPayload);\n }\n}\n\nfunction wrapInternalPayload(\n internalPayload: MessagePayloadInternal\n): NotificationPayloadInternal {\n const wrappedInternalPayload: NotificationPayloadInternal = {\n ...((internalPayload.notification as unknown) as NotificationPayloadInternal)\n };\n\n // Put the message payload under FCM_MSG name so we can identify the notification as being an FCM\n // notification vs a notification from somewhere else (i.e. normal web push or developer generated\n // notification).\n wrappedInternalPayload.data = {\n [FCM_MSG]: internalPayload\n };\n\n return wrappedInternalPayload;\n}\n\nfunction getMessagePayloadInternal({\n data\n}: PushEvent): MessagePayloadInternal | null {\n if (!data) {\n return null;\n }\n\n try {\n return data.json();\n } catch (err) {\n // Not JSON so not an FCM message.\n return null;\n }\n}\n\n/**\n * @param url The URL to look for when focusing a client.\n * @return Returns an existing window client or a newly opened WindowClient.\n */\nasync function getWindowClient(url: URL): Promise {\n const clientList = await getClientList();\n\n for (const client of clientList) {\n const clientUrl = new URL(client.url, self.location.href);\n\n if (url.host === clientUrl.host) {\n return client;\n }\n }\n\n return null;\n}\n\n/**\n * @returns If there is currently a visible WindowClient, this method will resolve to true,\n * otherwise false.\n */\nfunction hasVisibleClients(clientList: WindowClient[]): boolean {\n return clientList.some(\n client =>\n client.visibilityState === 'visible' &&\n // Ignore chrome-extension clients as that matches the background pages of extensions, which\n // are always considered visible for some reason.\n !client.url.startsWith('chrome-extension://')\n );\n}\n\nfunction sendMessagePayloadInternalToWindows(\n clientList: WindowClient[],\n internalPayload: MessagePayloadInternal\n): void {\n internalPayload.isFirebaseMessaging = true;\n internalPayload.messageType = MessageType.PUSH_RECEIVED;\n\n for (const client of clientList) {\n client.postMessage(internalPayload);\n }\n}\n\nfunction getClientList(): Promise {\n return self.clients.matchAll({\n type: 'window',\n includeUncontrolled: true\n // TS doesn't know that \"type: 'window'\" means it'll return WindowClient[]\n }) as Promise;\n}\n\nfunction showNotification(\n notificationPayloadInternal: NotificationPayloadInternal\n): Promise {\n // Note: Firefox does not support the maxActions property.\n // https://developer.mozilla.org/en-US/docs/Web/API/notification/maxActions\n const { actions } = notificationPayloadInternal;\n const { maxActions } = Notification;\n if (actions && maxActions && actions.length > maxActions) {\n console.warn(\n `This browser only supports ${maxActions} actions. The remaining actions will not be displayed.`\n );\n }\n\n return self.registration.showNotification(\n /* title= */ notificationPayloadInternal.title ?? '',\n notificationPayloadInternal\n );\n}\n\nfunction getLink(payload: MessagePayloadInternal): string | null {\n // eslint-disable-next-line camelcase\n const link = payload.fcmOptions?.link ?? payload.notification?.click_action;\n if (link) {\n return link;\n }\n\n if (isConsoleMessage(payload.data)) {\n // Notification created in the Firebase Console. Redirect to origin.\n return self.location.origin;\n } else {\n return null;\n }\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n CONSOLE_CAMPAIGN_ANALYTICS_ENABLED,\n CONSOLE_CAMPAIGN_ID,\n CONSOLE_CAMPAIGN_NAME,\n CONSOLE_CAMPAIGN_TIME,\n DEFAULT_SW_PATH,\n DEFAULT_SW_SCOPE,\n DEFAULT_VAPID_KEY\n} from '../util/constants';\nimport {\n ConsoleMessageData,\n MessagePayloadInternal,\n MessageType\n} from '../interfaces/internal-message-payload';\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { NextFn, Observer, Unsubscribe } from '@firebase/util';\nimport { deleteToken, getToken } from '../core/token-management';\n\nimport { FirebaseApp } from '@firebase/app-types';\nimport { FirebaseInternalDependencies } from '../interfaces/internal-dependencies';\nimport { FirebaseMessaging } from '@firebase/messaging-types';\nimport { FirebaseService } from '@firebase/app-types/private';\nimport { isConsoleMessage } from '../helpers/is-console-message';\n\nexport class WindowController implements FirebaseMessaging, FirebaseService {\n private vapidKey: string | null = null;\n private swRegistration?: ServiceWorkerRegistration;\n private onMessageCallback: NextFn | Observer | null = null;\n\n constructor(\n private readonly firebaseDependencies: FirebaseInternalDependencies\n ) {\n navigator.serviceWorker.addEventListener('message', e =>\n this.messageEventListener(e)\n );\n }\n\n get app(): FirebaseApp {\n return this.firebaseDependencies.app;\n }\n\n private async messageEventListener(event: MessageEvent): Promise {\n const internalPayload = event.data as MessagePayloadInternal;\n\n if (!internalPayload.isFirebaseMessaging) {\n return;\n }\n\n // onMessageCallback is either a function or observer/subscriber.\n // TODO: in the modularization release, have onMessage handle type MessagePayload as supposed to\n // the legacy payload where some fields are in snake cases.\n if (\n this.onMessageCallback &&\n internalPayload.messageType === MessageType.PUSH_RECEIVED\n ) {\n if (typeof this.onMessageCallback === 'function') {\n this.onMessageCallback(\n stripInternalFields(Object.assign({}, internalPayload))\n );\n } else {\n this.onMessageCallback.next(Object.assign({}, internalPayload));\n }\n }\n\n const dataPayload = internalPayload.data;\n\n if (\n isConsoleMessage(dataPayload) &&\n dataPayload[CONSOLE_CAMPAIGN_ANALYTICS_ENABLED] === '1'\n ) {\n await this.logEvent(internalPayload.messageType!, dataPayload);\n }\n }\n\n getVapidKey(): string | null {\n return this.vapidKey;\n }\n\n getSwReg(): ServiceWorkerRegistration | undefined {\n return this.swRegistration;\n }\n\n async getToken(options?: {\n vapidKey?: string;\n serviceWorkerRegistration?: ServiceWorkerRegistration;\n }): Promise {\n if (Notification.permission === 'default') {\n await Notification.requestPermission();\n }\n\n if (Notification.permission !== 'granted') {\n throw ERROR_FACTORY.create(ErrorCode.PERMISSION_BLOCKED);\n }\n\n await this.updateVapidKey(options?.vapidKey);\n await this.updateSwReg(options?.serviceWorkerRegistration);\n\n return getToken(\n this.firebaseDependencies,\n this.swRegistration!,\n this.vapidKey!\n );\n }\n\n async updateVapidKey(vapidKey?: string | undefined): Promise {\n if (!!vapidKey) {\n this.vapidKey = vapidKey;\n } else if (!this.vapidKey) {\n this.vapidKey = DEFAULT_VAPID_KEY;\n }\n }\n\n async updateSwReg(\n swRegistration?: ServiceWorkerRegistration | undefined\n ): Promise {\n if (!swRegistration && !this.swRegistration) {\n await this.registerDefaultSw();\n }\n\n if (!swRegistration && !!this.swRegistration) {\n return;\n }\n\n if (!(swRegistration instanceof ServiceWorkerRegistration)) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_SW_REGISTRATION);\n }\n\n this.swRegistration = swRegistration;\n }\n\n private async registerDefaultSw(): Promise {\n try {\n this.swRegistration = await navigator.serviceWorker.register(\n DEFAULT_SW_PATH,\n {\n scope: DEFAULT_SW_SCOPE\n }\n );\n\n // The timing when browser updates sw when sw has an update is unreliable by my experiment. It\n // leads to version conflict when the SDK upgrades to a newer version in the main page, but sw\n // is stuck with the old version. For example,\n // https://github.com/firebase/firebase-js-sdk/issues/2590 The following line reliably updates\n // sw if there was an update.\n this.swRegistration.update().catch(() => {\n /* it is non blocking and we don't care if it failed */\n });\n } catch (e) {\n throw ERROR_FACTORY.create(ErrorCode.FAILED_DEFAULT_REGISTRATION, {\n browserErrorMessage: e.message\n });\n }\n }\n\n async deleteToken(): Promise {\n if (!this.swRegistration) {\n await this.registerDefaultSw();\n }\n\n return deleteToken(this.firebaseDependencies, this.swRegistration!);\n }\n\n /**\n * Request permission if it is not currently granted.\n *\n * @return Resolves if the permission was granted, rejects otherwise.\n *\n * @deprecated Use Notification.requestPermission() instead.\n * https://developer.mozilla.org/en-US/docs/Web/API/Notification/requestPermission\n */\n async requestPermission(): Promise {\n if (Notification.permission === 'granted') {\n return;\n }\n\n const permissionResult = await Notification.requestPermission();\n if (permissionResult === 'granted') {\n return;\n } else if (permissionResult === 'denied') {\n throw ERROR_FACTORY.create(ErrorCode.PERMISSION_BLOCKED);\n } else {\n throw ERROR_FACTORY.create(ErrorCode.PERMISSION_DEFAULT);\n }\n }\n\n /**\n * @deprecated. Use getToken(options?: {vapidKey?: string; serviceWorkerRegistration?:\n * ServiceWorkerRegistration;}): Promise instead.\n */\n usePublicVapidKey(vapidKey: string): void {\n if (this.vapidKey !== null) {\n throw ERROR_FACTORY.create(ErrorCode.USE_VAPID_KEY_AFTER_GET_TOKEN);\n }\n\n if (typeof vapidKey !== 'string' || vapidKey.length === 0) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_VAPID_KEY);\n }\n\n this.vapidKey = vapidKey;\n }\n\n /**\n * @deprecated. Use getToken(options?: {vapidKey?: string; serviceWorkerRegistration?:\n * ServiceWorkerRegistration;}): Promise instead.\n */\n useServiceWorker(swRegistration: ServiceWorkerRegistration): void {\n if (!(swRegistration instanceof ServiceWorkerRegistration)) {\n throw ERROR_FACTORY.create(ErrorCode.INVALID_SW_REGISTRATION);\n }\n\n if (this.swRegistration) {\n throw ERROR_FACTORY.create(ErrorCode.USE_SW_AFTER_GET_TOKEN);\n }\n\n this.swRegistration = swRegistration;\n }\n\n /**\n * @param nextOrObserver An observer object or a function triggered on message.\n *\n * @return The unsubscribe function for the observer.\n */\n onMessage(nextOrObserver: NextFn | Observer): Unsubscribe {\n this.onMessageCallback = nextOrObserver;\n\n return () => {\n this.onMessageCallback = null;\n };\n }\n\n setBackgroundMessageHandler(): void {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_SW);\n }\n\n onBackgroundMessage(): Unsubscribe {\n throw ERROR_FACTORY.create(ErrorCode.AVAILABLE_IN_SW);\n }\n\n /**\n * @deprecated No-op. It was initially designed with token rotation requests from server in mind.\n * However, the plan to implement such feature was abandoned.\n */\n onTokenRefresh(): Unsubscribe {\n return () => {};\n }\n\n private async logEvent(\n messageType: MessageType,\n data: ConsoleMessageData\n ): Promise {\n const eventType = getEventType(messageType);\n const analytics = await this.firebaseDependencies.analyticsProvider.get();\n analytics.logEvent(eventType, {\n /* eslint-disable camelcase */\n message_id: data[CONSOLE_CAMPAIGN_ID],\n message_name: data[CONSOLE_CAMPAIGN_NAME],\n message_time: data[CONSOLE_CAMPAIGN_TIME],\n message_device_time: Math.floor(Date.now() / 1000)\n /* eslint-enable camelcase */\n });\n }\n}\n\nfunction getEventType(messageType: MessageType): string {\n switch (messageType) {\n case MessageType.NOTIFICATION_CLICKED:\n return 'notification_open';\n case MessageType.PUSH_RECEIVED:\n return 'notification_foreground';\n default:\n throw new Error();\n }\n}\n\nfunction stripInternalFields(\n internalPayload: MessagePayloadInternal\n): MessagePayloadInternal {\n delete internalPayload.messageType;\n delete internalPayload.isFirebaseMessaging;\n return internalPayload;\n}\n","/**\n * @license\n * Copyright 2019 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ERROR_FACTORY, ErrorCode } from '../util/errors';\nimport { FirebaseApp, FirebaseOptions } from '@firebase/app-types';\n\nimport { AppConfig } from '../interfaces/app-config';\nimport { FirebaseError } from '@firebase/util';\n\nexport function extractAppConfig(app: FirebaseApp): AppConfig {\n if (!app || !app.options) {\n throw getMissingValueError('App Configuration Object');\n }\n\n if (!app.name) {\n throw getMissingValueError('App Name');\n }\n\n // Required app config keys\n const configKeys: ReadonlyArray = [\n 'projectId',\n 'apiKey',\n 'appId',\n 'messagingSenderId'\n ];\n\n const { options } = app;\n for (const keyName of configKeys) {\n if (!options[keyName]) {\n throw getMissingValueError(keyName);\n }\n }\n\n return {\n appName: app.name,\n projectId: options.projectId!,\n apiKey: options.apiKey!,\n appId: options.appId!,\n senderId: options.messagingSenderId!\n };\n}\n\nfunction getMissingValueError(valueName: string): FirebaseError {\n return ERROR_FACTORY.create(ErrorCode.MISSING_APP_CONFIG_VALUES, {\n valueName\n });\n}\n","/**\n * @license\n * Copyright 2017 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport '@firebase/installations';\n\nimport {\n Component,\n ComponentContainer,\n ComponentType\n} from '@firebase/component';\nimport { ERROR_FACTORY, ErrorCode } from './util/errors';\nimport {\n FirebaseService,\n _FirebaseNamespace\n} from '@firebase/app-types/private';\n\nimport { FirebaseInternalDependencies } from './interfaces/internal-dependencies';\nimport { FirebaseMessaging } from '@firebase/messaging-types';\nimport { SwController } from './controllers/sw-controller';\nimport { WindowController } from './controllers/window-controller';\nimport { extractAppConfig } from './helpers/extract-app-config';\nimport firebase from '@firebase/app';\n\nconst MESSAGING_NAME = 'messaging';\nfunction factoryMethod(\n container: ComponentContainer\n): FirebaseService & FirebaseMessaging {\n // Dependencies.\n const app = container.getProvider('app').getImmediate();\n const appConfig = extractAppConfig(app);\n const installations = container.getProvider('installations').getImmediate();\n const analyticsProvider = container.getProvider('analytics-internal');\n\n const firebaseDependencies: FirebaseInternalDependencies = {\n app,\n appConfig,\n installations,\n analyticsProvider\n };\n\n if (!isSupported()) {\n throw ERROR_FACTORY.create(ErrorCode.UNSUPPORTED_BROWSER);\n }\n\n if (self && 'ServiceWorkerGlobalScope' in self) {\n // Running in ServiceWorker context\n return new SwController(firebaseDependencies);\n } else {\n // Assume we are in the window context.\n return new WindowController(firebaseDependencies);\n }\n}\n\nconst NAMESPACE_EXPORTS = {\n isSupported\n};\n\n(firebase as _FirebaseNamespace).INTERNAL.registerComponent(\n new Component(\n MESSAGING_NAME,\n factoryMethod,\n ComponentType.PUBLIC\n ).setServiceProps(NAMESPACE_EXPORTS)\n);\n\n/**\n * Define extension behavior of `registerMessaging`\n */\ndeclare module '@firebase/app-types' {\n interface FirebaseNamespace {\n messaging: {\n (app?: FirebaseApp): FirebaseMessaging;\n isSupported(): boolean;\n };\n }\n interface FirebaseApp {\n messaging(): FirebaseMessaging;\n }\n}\n\nfunction isSupported(): boolean {\n if (self && 'ServiceWorkerGlobalScope' in self) {\n // Running in ServiceWorker context\n return isSWControllerSupported();\n } else {\n // Assume we are in the window context.\n return isWindowControllerSupported();\n }\n}\n\n/**\n * Checks to see if the required APIs exist.\n */\nfunction isWindowControllerSupported(): boolean {\n return (\n 'indexedDB' in window &&\n indexedDB !== null &&\n navigator.cookieEnabled &&\n 'serviceWorker' in navigator &&\n 'PushManager' in window &&\n 'Notification' in window &&\n 'fetch' in window &&\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey')\n );\n}\n\n/**\n * Checks to see if the required APIs exist within SW Context.\n */\nfunction isSWControllerSupported(): boolean {\n return (\n 'indexedDB' in self &&\n indexedDB !== null &&\n 'PushManager' in self &&\n 'Notification' in self &&\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey')\n );\n}\n"],"names":["extendStatics","d","b","Object","setPrototypeOf","__proto__","Array","p","prototype","hasOwnProperty","call","__assign","assign","t","s","i","n","arguments","length","apply","this","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","__generator","body","f","y","_","label","sent","trys","ops","g","verb","throw","return","Symbol","iterator","v","op","TypeError","pop","push","__values","o","m","__read","r","ar","error","__spreadArray","to","from","il","j","ERROR_NAME","String","__","constructor","create","__extends","Error","code","message","customData","_super","_this","FirebaseError","captureStackTrace","ErrorFactory","_i","data","fullCode","service","template","errors","replace","PATTERN","key","fullMessage","serviceName","Component","mode","instantiationMode","multipleInstances","props","serviceProps","callback","onInstanceCreated","name","instanceFactory","type","promisifyRequest","request","onsuccess","onerror","promisifyRequestCall","obj","method","args","proxyProperties","ProxyClass","targetProp","properties","forEach","prop","defineProperty","get","set","val","proxyRequestMethods","Constructor","proxyMethods","proxyCursorRequestMethods","Cursor","Index","index","_index","cursor","_cursor","_request","ObjectStore","store","_store","Transaction","idbTransaction","_tx","complete","oncomplete","onabort","UpgradeDB","db","oldVersion","transaction","_db","DB","openDb","version","upgradeCallback","indexedDB","onupgradeneeded","event","deleteDb","IDBIndex","IDBCursor","methodName","createIndex","IDBObjectStore","objectStore","IDBTransaction","createObjectStore","IDBDatabase","funcName","arr","slice","nativeObject","getAll","query","count","instance","items","iterateCursor","undefined","continue","PENDING_TIMEOUT_MS","PACKAGE_VERSION","INTERNAL_AUTH_VERSION","INSTALLATIONS_API_URL","TOKEN_EXPIRATION_BUFFER","ERROR_DESCRIPTION_MAP","_a","ERROR_FACTORY","isServerError","includes","getInstallationsEndpoint","projectId","extractAuthTokenInfoFromResponse","response","token","requestStatus","expiresIn","responseExpiresIn","Number","creationTime","Date","now","getErrorFromResponse","requestName","json","responseJson","errorData","serverCode","serverMessage","serverStatus","status","getHeaders","apiKey","Headers","Content-Type","Accept","x-goog-api-key","getHeadersWithAuth","appConfig","refreshToken","headers","append","retryIfServerError","fn","sleep","ms","setTimeout","VALID_FID_PATTERN","INVALID_FID","generateFid","fidByteArray","Uint8Array","self","crypto","msCrypto","getRandomValues","fid","array","btoa","fromCharCode","bufferToBase64UrlSafe","substr","test","getKey","appName","appId","fidChangeCallbacks","Map","fidChanged","callFidChangeCallbacks","channel","getBroadcastChannel","postMessage","closeBroadcastChannel","broadcastFidChange","callbacks","callbacks_1","broadcastChannel","BroadcastChannel","onmessage","size","close","DATABASE_NAME","DATABASE_VERSION","OBJECT_STORE_NAME","dbPromise","getDbPromise","upgradeDB","tx","oldValue","put","remove","delete","update","updateFn","newValue","getInstallationEntry","oldEntry","installationEntry","clearTimedOutRequest","registrationStatus","entryWithPromise","registrationPromise","updateInstallationRequest","entry","_b","waitUntilFidRegistration","navigator","onLine","registrationPromiseWithError","inProgressEntry","registrationTime","endpoint","authVersion","sdkVersion","JSON","stringify","fetch","ok","responseValue","authToken","createInstallationRequest","registeredInstallationEntry","e_1","registerInstallation","triggerRegistrationIfNecessary","generateAuthTokenRequest","platformLoggerProvider","getGenerateAuthTokenEndpoint","platformLogger","getImmediate","optional","getPlatformInfoString","installation","refreshAuthToken","dependencies","forceRefresh","isEntryRegistered","oldAuthToken","isAuthTokenExpired","tokenPromise","updateAuthTokenRequest","waitUntilAuthTokenRequest","inProgressAuthToken","requestTime","updatedInstallationEntry","fetchAuthTokenFromServer","getToken","completeInstallationRegistration","deleteInstallationRequest","getDeleteEndpoint","onIdChange","callbackSet","Set","add","addCallback","getMissingValueError","valueName","firebase","INTERNAL","registerComponent","container","app","getProvider","options","configKeys_1","keyName","extractAppConfig","getId","catch","console","deleteInstallation","registerVersion","MessageType","ERROR_MAP","DEFAULT_VAPID_KEY","ENDPOINT","FCM_MSG","CONSOLE_CAMPAIGN_ID","arrayToBase64","uint8Array","OLD_DB_NAME","OLD_DB_VERSION","OLD_OBJECT_STORE_NAME","migrateOldDatabase","senderId","databases","map","tokenDetails","objectStoreNames","contains","clear","oldDetails","auth","p256dh","fcmToken","createTime","subscriptionOptions","swScope","vapidKey","checkTokenDetails","upgradeDb","dbGet","firebaseDependencies","oldTokenDetails","dbSet","requestDeleteToken","unsubscribeOptions","getEndpoint","responseData","errorInfo","err_3","installations","x-goog-firebase-installations-auth","getBody","web","applicationPubKey","swRegistration","Notification","permission","pushManager","getSubscription","subscription","subscribe","userVisibleOnly","applicationServerKey","base64String","base64","repeat","rawData","atob","outputArray","charCodeAt","base64ToArray","getPushSubscription","pushSubscription","scope","getNewToken","dbOptions","isVapidKeyEqual","currentOptions","isEndpointEqual","isAuthEqual","isP256dhEqual","warn","updateOptions","err_2","requestUpdateToken","updatedToken","updatedTokenDetails","deleteToken","e_2","updateToken","dbRemove","unsubscribe","subscribeOptions","err_1","requestGetToken","externalizePayload","internalPayload","payload","collapseKey","collapse_key","messagePayloadInternal","notification","title","image","propagateNotificationPayload","propagateDataPayload","fcmOptions","link","analyticsLabel","analytics_label","propagateFcmOptions","isConsoleMessage","SwController","isOnBackgroundMessageUsed","bgMessageHandler","nextOrObserver","_c","registration","err","getMessagePayloadInternal","getClientList","debug","TAG","clientList","some","client","visibilityState","url","startsWith","isFirebaseMessaging","messageType","PUSH_RECEIVED","clientList_2","sendMessagePayloadInternalToWindows","isNotificationShown","notificationPayloadInternal","actions","maxActions","showNotification","wrappedInternalPayload","action","stopImmediatePropagation","click_action","location","origin","getLink","URL","href","originUrl","host","clientList_1","clientUrl","getWindowClient","clients","openWindow","focus","NOTIFICATION_CLICKED","addEventListener","waitUntil","onPush","onSubChange","onNotificationClick","matchAll","includeUncontrolled","WindowController","onMessageCallback","dataPayload","logEvent","requestPermission","updateVapidKey","updateSwReg","serviceWorkerRegistration","registerDefaultSw","ServiceWorkerRegistration","serviceWorker","register","browserErrorMessage","permissionResult","eventType","getEventType","analyticsProvider","message_id","message_name","message_time","message_device_time","Math","floor","messageEventListener","NAMESPACE_EXPORTS","isSupported","PushSubscription","window","cookieEnabled","messagingSenderId","setServiceProps"],"mappings":"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"}