index.esm5.js 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099
  1. import { Component, ComponentContainer } from '@firebase/component';
  2. import { __values, __assign, __awaiter, __generator, __spreadArray, __read } from 'tslib';
  3. import { Logger, setUserLogHandler, setLogLevel as setLogLevel$1 } from '@firebase/logger';
  4. import { ErrorFactory, getDefaultAppConfig, deepEqual, FirebaseError, base64urlEncodeWithoutPadding, isIndexedDBAvailable, validateIndexedDBOpenable } from '@firebase/util';
  5. export { FirebaseError } from '@firebase/util';
  6. import { openDB } from 'idb';
  7. /**
  8. * @license
  9. * Copyright 2019 Google LLC
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. */
  23. var PlatformLoggerServiceImpl = /** @class */ (function () {
  24. function PlatformLoggerServiceImpl(container) {
  25. this.container = container;
  26. }
  27. // In initial implementation, this will be called by installations on
  28. // auth token refresh, and installations will send this string.
  29. PlatformLoggerServiceImpl.prototype.getPlatformInfoString = function () {
  30. var providers = this.container.getProviders();
  31. // Loop through providers and get library/version pairs from any that are
  32. // version components.
  33. return providers
  34. .map(function (provider) {
  35. if (isVersionServiceProvider(provider)) {
  36. var service = provider.getImmediate();
  37. return "".concat(service.library, "/").concat(service.version);
  38. }
  39. else {
  40. return null;
  41. }
  42. })
  43. .filter(function (logString) { return logString; })
  44. .join(' ');
  45. };
  46. return PlatformLoggerServiceImpl;
  47. }());
  48. /**
  49. *
  50. * @param provider check if this provider provides a VersionService
  51. *
  52. * NOTE: Using Provider<'app-version'> is a hack to indicate that the provider
  53. * provides VersionService. The provider is not necessarily a 'app-version'
  54. * provider.
  55. */
  56. function isVersionServiceProvider(provider) {
  57. var component = provider.getComponent();
  58. return (component === null || component === void 0 ? void 0 : component.type) === "VERSION" /* ComponentType.VERSION */;
  59. }
  60. var name$o = "@firebase/app";
  61. var version$1 = "0.9.13";
  62. /**
  63. * @license
  64. * Copyright 2019 Google LLC
  65. *
  66. * Licensed under the Apache License, Version 2.0 (the "License");
  67. * you may not use this file except in compliance with the License.
  68. * You may obtain a copy of the License at
  69. *
  70. * http://www.apache.org/licenses/LICENSE-2.0
  71. *
  72. * Unless required by applicable law or agreed to in writing, software
  73. * distributed under the License is distributed on an "AS IS" BASIS,
  74. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  75. * See the License for the specific language governing permissions and
  76. * limitations under the License.
  77. */
  78. var logger = new Logger('@firebase/app');
  79. var name$n = "@firebase/app-compat";
  80. var name$m = "@firebase/analytics-compat";
  81. var name$l = "@firebase/analytics";
  82. var name$k = "@firebase/app-check-compat";
  83. var name$j = "@firebase/app-check";
  84. var name$i = "@firebase/auth";
  85. var name$h = "@firebase/auth-compat";
  86. var name$g = "@firebase/database";
  87. var name$f = "@firebase/database-compat";
  88. var name$e = "@firebase/functions";
  89. var name$d = "@firebase/functions-compat";
  90. var name$c = "@firebase/installations";
  91. var name$b = "@firebase/installations-compat";
  92. var name$a = "@firebase/messaging";
  93. var name$9 = "@firebase/messaging-compat";
  94. var name$8 = "@firebase/performance";
  95. var name$7 = "@firebase/performance-compat";
  96. var name$6 = "@firebase/remote-config";
  97. var name$5 = "@firebase/remote-config-compat";
  98. var name$4 = "@firebase/storage";
  99. var name$3 = "@firebase/storage-compat";
  100. var name$2 = "@firebase/firestore";
  101. var name$1 = "@firebase/firestore-compat";
  102. var name = "firebase";
  103. var version = "9.23.0";
  104. /**
  105. * @license
  106. * Copyright 2019 Google LLC
  107. *
  108. * Licensed under the Apache License, Version 2.0 (the "License");
  109. * you may not use this file except in compliance with the License.
  110. * You may obtain a copy of the License at
  111. *
  112. * http://www.apache.org/licenses/LICENSE-2.0
  113. *
  114. * Unless required by applicable law or agreed to in writing, software
  115. * distributed under the License is distributed on an "AS IS" BASIS,
  116. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  117. * See the License for the specific language governing permissions and
  118. * limitations under the License.
  119. */
  120. var _a$1;
  121. /**
  122. * The default app name
  123. *
  124. * @internal
  125. */
  126. var DEFAULT_ENTRY_NAME = '[DEFAULT]';
  127. var PLATFORM_LOG_STRING = (_a$1 = {},
  128. _a$1[name$o] = 'fire-core',
  129. _a$1[name$n] = 'fire-core-compat',
  130. _a$1[name$l] = 'fire-analytics',
  131. _a$1[name$m] = 'fire-analytics-compat',
  132. _a$1[name$j] = 'fire-app-check',
  133. _a$1[name$k] = 'fire-app-check-compat',
  134. _a$1[name$i] = 'fire-auth',
  135. _a$1[name$h] = 'fire-auth-compat',
  136. _a$1[name$g] = 'fire-rtdb',
  137. _a$1[name$f] = 'fire-rtdb-compat',
  138. _a$1[name$e] = 'fire-fn',
  139. _a$1[name$d] = 'fire-fn-compat',
  140. _a$1[name$c] = 'fire-iid',
  141. _a$1[name$b] = 'fire-iid-compat',
  142. _a$1[name$a] = 'fire-fcm',
  143. _a$1[name$9] = 'fire-fcm-compat',
  144. _a$1[name$8] = 'fire-perf',
  145. _a$1[name$7] = 'fire-perf-compat',
  146. _a$1[name$6] = 'fire-rc',
  147. _a$1[name$5] = 'fire-rc-compat',
  148. _a$1[name$4] = 'fire-gcs',
  149. _a$1[name$3] = 'fire-gcs-compat',
  150. _a$1[name$2] = 'fire-fst',
  151. _a$1[name$1] = 'fire-fst-compat',
  152. _a$1['fire-js'] = 'fire-js',
  153. _a$1[name] = 'fire-js-all',
  154. _a$1);
  155. /**
  156. * @license
  157. * Copyright 2019 Google LLC
  158. *
  159. * Licensed under the Apache License, Version 2.0 (the "License");
  160. * you may not use this file except in compliance with the License.
  161. * You may obtain a copy of the License at
  162. *
  163. * http://www.apache.org/licenses/LICENSE-2.0
  164. *
  165. * Unless required by applicable law or agreed to in writing, software
  166. * distributed under the License is distributed on an "AS IS" BASIS,
  167. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  168. * See the License for the specific language governing permissions and
  169. * limitations under the License.
  170. */
  171. /**
  172. * @internal
  173. */
  174. var _apps = new Map();
  175. /**
  176. * Registered components.
  177. *
  178. * @internal
  179. */
  180. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  181. var _components = new Map();
  182. /**
  183. * @param component - the component being added to this app's container
  184. *
  185. * @internal
  186. */
  187. function _addComponent(app, component) {
  188. try {
  189. app.container.addComponent(component);
  190. }
  191. catch (e) {
  192. logger.debug("Component ".concat(component.name, " failed to register with FirebaseApp ").concat(app.name), e);
  193. }
  194. }
  195. /**
  196. *
  197. * @internal
  198. */
  199. function _addOrOverwriteComponent(app, component) {
  200. app.container.addOrOverwriteComponent(component);
  201. }
  202. /**
  203. *
  204. * @param component - the component to register
  205. * @returns whether or not the component is registered successfully
  206. *
  207. * @internal
  208. */
  209. function _registerComponent(component) {
  210. var e_1, _a;
  211. var componentName = component.name;
  212. if (_components.has(componentName)) {
  213. logger.debug("There were multiple attempts to register component ".concat(componentName, "."));
  214. return false;
  215. }
  216. _components.set(componentName, component);
  217. try {
  218. // add the component to existing app instances
  219. for (var _b = __values(_apps.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
  220. var app = _c.value;
  221. _addComponent(app, component);
  222. }
  223. }
  224. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  225. finally {
  226. try {
  227. if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
  228. }
  229. finally { if (e_1) throw e_1.error; }
  230. }
  231. return true;
  232. }
  233. /**
  234. *
  235. * @param app - FirebaseApp instance
  236. * @param name - service name
  237. *
  238. * @returns the provider for the service with the matching name
  239. *
  240. * @internal
  241. */
  242. function _getProvider(app, name) {
  243. var heartbeatController = app.container
  244. .getProvider('heartbeat')
  245. .getImmediate({ optional: true });
  246. if (heartbeatController) {
  247. void heartbeatController.triggerHeartbeat();
  248. }
  249. return app.container.getProvider(name);
  250. }
  251. /**
  252. *
  253. * @param app - FirebaseApp instance
  254. * @param name - service name
  255. * @param instanceIdentifier - service instance identifier in case the service supports multiple instances
  256. *
  257. * @internal
  258. */
  259. function _removeServiceInstance(app, name, instanceIdentifier) {
  260. if (instanceIdentifier === void 0) { instanceIdentifier = DEFAULT_ENTRY_NAME; }
  261. _getProvider(app, name).clearInstance(instanceIdentifier);
  262. }
  263. /**
  264. * Test only
  265. *
  266. * @internal
  267. */
  268. function _clearComponents() {
  269. _components.clear();
  270. }
  271. /**
  272. * @license
  273. * Copyright 2019 Google LLC
  274. *
  275. * Licensed under the Apache License, Version 2.0 (the "License");
  276. * you may not use this file except in compliance with the License.
  277. * You may obtain a copy of the License at
  278. *
  279. * http://www.apache.org/licenses/LICENSE-2.0
  280. *
  281. * Unless required by applicable law or agreed to in writing, software
  282. * distributed under the License is distributed on an "AS IS" BASIS,
  283. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  284. * See the License for the specific language governing permissions and
  285. * limitations under the License.
  286. */
  287. var _a;
  288. var ERRORS = (_a = {},
  289. _a["no-app" /* AppError.NO_APP */] = "No Firebase App '{$appName}' has been created - " +
  290. 'call initializeApp() first',
  291. _a["bad-app-name" /* AppError.BAD_APP_NAME */] = "Illegal App name: '{$appName}",
  292. _a["duplicate-app" /* AppError.DUPLICATE_APP */] = "Firebase App named '{$appName}' already exists with different options or config",
  293. _a["app-deleted" /* AppError.APP_DELETED */] = "Firebase App named '{$appName}' already deleted",
  294. _a["no-options" /* AppError.NO_OPTIONS */] = 'Need to provide options, when not being deployed to hosting via source.',
  295. _a["invalid-app-argument" /* AppError.INVALID_APP_ARGUMENT */] = 'firebase.{$appName}() takes either no argument or a ' +
  296. 'Firebase App instance.',
  297. _a["invalid-log-argument" /* AppError.INVALID_LOG_ARGUMENT */] = 'First argument to `onLog` must be null or a function.',
  298. _a["idb-open" /* AppError.IDB_OPEN */] = 'Error thrown when opening IndexedDB. Original error: {$originalErrorMessage}.',
  299. _a["idb-get" /* AppError.IDB_GET */] = 'Error thrown when reading from IndexedDB. Original error: {$originalErrorMessage}.',
  300. _a["idb-set" /* AppError.IDB_WRITE */] = 'Error thrown when writing to IndexedDB. Original error: {$originalErrorMessage}.',
  301. _a["idb-delete" /* AppError.IDB_DELETE */] = 'Error thrown when deleting from IndexedDB. Original error: {$originalErrorMessage}.',
  302. _a);
  303. var ERROR_FACTORY = new ErrorFactory('app', 'Firebase', ERRORS);
  304. /**
  305. * @license
  306. * Copyright 2019 Google LLC
  307. *
  308. * Licensed under the Apache License, Version 2.0 (the "License");
  309. * you may not use this file except in compliance with the License.
  310. * You may obtain a copy of the License at
  311. *
  312. * http://www.apache.org/licenses/LICENSE-2.0
  313. *
  314. * Unless required by applicable law or agreed to in writing, software
  315. * distributed under the License is distributed on an "AS IS" BASIS,
  316. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  317. * See the License for the specific language governing permissions and
  318. * limitations under the License.
  319. */
  320. var FirebaseAppImpl = /** @class */ (function () {
  321. function FirebaseAppImpl(options, config, container) {
  322. var _this = this;
  323. this._isDeleted = false;
  324. this._options = __assign({}, options);
  325. this._config = __assign({}, config);
  326. this._name = config.name;
  327. this._automaticDataCollectionEnabled =
  328. config.automaticDataCollectionEnabled;
  329. this._container = container;
  330. this.container.addComponent(new Component('app', function () { return _this; }, "PUBLIC" /* ComponentType.PUBLIC */));
  331. }
  332. Object.defineProperty(FirebaseAppImpl.prototype, "automaticDataCollectionEnabled", {
  333. get: function () {
  334. this.checkDestroyed();
  335. return this._automaticDataCollectionEnabled;
  336. },
  337. set: function (val) {
  338. this.checkDestroyed();
  339. this._automaticDataCollectionEnabled = val;
  340. },
  341. enumerable: false,
  342. configurable: true
  343. });
  344. Object.defineProperty(FirebaseAppImpl.prototype, "name", {
  345. get: function () {
  346. this.checkDestroyed();
  347. return this._name;
  348. },
  349. enumerable: false,
  350. configurable: true
  351. });
  352. Object.defineProperty(FirebaseAppImpl.prototype, "options", {
  353. get: function () {
  354. this.checkDestroyed();
  355. return this._options;
  356. },
  357. enumerable: false,
  358. configurable: true
  359. });
  360. Object.defineProperty(FirebaseAppImpl.prototype, "config", {
  361. get: function () {
  362. this.checkDestroyed();
  363. return this._config;
  364. },
  365. enumerable: false,
  366. configurable: true
  367. });
  368. Object.defineProperty(FirebaseAppImpl.prototype, "container", {
  369. get: function () {
  370. return this._container;
  371. },
  372. enumerable: false,
  373. configurable: true
  374. });
  375. Object.defineProperty(FirebaseAppImpl.prototype, "isDeleted", {
  376. get: function () {
  377. return this._isDeleted;
  378. },
  379. set: function (val) {
  380. this._isDeleted = val;
  381. },
  382. enumerable: false,
  383. configurable: true
  384. });
  385. /**
  386. * This function will throw an Error if the App has already been deleted -
  387. * use before performing API actions on the App.
  388. */
  389. FirebaseAppImpl.prototype.checkDestroyed = function () {
  390. if (this.isDeleted) {
  391. throw ERROR_FACTORY.create("app-deleted" /* AppError.APP_DELETED */, { appName: this._name });
  392. }
  393. };
  394. return FirebaseAppImpl;
  395. }());
  396. /**
  397. * @license
  398. * Copyright 2019 Google LLC
  399. *
  400. * Licensed under the Apache License, Version 2.0 (the "License");
  401. * you may not use this file except in compliance with the License.
  402. * You may obtain a copy of the License at
  403. *
  404. * http://www.apache.org/licenses/LICENSE-2.0
  405. *
  406. * Unless required by applicable law or agreed to in writing, software
  407. * distributed under the License is distributed on an "AS IS" BASIS,
  408. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  409. * See the License for the specific language governing permissions and
  410. * limitations under the License.
  411. */
  412. /**
  413. * The current SDK version.
  414. *
  415. * @public
  416. */
  417. var SDK_VERSION = version;
  418. function initializeApp(_options, rawConfig) {
  419. var e_1, _a;
  420. if (rawConfig === void 0) { rawConfig = {}; }
  421. var options = _options;
  422. if (typeof rawConfig !== 'object') {
  423. var name_1 = rawConfig;
  424. rawConfig = { name: name_1 };
  425. }
  426. var config = __assign({ name: DEFAULT_ENTRY_NAME, automaticDataCollectionEnabled: false }, rawConfig);
  427. var name = config.name;
  428. if (typeof name !== 'string' || !name) {
  429. throw ERROR_FACTORY.create("bad-app-name" /* AppError.BAD_APP_NAME */, {
  430. appName: String(name)
  431. });
  432. }
  433. options || (options = getDefaultAppConfig());
  434. if (!options) {
  435. throw ERROR_FACTORY.create("no-options" /* AppError.NO_OPTIONS */);
  436. }
  437. var existingApp = _apps.get(name);
  438. if (existingApp) {
  439. // return the existing app if options and config deep equal the ones in the existing app.
  440. if (deepEqual(options, existingApp.options) &&
  441. deepEqual(config, existingApp.config)) {
  442. return existingApp;
  443. }
  444. else {
  445. throw ERROR_FACTORY.create("duplicate-app" /* AppError.DUPLICATE_APP */, { appName: name });
  446. }
  447. }
  448. var container = new ComponentContainer(name);
  449. try {
  450. for (var _b = __values(_components.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
  451. var component = _c.value;
  452. container.addComponent(component);
  453. }
  454. }
  455. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  456. finally {
  457. try {
  458. if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
  459. }
  460. finally { if (e_1) throw e_1.error; }
  461. }
  462. var newApp = new FirebaseAppImpl(options, config, container);
  463. _apps.set(name, newApp);
  464. return newApp;
  465. }
  466. /**
  467. * Retrieves a {@link @firebase/app#FirebaseApp} instance.
  468. *
  469. * When called with no arguments, the default app is returned. When an app name
  470. * is provided, the app corresponding to that name is returned.
  471. *
  472. * An exception is thrown if the app being retrieved has not yet been
  473. * initialized.
  474. *
  475. * @example
  476. * ```javascript
  477. * // Return the default app
  478. * const app = getApp();
  479. * ```
  480. *
  481. * @example
  482. * ```javascript
  483. * // Return a named app
  484. * const otherApp = getApp("otherApp");
  485. * ```
  486. *
  487. * @param name - Optional name of the app to return. If no name is
  488. * provided, the default is `"[DEFAULT]"`.
  489. *
  490. * @returns The app corresponding to the provided app name.
  491. * If no app name is provided, the default app is returned.
  492. *
  493. * @public
  494. */
  495. function getApp(name) {
  496. if (name === void 0) { name = DEFAULT_ENTRY_NAME; }
  497. var app = _apps.get(name);
  498. if (!app && name === DEFAULT_ENTRY_NAME && getDefaultAppConfig()) {
  499. return initializeApp();
  500. }
  501. if (!app) {
  502. throw ERROR_FACTORY.create("no-app" /* AppError.NO_APP */, { appName: name });
  503. }
  504. return app;
  505. }
  506. /**
  507. * A (read-only) array of all initialized apps.
  508. * @public
  509. */
  510. function getApps() {
  511. return Array.from(_apps.values());
  512. }
  513. /**
  514. * Renders this app unusable and frees the resources of all associated
  515. * services.
  516. *
  517. * @example
  518. * ```javascript
  519. * deleteApp(app)
  520. * .then(function() {
  521. * console.log("App deleted successfully");
  522. * })
  523. * .catch(function(error) {
  524. * console.log("Error deleting app:", error);
  525. * });
  526. * ```
  527. *
  528. * @public
  529. */
  530. function deleteApp(app) {
  531. return __awaiter(this, void 0, void 0, function () {
  532. var name;
  533. return __generator(this, function (_a) {
  534. switch (_a.label) {
  535. case 0:
  536. name = app.name;
  537. if (!_apps.has(name)) return [3 /*break*/, 2];
  538. _apps.delete(name);
  539. return [4 /*yield*/, Promise.all(app.container
  540. .getProviders()
  541. .map(function (provider) { return provider.delete(); }))];
  542. case 1:
  543. _a.sent();
  544. app.isDeleted = true;
  545. _a.label = 2;
  546. case 2: return [2 /*return*/];
  547. }
  548. });
  549. });
  550. }
  551. /**
  552. * Registers a library's name and version for platform logging purposes.
  553. * @param library - Name of 1p or 3p library (e.g. firestore, angularfire)
  554. * @param version - Current version of that library.
  555. * @param variant - Bundle variant, e.g., node, rn, etc.
  556. *
  557. * @public
  558. */
  559. function registerVersion(libraryKeyOrName, version, variant) {
  560. var _a;
  561. // TODO: We can use this check to whitelist strings when/if we set up
  562. // a good whitelist system.
  563. var library = (_a = PLATFORM_LOG_STRING[libraryKeyOrName]) !== null && _a !== void 0 ? _a : libraryKeyOrName;
  564. if (variant) {
  565. library += "-".concat(variant);
  566. }
  567. var libraryMismatch = library.match(/\s|\//);
  568. var versionMismatch = version.match(/\s|\//);
  569. if (libraryMismatch || versionMismatch) {
  570. var warning = [
  571. "Unable to register library \"".concat(library, "\" with version \"").concat(version, "\":")
  572. ];
  573. if (libraryMismatch) {
  574. warning.push("library name \"".concat(library, "\" contains illegal characters (whitespace or \"/\")"));
  575. }
  576. if (libraryMismatch && versionMismatch) {
  577. warning.push('and');
  578. }
  579. if (versionMismatch) {
  580. warning.push("version name \"".concat(version, "\" contains illegal characters (whitespace or \"/\")"));
  581. }
  582. logger.warn(warning.join(' '));
  583. return;
  584. }
  585. _registerComponent(new Component("".concat(library, "-version"), function () { return ({ library: library, version: version }); }, "VERSION" /* ComponentType.VERSION */));
  586. }
  587. /**
  588. * Sets log handler for all Firebase SDKs.
  589. * @param logCallback - An optional custom log handler that executes user code whenever
  590. * the Firebase SDK makes a logging call.
  591. *
  592. * @public
  593. */
  594. function onLog(logCallback, options) {
  595. if (logCallback !== null && typeof logCallback !== 'function') {
  596. throw ERROR_FACTORY.create("invalid-log-argument" /* AppError.INVALID_LOG_ARGUMENT */);
  597. }
  598. setUserLogHandler(logCallback, options);
  599. }
  600. /**
  601. * Sets log level for all Firebase SDKs.
  602. *
  603. * All of the log types above the current log level are captured (i.e. if
  604. * you set the log level to `info`, errors are logged, but `debug` and
  605. * `verbose` logs are not).
  606. *
  607. * @public
  608. */
  609. function setLogLevel(logLevel) {
  610. setLogLevel$1(logLevel);
  611. }
  612. /**
  613. * @license
  614. * Copyright 2021 Google LLC
  615. *
  616. * Licensed under the Apache License, Version 2.0 (the "License");
  617. * you may not use this file except in compliance with the License.
  618. * You may obtain a copy of the License at
  619. *
  620. * http://www.apache.org/licenses/LICENSE-2.0
  621. *
  622. * Unless required by applicable law or agreed to in writing, software
  623. * distributed under the License is distributed on an "AS IS" BASIS,
  624. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  625. * See the License for the specific language governing permissions and
  626. * limitations under the License.
  627. */
  628. var DB_NAME = 'firebase-heartbeat-database';
  629. var DB_VERSION = 1;
  630. var STORE_NAME = 'firebase-heartbeat-store';
  631. var dbPromise = null;
  632. function getDbPromise() {
  633. if (!dbPromise) {
  634. dbPromise = openDB(DB_NAME, DB_VERSION, {
  635. upgrade: function (db, oldVersion) {
  636. // We don't use 'break' in this switch statement, the fall-through
  637. // behavior is what we want, because if there are multiple versions between
  638. // the old version and the current version, we want ALL the migrations
  639. // that correspond to those versions to run, not only the last one.
  640. // eslint-disable-next-line default-case
  641. switch (oldVersion) {
  642. case 0:
  643. db.createObjectStore(STORE_NAME);
  644. }
  645. }
  646. }).catch(function (e) {
  647. throw ERROR_FACTORY.create("idb-open" /* AppError.IDB_OPEN */, {
  648. originalErrorMessage: e.message
  649. });
  650. });
  651. }
  652. return dbPromise;
  653. }
  654. function readHeartbeatsFromIndexedDB(app) {
  655. return __awaiter(this, void 0, void 0, function () {
  656. var db, result, e_1, idbGetError;
  657. return __generator(this, function (_a) {
  658. switch (_a.label) {
  659. case 0:
  660. _a.trys.push([0, 3, , 4]);
  661. return [4 /*yield*/, getDbPromise()];
  662. case 1:
  663. db = _a.sent();
  664. return [4 /*yield*/, db
  665. .transaction(STORE_NAME)
  666. .objectStore(STORE_NAME)
  667. .get(computeKey(app))];
  668. case 2:
  669. result = _a.sent();
  670. return [2 /*return*/, result];
  671. case 3:
  672. e_1 = _a.sent();
  673. if (e_1 instanceof FirebaseError) {
  674. logger.warn(e_1.message);
  675. }
  676. else {
  677. idbGetError = ERROR_FACTORY.create("idb-get" /* AppError.IDB_GET */, {
  678. originalErrorMessage: e_1 === null || e_1 === void 0 ? void 0 : e_1.message
  679. });
  680. logger.warn(idbGetError.message);
  681. }
  682. return [3 /*break*/, 4];
  683. case 4: return [2 /*return*/];
  684. }
  685. });
  686. });
  687. }
  688. function writeHeartbeatsToIndexedDB(app, heartbeatObject) {
  689. return __awaiter(this, void 0, void 0, function () {
  690. var db, tx, objectStore, e_2, idbGetError;
  691. return __generator(this, function (_a) {
  692. switch (_a.label) {
  693. case 0:
  694. _a.trys.push([0, 4, , 5]);
  695. return [4 /*yield*/, getDbPromise()];
  696. case 1:
  697. db = _a.sent();
  698. tx = db.transaction(STORE_NAME, 'readwrite');
  699. objectStore = tx.objectStore(STORE_NAME);
  700. return [4 /*yield*/, objectStore.put(heartbeatObject, computeKey(app))];
  701. case 2:
  702. _a.sent();
  703. return [4 /*yield*/, tx.done];
  704. case 3:
  705. _a.sent();
  706. return [3 /*break*/, 5];
  707. case 4:
  708. e_2 = _a.sent();
  709. if (e_2 instanceof FirebaseError) {
  710. logger.warn(e_2.message);
  711. }
  712. else {
  713. idbGetError = ERROR_FACTORY.create("idb-set" /* AppError.IDB_WRITE */, {
  714. originalErrorMessage: e_2 === null || e_2 === void 0 ? void 0 : e_2.message
  715. });
  716. logger.warn(idbGetError.message);
  717. }
  718. return [3 /*break*/, 5];
  719. case 5: return [2 /*return*/];
  720. }
  721. });
  722. });
  723. }
  724. function computeKey(app) {
  725. return "".concat(app.name, "!").concat(app.options.appId);
  726. }
  727. /**
  728. * @license
  729. * Copyright 2021 Google LLC
  730. *
  731. * Licensed under the Apache License, Version 2.0 (the "License");
  732. * you may not use this file except in compliance with the License.
  733. * You may obtain a copy of the License at
  734. *
  735. * http://www.apache.org/licenses/LICENSE-2.0
  736. *
  737. * Unless required by applicable law or agreed to in writing, software
  738. * distributed under the License is distributed on an "AS IS" BASIS,
  739. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  740. * See the License for the specific language governing permissions and
  741. * limitations under the License.
  742. */
  743. var MAX_HEADER_BYTES = 1024;
  744. // 30 days
  745. var STORED_HEARTBEAT_RETENTION_MAX_MILLIS = 30 * 24 * 60 * 60 * 1000;
  746. var HeartbeatServiceImpl = /** @class */ (function () {
  747. function HeartbeatServiceImpl(container) {
  748. var _this = this;
  749. this.container = container;
  750. /**
  751. * In-memory cache for heartbeats, used by getHeartbeatsHeader() to generate
  752. * the header string.
  753. * Stores one record per date. This will be consolidated into the standard
  754. * format of one record per user agent string before being sent as a header.
  755. * Populated from indexedDB when the controller is instantiated and should
  756. * be kept in sync with indexedDB.
  757. * Leave public for easier testing.
  758. */
  759. this._heartbeatsCache = null;
  760. var app = this.container.getProvider('app').getImmediate();
  761. this._storage = new HeartbeatStorageImpl(app);
  762. this._heartbeatsCachePromise = this._storage.read().then(function (result) {
  763. _this._heartbeatsCache = result;
  764. return result;
  765. });
  766. }
  767. /**
  768. * Called to report a heartbeat. The function will generate
  769. * a HeartbeatsByUserAgent object, update heartbeatsCache, and persist it
  770. * to IndexedDB.
  771. * Note that we only store one heartbeat per day. So if a heartbeat for today is
  772. * already logged, subsequent calls to this function in the same day will be ignored.
  773. */
  774. HeartbeatServiceImpl.prototype.triggerHeartbeat = function () {
  775. return __awaiter(this, void 0, void 0, function () {
  776. var platformLogger, agent, date, _a;
  777. return __generator(this, function (_b) {
  778. switch (_b.label) {
  779. case 0:
  780. platformLogger = this.container
  781. .getProvider('platform-logger')
  782. .getImmediate();
  783. agent = platformLogger.getPlatformInfoString();
  784. date = getUTCDateString();
  785. if (!(this._heartbeatsCache === null)) return [3 /*break*/, 2];
  786. _a = this;
  787. return [4 /*yield*/, this._heartbeatsCachePromise];
  788. case 1:
  789. _a._heartbeatsCache = _b.sent();
  790. _b.label = 2;
  791. case 2:
  792. // Do not store a heartbeat if one is already stored for this day
  793. // or if a header has already been sent today.
  794. if (this._heartbeatsCache.lastSentHeartbeatDate === date ||
  795. this._heartbeatsCache.heartbeats.some(function (singleDateHeartbeat) { return singleDateHeartbeat.date === date; })) {
  796. return [2 /*return*/];
  797. }
  798. else {
  799. // There is no entry for this date. Create one.
  800. this._heartbeatsCache.heartbeats.push({ date: date, agent: agent });
  801. }
  802. // Remove entries older than 30 days.
  803. this._heartbeatsCache.heartbeats = this._heartbeatsCache.heartbeats.filter(function (singleDateHeartbeat) {
  804. var hbTimestamp = new Date(singleDateHeartbeat.date).valueOf();
  805. var now = Date.now();
  806. return now - hbTimestamp <= STORED_HEARTBEAT_RETENTION_MAX_MILLIS;
  807. });
  808. return [2 /*return*/, this._storage.overwrite(this._heartbeatsCache)];
  809. }
  810. });
  811. });
  812. };
  813. /**
  814. * Returns a base64 encoded string which can be attached to the heartbeat-specific header directly.
  815. * It also clears all heartbeats from memory as well as in IndexedDB.
  816. *
  817. * NOTE: Consuming product SDKs should not send the header if this method
  818. * returns an empty string.
  819. */
  820. HeartbeatServiceImpl.prototype.getHeartbeatsHeader = function () {
  821. return __awaiter(this, void 0, void 0, function () {
  822. var date, _a, heartbeatsToSend, unsentEntries, headerString;
  823. return __generator(this, function (_b) {
  824. switch (_b.label) {
  825. case 0:
  826. if (!(this._heartbeatsCache === null)) return [3 /*break*/, 2];
  827. return [4 /*yield*/, this._heartbeatsCachePromise];
  828. case 1:
  829. _b.sent();
  830. _b.label = 2;
  831. case 2:
  832. // If it's still null or the array is empty, there is no data to send.
  833. if (this._heartbeatsCache === null ||
  834. this._heartbeatsCache.heartbeats.length === 0) {
  835. return [2 /*return*/, ''];
  836. }
  837. date = getUTCDateString();
  838. _a = extractHeartbeatsForHeader(this._heartbeatsCache.heartbeats), heartbeatsToSend = _a.heartbeatsToSend, unsentEntries = _a.unsentEntries;
  839. headerString = base64urlEncodeWithoutPadding(JSON.stringify({ version: 2, heartbeats: heartbeatsToSend }));
  840. // Store last sent date to prevent another being logged/sent for the same day.
  841. this._heartbeatsCache.lastSentHeartbeatDate = date;
  842. if (!(unsentEntries.length > 0)) return [3 /*break*/, 4];
  843. // Store any unsent entries if they exist.
  844. this._heartbeatsCache.heartbeats = unsentEntries;
  845. // This seems more likely than emptying the array (below) to lead to some odd state
  846. // since the cache isn't empty and this will be called again on the next request,
  847. // and is probably safest if we await it.
  848. return [4 /*yield*/, this._storage.overwrite(this._heartbeatsCache)];
  849. case 3:
  850. // This seems more likely than emptying the array (below) to lead to some odd state
  851. // since the cache isn't empty and this will be called again on the next request,
  852. // and is probably safest if we await it.
  853. _b.sent();
  854. return [3 /*break*/, 5];
  855. case 4:
  856. this._heartbeatsCache.heartbeats = [];
  857. // Do not wait for this, to reduce latency.
  858. void this._storage.overwrite(this._heartbeatsCache);
  859. _b.label = 5;
  860. case 5: return [2 /*return*/, headerString];
  861. }
  862. });
  863. });
  864. };
  865. return HeartbeatServiceImpl;
  866. }());
  867. function getUTCDateString() {
  868. var today = new Date();
  869. // Returns date format 'YYYY-MM-DD'
  870. return today.toISOString().substring(0, 10);
  871. }
  872. function extractHeartbeatsForHeader(heartbeatsCache, maxSize) {
  873. var e_1, _a;
  874. if (maxSize === void 0) { maxSize = MAX_HEADER_BYTES; }
  875. // Heartbeats grouped by user agent in the standard format to be sent in
  876. // the header.
  877. var heartbeatsToSend = [];
  878. // Single date format heartbeats that are not sent.
  879. var unsentEntries = heartbeatsCache.slice();
  880. var _loop_1 = function (singleDateHeartbeat) {
  881. // Look for an existing entry with the same user agent.
  882. var heartbeatEntry = heartbeatsToSend.find(function (hb) { return hb.agent === singleDateHeartbeat.agent; });
  883. if (!heartbeatEntry) {
  884. // If no entry for this user agent exists, create one.
  885. heartbeatsToSend.push({
  886. agent: singleDateHeartbeat.agent,
  887. dates: [singleDateHeartbeat.date]
  888. });
  889. if (countBytes(heartbeatsToSend) > maxSize) {
  890. // If the header would exceed max size, remove the added heartbeat
  891. // entry and stop adding to the header.
  892. heartbeatsToSend.pop();
  893. return "break";
  894. }
  895. }
  896. else {
  897. heartbeatEntry.dates.push(singleDateHeartbeat.date);
  898. // If the header would exceed max size, remove the added date
  899. // and stop adding to the header.
  900. if (countBytes(heartbeatsToSend) > maxSize) {
  901. heartbeatEntry.dates.pop();
  902. return "break";
  903. }
  904. }
  905. // Pop unsent entry from queue. (Skipped if adding the entry exceeded
  906. // quota and the loop breaks early.)
  907. unsentEntries = unsentEntries.slice(1);
  908. };
  909. try {
  910. for (var heartbeatsCache_1 = __values(heartbeatsCache), heartbeatsCache_1_1 = heartbeatsCache_1.next(); !heartbeatsCache_1_1.done; heartbeatsCache_1_1 = heartbeatsCache_1.next()) {
  911. var singleDateHeartbeat = heartbeatsCache_1_1.value;
  912. var state_1 = _loop_1(singleDateHeartbeat);
  913. if (state_1 === "break")
  914. break;
  915. }
  916. }
  917. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  918. finally {
  919. try {
  920. if (heartbeatsCache_1_1 && !heartbeatsCache_1_1.done && (_a = heartbeatsCache_1.return)) _a.call(heartbeatsCache_1);
  921. }
  922. finally { if (e_1) throw e_1.error; }
  923. }
  924. return {
  925. heartbeatsToSend: heartbeatsToSend,
  926. unsentEntries: unsentEntries
  927. };
  928. }
  929. var HeartbeatStorageImpl = /** @class */ (function () {
  930. function HeartbeatStorageImpl(app) {
  931. this.app = app;
  932. this._canUseIndexedDBPromise = this.runIndexedDBEnvironmentCheck();
  933. }
  934. HeartbeatStorageImpl.prototype.runIndexedDBEnvironmentCheck = function () {
  935. return __awaiter(this, void 0, void 0, function () {
  936. return __generator(this, function (_a) {
  937. if (!isIndexedDBAvailable()) {
  938. return [2 /*return*/, false];
  939. }
  940. else {
  941. return [2 /*return*/, validateIndexedDBOpenable()
  942. .then(function () { return true; })
  943. .catch(function () { return false; })];
  944. }
  945. });
  946. });
  947. };
  948. /**
  949. * Read all heartbeats.
  950. */
  951. HeartbeatStorageImpl.prototype.read = function () {
  952. return __awaiter(this, void 0, void 0, function () {
  953. var canUseIndexedDB, idbHeartbeatObject;
  954. return __generator(this, function (_a) {
  955. switch (_a.label) {
  956. case 0: return [4 /*yield*/, this._canUseIndexedDBPromise];
  957. case 1:
  958. canUseIndexedDB = _a.sent();
  959. if (!!canUseIndexedDB) return [3 /*break*/, 2];
  960. return [2 /*return*/, { heartbeats: [] }];
  961. case 2: return [4 /*yield*/, readHeartbeatsFromIndexedDB(this.app)];
  962. case 3:
  963. idbHeartbeatObject = _a.sent();
  964. return [2 /*return*/, idbHeartbeatObject || { heartbeats: [] }];
  965. }
  966. });
  967. });
  968. };
  969. // overwrite the storage with the provided heartbeats
  970. HeartbeatStorageImpl.prototype.overwrite = function (heartbeatsObject) {
  971. var _a;
  972. return __awaiter(this, void 0, void 0, function () {
  973. var canUseIndexedDB, existingHeartbeatsObject;
  974. return __generator(this, function (_b) {
  975. switch (_b.label) {
  976. case 0: return [4 /*yield*/, this._canUseIndexedDBPromise];
  977. case 1:
  978. canUseIndexedDB = _b.sent();
  979. if (!!canUseIndexedDB) return [3 /*break*/, 2];
  980. return [2 /*return*/];
  981. case 2: return [4 /*yield*/, this.read()];
  982. case 3:
  983. existingHeartbeatsObject = _b.sent();
  984. return [2 /*return*/, writeHeartbeatsToIndexedDB(this.app, {
  985. lastSentHeartbeatDate: (_a = heartbeatsObject.lastSentHeartbeatDate) !== null && _a !== void 0 ? _a : existingHeartbeatsObject.lastSentHeartbeatDate,
  986. heartbeats: heartbeatsObject.heartbeats
  987. })];
  988. }
  989. });
  990. });
  991. };
  992. // add heartbeats
  993. HeartbeatStorageImpl.prototype.add = function (heartbeatsObject) {
  994. var _a;
  995. return __awaiter(this, void 0, void 0, function () {
  996. var canUseIndexedDB, existingHeartbeatsObject;
  997. return __generator(this, function (_b) {
  998. switch (_b.label) {
  999. case 0: return [4 /*yield*/, this._canUseIndexedDBPromise];
  1000. case 1:
  1001. canUseIndexedDB = _b.sent();
  1002. if (!!canUseIndexedDB) return [3 /*break*/, 2];
  1003. return [2 /*return*/];
  1004. case 2: return [4 /*yield*/, this.read()];
  1005. case 3:
  1006. existingHeartbeatsObject = _b.sent();
  1007. return [2 /*return*/, writeHeartbeatsToIndexedDB(this.app, {
  1008. lastSentHeartbeatDate: (_a = heartbeatsObject.lastSentHeartbeatDate) !== null && _a !== void 0 ? _a : existingHeartbeatsObject.lastSentHeartbeatDate,
  1009. heartbeats: __spreadArray(__spreadArray([], __read(existingHeartbeatsObject.heartbeats), false), __read(heartbeatsObject.heartbeats), false)
  1010. })];
  1011. }
  1012. });
  1013. });
  1014. };
  1015. return HeartbeatStorageImpl;
  1016. }());
  1017. /**
  1018. * Calculate bytes of a HeartbeatsByUserAgent array after being wrapped
  1019. * in a platform logging header JSON object, stringified, and converted
  1020. * to base 64.
  1021. */
  1022. function countBytes(heartbeatsCache) {
  1023. // base64 has a restricted set of characters, all of which should be 1 byte.
  1024. return base64urlEncodeWithoutPadding(
  1025. // heartbeatsCache wrapper properties
  1026. JSON.stringify({ version: 2, heartbeats: heartbeatsCache })).length;
  1027. }
  1028. /**
  1029. * @license
  1030. * Copyright 2019 Google LLC
  1031. *
  1032. * Licensed under the Apache License, Version 2.0 (the "License");
  1033. * you may not use this file except in compliance with the License.
  1034. * You may obtain a copy of the License at
  1035. *
  1036. * http://www.apache.org/licenses/LICENSE-2.0
  1037. *
  1038. * Unless required by applicable law or agreed to in writing, software
  1039. * distributed under the License is distributed on an "AS IS" BASIS,
  1040. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1041. * See the License for the specific language governing permissions and
  1042. * limitations under the License.
  1043. */
  1044. function registerCoreComponents(variant) {
  1045. _registerComponent(new Component('platform-logger', function (container) { return new PlatformLoggerServiceImpl(container); }, "PRIVATE" /* ComponentType.PRIVATE */));
  1046. _registerComponent(new Component('heartbeat', function (container) { return new HeartbeatServiceImpl(container); }, "PRIVATE" /* ComponentType.PRIVATE */));
  1047. // Register `app` package.
  1048. registerVersion(name$o, version$1, variant);
  1049. // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
  1050. registerVersion(name$o, version$1, 'esm5');
  1051. // Register platform SDK identifier (no version).
  1052. registerVersion('fire-js', '');
  1053. }
  1054. /**
  1055. * Firebase App
  1056. *
  1057. * @remarks This package coordinates the communication between the different Firebase components
  1058. * @packageDocumentation
  1059. */
  1060. registerCoreComponents('');
  1061. export { SDK_VERSION, DEFAULT_ENTRY_NAME as _DEFAULT_ENTRY_NAME, _addComponent, _addOrOverwriteComponent, _apps, _clearComponents, _components, _getProvider, _registerComponent, _removeServiceInstance, deleteApp, getApp, getApps, initializeApp, onLog, registerVersion, setLogLevel };
  1062. //# sourceMappingURL=index.esm5.js.map