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

index.esm.js 57KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423
  1. import { getApp, _getProvider, _registerComponent, registerVersion } from '@firebase/app';
  2. import { Component } from '@firebase/component';
  3. import { __awaiter, __generator, __spreadArray, __read, __values, __assign } from 'tslib';
  4. import { ErrorFactory, FirebaseError } from '@firebase/util';
  5. import { openDB } from 'idb';
  6. var name = "@firebase/installations";
  7. var version = "0.6.1";
  8. /**
  9. * @license
  10. * Copyright 2019 Google LLC
  11. *
  12. * Licensed under the Apache License, Version 2.0 (the "License");
  13. * you may not use this file except in compliance with the License.
  14. * You may obtain a copy of the License at
  15. *
  16. * http://www.apache.org/licenses/LICENSE-2.0
  17. *
  18. * Unless required by applicable law or agreed to in writing, software
  19. * distributed under the License is distributed on an "AS IS" BASIS,
  20. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  21. * See the License for the specific language governing permissions and
  22. * limitations under the License.
  23. */
  24. var PENDING_TIMEOUT_MS = 10000;
  25. var PACKAGE_VERSION = "w:".concat(version);
  26. var INTERNAL_AUTH_VERSION = 'FIS_v2';
  27. var INSTALLATIONS_API_URL = 'https://firebaseinstallations.googleapis.com/v1';
  28. var TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour
  29. var SERVICE = 'installations';
  30. var SERVICE_NAME = 'Installations';
  31. /**
  32. * @license
  33. * Copyright 2019 Google LLC
  34. *
  35. * Licensed under the Apache License, Version 2.0 (the "License");
  36. * you may not use this file except in compliance with the License.
  37. * You may obtain a copy of the License at
  38. *
  39. * http://www.apache.org/licenses/LICENSE-2.0
  40. *
  41. * Unless required by applicable law or agreed to in writing, software
  42. * distributed under the License is distributed on an "AS IS" BASIS,
  43. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  44. * See the License for the specific language governing permissions and
  45. * limitations under the License.
  46. */
  47. var _a;
  48. var ERROR_DESCRIPTION_MAP = (_a = {},
  49. _a["missing-app-config-values" /* ErrorCode.MISSING_APP_CONFIG_VALUES */] = 'Missing App configuration value: "{$valueName}"',
  50. _a["not-registered" /* ErrorCode.NOT_REGISTERED */] = 'Firebase Installation is not registered.',
  51. _a["installation-not-found" /* ErrorCode.INSTALLATION_NOT_FOUND */] = 'Firebase Installation not found.',
  52. _a["request-failed" /* ErrorCode.REQUEST_FAILED */] = '{$requestName} request failed with error "{$serverCode} {$serverStatus}: {$serverMessage}"',
  53. _a["app-offline" /* ErrorCode.APP_OFFLINE */] = 'Could not process request. Application offline.',
  54. _a["delete-pending-registration" /* ErrorCode.DELETE_PENDING_REGISTRATION */] = "Can't delete installation while there is a pending registration request.",
  55. _a);
  56. var ERROR_FACTORY = new ErrorFactory(SERVICE, SERVICE_NAME, ERROR_DESCRIPTION_MAP);
  57. /** Returns true if error is a FirebaseError that is based on an error from the server. */
  58. function isServerError(error) {
  59. return (error instanceof FirebaseError &&
  60. error.code.includes("request-failed" /* ErrorCode.REQUEST_FAILED */));
  61. }
  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. function getInstallationsEndpoint(_a) {
  79. var projectId = _a.projectId;
  80. return "".concat(INSTALLATIONS_API_URL, "/projects/").concat(projectId, "/installations");
  81. }
  82. function extractAuthTokenInfoFromResponse(response) {
  83. return {
  84. token: response.token,
  85. requestStatus: 2 /* RequestStatus.COMPLETED */,
  86. expiresIn: getExpiresInFromResponseExpiresIn(response.expiresIn),
  87. creationTime: Date.now()
  88. };
  89. }
  90. function getErrorFromResponse(requestName, response) {
  91. return __awaiter(this, void 0, void 0, function () {
  92. var responseJson, errorData;
  93. return __generator(this, function (_a) {
  94. switch (_a.label) {
  95. case 0: return [4 /*yield*/, response.json()];
  96. case 1:
  97. responseJson = _a.sent();
  98. errorData = responseJson.error;
  99. return [2 /*return*/, ERROR_FACTORY.create("request-failed" /* ErrorCode.REQUEST_FAILED */, {
  100. requestName: requestName,
  101. serverCode: errorData.code,
  102. serverMessage: errorData.message,
  103. serverStatus: errorData.status
  104. })];
  105. }
  106. });
  107. });
  108. }
  109. function getHeaders(_a) {
  110. var apiKey = _a.apiKey;
  111. return new Headers({
  112. 'Content-Type': 'application/json',
  113. Accept: 'application/json',
  114. 'x-goog-api-key': apiKey
  115. });
  116. }
  117. function getHeadersWithAuth(appConfig, _a) {
  118. var refreshToken = _a.refreshToken;
  119. var headers = getHeaders(appConfig);
  120. headers.append('Authorization', getAuthorizationHeader(refreshToken));
  121. return headers;
  122. }
  123. /**
  124. * Calls the passed in fetch wrapper and returns the response.
  125. * If the returned response has a status of 5xx, re-runs the function once and
  126. * returns the response.
  127. */
  128. function retryIfServerError(fn) {
  129. return __awaiter(this, void 0, void 0, function () {
  130. var result;
  131. return __generator(this, function (_a) {
  132. switch (_a.label) {
  133. case 0: return [4 /*yield*/, fn()];
  134. case 1:
  135. result = _a.sent();
  136. if (result.status >= 500 && result.status < 600) {
  137. // Internal Server Error. Retry request.
  138. return [2 /*return*/, fn()];
  139. }
  140. return [2 /*return*/, result];
  141. }
  142. });
  143. });
  144. }
  145. function getExpiresInFromResponseExpiresIn(responseExpiresIn) {
  146. // This works because the server will never respond with fractions of a second.
  147. return Number(responseExpiresIn.replace('s', '000'));
  148. }
  149. function getAuthorizationHeader(refreshToken) {
  150. return "".concat(INTERNAL_AUTH_VERSION, " ").concat(refreshToken);
  151. }
  152. /**
  153. * @license
  154. * Copyright 2019 Google LLC
  155. *
  156. * Licensed under the Apache License, Version 2.0 (the "License");
  157. * you may not use this file except in compliance with the License.
  158. * You may obtain a copy of the License at
  159. *
  160. * http://www.apache.org/licenses/LICENSE-2.0
  161. *
  162. * Unless required by applicable law or agreed to in writing, software
  163. * distributed under the License is distributed on an "AS IS" BASIS,
  164. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  165. * See the License for the specific language governing permissions and
  166. * limitations under the License.
  167. */
  168. function createInstallationRequest(_a, _b) {
  169. var appConfig = _a.appConfig, heartbeatServiceProvider = _a.heartbeatServiceProvider;
  170. var fid = _b.fid;
  171. return __awaiter(this, void 0, void 0, function () {
  172. var endpoint, headers, heartbeatService, heartbeatsHeader, body, request, response, responseValue, registeredInstallationEntry;
  173. return __generator(this, function (_c) {
  174. switch (_c.label) {
  175. case 0:
  176. endpoint = getInstallationsEndpoint(appConfig);
  177. headers = getHeaders(appConfig);
  178. heartbeatService = heartbeatServiceProvider.getImmediate({
  179. optional: true
  180. });
  181. if (!heartbeatService) return [3 /*break*/, 2];
  182. return [4 /*yield*/, heartbeatService.getHeartbeatsHeader()];
  183. case 1:
  184. heartbeatsHeader = _c.sent();
  185. if (heartbeatsHeader) {
  186. headers.append('x-firebase-client', heartbeatsHeader);
  187. }
  188. _c.label = 2;
  189. case 2:
  190. body = {
  191. fid: fid,
  192. authVersion: INTERNAL_AUTH_VERSION,
  193. appId: appConfig.appId,
  194. sdkVersion: PACKAGE_VERSION
  195. };
  196. request = {
  197. method: 'POST',
  198. headers: headers,
  199. body: JSON.stringify(body)
  200. };
  201. return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })];
  202. case 3:
  203. response = _c.sent();
  204. if (!response.ok) return [3 /*break*/, 5];
  205. return [4 /*yield*/, response.json()];
  206. case 4:
  207. responseValue = _c.sent();
  208. registeredInstallationEntry = {
  209. fid: responseValue.fid || fid,
  210. registrationStatus: 2 /* RequestStatus.COMPLETED */,
  211. refreshToken: responseValue.refreshToken,
  212. authToken: extractAuthTokenInfoFromResponse(responseValue.authToken)
  213. };
  214. return [2 /*return*/, registeredInstallationEntry];
  215. case 5: return [4 /*yield*/, getErrorFromResponse('Create Installation', response)];
  216. case 6: throw _c.sent();
  217. }
  218. });
  219. });
  220. }
  221. /**
  222. * @license
  223. * Copyright 2019 Google LLC
  224. *
  225. * Licensed under the Apache License, Version 2.0 (the "License");
  226. * you may not use this file except in compliance with the License.
  227. * You may obtain a copy of the License at
  228. *
  229. * http://www.apache.org/licenses/LICENSE-2.0
  230. *
  231. * Unless required by applicable law or agreed to in writing, software
  232. * distributed under the License is distributed on an "AS IS" BASIS,
  233. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  234. * See the License for the specific language governing permissions and
  235. * limitations under the License.
  236. */
  237. /** Returns a promise that resolves after given time passes. */
  238. function sleep(ms) {
  239. return new Promise(function (resolve) {
  240. setTimeout(resolve, ms);
  241. });
  242. }
  243. /**
  244. * @license
  245. * Copyright 2019 Google LLC
  246. *
  247. * Licensed under the Apache License, Version 2.0 (the "License");
  248. * you may not use this file except in compliance with the License.
  249. * You may obtain a copy of the License at
  250. *
  251. * http://www.apache.org/licenses/LICENSE-2.0
  252. *
  253. * Unless required by applicable law or agreed to in writing, software
  254. * distributed under the License is distributed on an "AS IS" BASIS,
  255. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  256. * See the License for the specific language governing permissions and
  257. * limitations under the License.
  258. */
  259. function bufferToBase64UrlSafe(array) {
  260. var b64 = btoa(String.fromCharCode.apply(String, __spreadArray([], __read(array), false)));
  261. return b64.replace(/\+/g, '-').replace(/\//g, '_');
  262. }
  263. /**
  264. * @license
  265. * Copyright 2019 Google LLC
  266. *
  267. * Licensed under the Apache License, Version 2.0 (the "License");
  268. * you may not use this file except in compliance with the License.
  269. * You may obtain a copy of the License at
  270. *
  271. * http://www.apache.org/licenses/LICENSE-2.0
  272. *
  273. * Unless required by applicable law or agreed to in writing, software
  274. * distributed under the License is distributed on an "AS IS" BASIS,
  275. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  276. * See the License for the specific language governing permissions and
  277. * limitations under the License.
  278. */
  279. var VALID_FID_PATTERN = /^[cdef][\w-]{21}$/;
  280. var INVALID_FID = '';
  281. /**
  282. * Generates a new FID using random values from Web Crypto API.
  283. * Returns an empty string if FID generation fails for any reason.
  284. */
  285. function generateFid() {
  286. try {
  287. // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5
  288. // bytes. our implementation generates a 17 byte array instead.
  289. var fidByteArray = new Uint8Array(17);
  290. var crypto_1 = self.crypto || self.msCrypto;
  291. crypto_1.getRandomValues(fidByteArray);
  292. // Replace the first 4 random bits with the constant FID header of 0b0111.
  293. fidByteArray[0] = 112 + (fidByteArray[0] % 16);
  294. var fid = encode(fidByteArray);
  295. return VALID_FID_PATTERN.test(fid) ? fid : INVALID_FID;
  296. }
  297. catch (_a) {
  298. // FID generation errored
  299. return INVALID_FID;
  300. }
  301. }
  302. /** Converts a FID Uint8Array to a base64 string representation. */
  303. function encode(fidByteArray) {
  304. var b64String = bufferToBase64UrlSafe(fidByteArray);
  305. // Remove the 23rd character that was added because of the extra 4 bits at the
  306. // end of our 17 byte array, and the '=' padding.
  307. return b64String.substr(0, 22);
  308. }
  309. /**
  310. * @license
  311. * Copyright 2019 Google LLC
  312. *
  313. * Licensed under the Apache License, Version 2.0 (the "License");
  314. * you may not use this file except in compliance with the License.
  315. * You may obtain a copy of the License at
  316. *
  317. * http://www.apache.org/licenses/LICENSE-2.0
  318. *
  319. * Unless required by applicable law or agreed to in writing, software
  320. * distributed under the License is distributed on an "AS IS" BASIS,
  321. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  322. * See the License for the specific language governing permissions and
  323. * limitations under the License.
  324. */
  325. /** Returns a string key that can be used to identify the app. */
  326. function getKey(appConfig) {
  327. return "".concat(appConfig.appName, "!").concat(appConfig.appId);
  328. }
  329. /**
  330. * @license
  331. * Copyright 2019 Google LLC
  332. *
  333. * Licensed under the Apache License, Version 2.0 (the "License");
  334. * you may not use this file except in compliance with the License.
  335. * You may obtain a copy of the License at
  336. *
  337. * http://www.apache.org/licenses/LICENSE-2.0
  338. *
  339. * Unless required by applicable law or agreed to in writing, software
  340. * distributed under the License is distributed on an "AS IS" BASIS,
  341. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  342. * See the License for the specific language governing permissions and
  343. * limitations under the License.
  344. */
  345. var fidChangeCallbacks = new Map();
  346. /**
  347. * Calls the onIdChange callbacks with the new FID value, and broadcasts the
  348. * change to other tabs.
  349. */
  350. function fidChanged(appConfig, fid) {
  351. var key = getKey(appConfig);
  352. callFidChangeCallbacks(key, fid);
  353. broadcastFidChange(key, fid);
  354. }
  355. function addCallback(appConfig, callback) {
  356. // Open the broadcast channel if it's not already open,
  357. // to be able to listen to change events from other tabs.
  358. getBroadcastChannel();
  359. var key = getKey(appConfig);
  360. var callbackSet = fidChangeCallbacks.get(key);
  361. if (!callbackSet) {
  362. callbackSet = new Set();
  363. fidChangeCallbacks.set(key, callbackSet);
  364. }
  365. callbackSet.add(callback);
  366. }
  367. function removeCallback(appConfig, callback) {
  368. var key = getKey(appConfig);
  369. var callbackSet = fidChangeCallbacks.get(key);
  370. if (!callbackSet) {
  371. return;
  372. }
  373. callbackSet.delete(callback);
  374. if (callbackSet.size === 0) {
  375. fidChangeCallbacks.delete(key);
  376. }
  377. // Close broadcast channel if there are no more callbacks.
  378. closeBroadcastChannel();
  379. }
  380. function callFidChangeCallbacks(key, fid) {
  381. var e_1, _a;
  382. var callbacks = fidChangeCallbacks.get(key);
  383. if (!callbacks) {
  384. return;
  385. }
  386. try {
  387. for (var callbacks_1 = __values(callbacks), callbacks_1_1 = callbacks_1.next(); !callbacks_1_1.done; callbacks_1_1 = callbacks_1.next()) {
  388. var callback = callbacks_1_1.value;
  389. callback(fid);
  390. }
  391. }
  392. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  393. finally {
  394. try {
  395. if (callbacks_1_1 && !callbacks_1_1.done && (_a = callbacks_1.return)) _a.call(callbacks_1);
  396. }
  397. finally { if (e_1) throw e_1.error; }
  398. }
  399. }
  400. function broadcastFidChange(key, fid) {
  401. var channel = getBroadcastChannel();
  402. if (channel) {
  403. channel.postMessage({ key: key, fid: fid });
  404. }
  405. closeBroadcastChannel();
  406. }
  407. var broadcastChannel = null;
  408. /** Opens and returns a BroadcastChannel if it is supported by the browser. */
  409. function getBroadcastChannel() {
  410. if (!broadcastChannel && 'BroadcastChannel' in self) {
  411. broadcastChannel = new BroadcastChannel('[Firebase] FID Change');
  412. broadcastChannel.onmessage = function (e) {
  413. callFidChangeCallbacks(e.data.key, e.data.fid);
  414. };
  415. }
  416. return broadcastChannel;
  417. }
  418. function closeBroadcastChannel() {
  419. if (fidChangeCallbacks.size === 0 && broadcastChannel) {
  420. broadcastChannel.close();
  421. broadcastChannel = null;
  422. }
  423. }
  424. /**
  425. * @license
  426. * Copyright 2019 Google LLC
  427. *
  428. * Licensed under the Apache License, Version 2.0 (the "License");
  429. * you may not use this file except in compliance with the License.
  430. * You may obtain a copy of the License at
  431. *
  432. * http://www.apache.org/licenses/LICENSE-2.0
  433. *
  434. * Unless required by applicable law or agreed to in writing, software
  435. * distributed under the License is distributed on an "AS IS" BASIS,
  436. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  437. * See the License for the specific language governing permissions and
  438. * limitations under the License.
  439. */
  440. var DATABASE_NAME = 'firebase-installations-database';
  441. var DATABASE_VERSION = 1;
  442. var OBJECT_STORE_NAME = 'firebase-installations-store';
  443. var dbPromise = null;
  444. function getDbPromise() {
  445. if (!dbPromise) {
  446. dbPromise = openDB(DATABASE_NAME, DATABASE_VERSION, {
  447. upgrade: function (db, oldVersion) {
  448. // We don't use 'break' in this switch statement, the fall-through
  449. // behavior is what we want, because if there are multiple versions between
  450. // the old version and the current version, we want ALL the migrations
  451. // that correspond to those versions to run, not only the last one.
  452. // eslint-disable-next-line default-case
  453. switch (oldVersion) {
  454. case 0:
  455. db.createObjectStore(OBJECT_STORE_NAME);
  456. }
  457. }
  458. });
  459. }
  460. return dbPromise;
  461. }
  462. /** Assigns or overwrites the record for the given key with the given value. */
  463. function set(appConfig, value) {
  464. return __awaiter(this, void 0, void 0, function () {
  465. var key, db, tx, objectStore, oldValue;
  466. return __generator(this, function (_a) {
  467. switch (_a.label) {
  468. case 0:
  469. key = getKey(appConfig);
  470. return [4 /*yield*/, getDbPromise()];
  471. case 1:
  472. db = _a.sent();
  473. tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
  474. objectStore = tx.objectStore(OBJECT_STORE_NAME);
  475. return [4 /*yield*/, objectStore.get(key)];
  476. case 2:
  477. oldValue = (_a.sent());
  478. return [4 /*yield*/, objectStore.put(value, key)];
  479. case 3:
  480. _a.sent();
  481. return [4 /*yield*/, tx.done];
  482. case 4:
  483. _a.sent();
  484. if (!oldValue || oldValue.fid !== value.fid) {
  485. fidChanged(appConfig, value.fid);
  486. }
  487. return [2 /*return*/, value];
  488. }
  489. });
  490. });
  491. }
  492. /** Removes record(s) from the objectStore that match the given key. */
  493. function remove(appConfig) {
  494. return __awaiter(this, void 0, void 0, function () {
  495. var key, db, tx;
  496. return __generator(this, function (_a) {
  497. switch (_a.label) {
  498. case 0:
  499. key = getKey(appConfig);
  500. return [4 /*yield*/, getDbPromise()];
  501. case 1:
  502. db = _a.sent();
  503. tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
  504. return [4 /*yield*/, tx.objectStore(OBJECT_STORE_NAME).delete(key)];
  505. case 2:
  506. _a.sent();
  507. return [4 /*yield*/, tx.done];
  508. case 3:
  509. _a.sent();
  510. return [2 /*return*/];
  511. }
  512. });
  513. });
  514. }
  515. /**
  516. * Atomically updates a record with the result of updateFn, which gets
  517. * called with the current value. If newValue is undefined, the record is
  518. * deleted instead.
  519. * @return Updated value
  520. */
  521. function update(appConfig, updateFn) {
  522. return __awaiter(this, void 0, void 0, function () {
  523. var key, db, tx, store, oldValue, newValue;
  524. return __generator(this, function (_a) {
  525. switch (_a.label) {
  526. case 0:
  527. key = getKey(appConfig);
  528. return [4 /*yield*/, getDbPromise()];
  529. case 1:
  530. db = _a.sent();
  531. tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
  532. store = tx.objectStore(OBJECT_STORE_NAME);
  533. return [4 /*yield*/, store.get(key)];
  534. case 2:
  535. oldValue = (_a.sent());
  536. newValue = updateFn(oldValue);
  537. if (!(newValue === undefined)) return [3 /*break*/, 4];
  538. return [4 /*yield*/, store.delete(key)];
  539. case 3:
  540. _a.sent();
  541. return [3 /*break*/, 6];
  542. case 4: return [4 /*yield*/, store.put(newValue, key)];
  543. case 5:
  544. _a.sent();
  545. _a.label = 6;
  546. case 6: return [4 /*yield*/, tx.done];
  547. case 7:
  548. _a.sent();
  549. if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) {
  550. fidChanged(appConfig, newValue.fid);
  551. }
  552. return [2 /*return*/, newValue];
  553. }
  554. });
  555. });
  556. }
  557. /**
  558. * @license
  559. * Copyright 2019 Google LLC
  560. *
  561. * Licensed under the Apache License, Version 2.0 (the "License");
  562. * you may not use this file except in compliance with the License.
  563. * You may obtain a copy of the License at
  564. *
  565. * http://www.apache.org/licenses/LICENSE-2.0
  566. *
  567. * Unless required by applicable law or agreed to in writing, software
  568. * distributed under the License is distributed on an "AS IS" BASIS,
  569. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  570. * See the License for the specific language governing permissions and
  571. * limitations under the License.
  572. */
  573. /**
  574. * Updates and returns the InstallationEntry from the database.
  575. * Also triggers a registration request if it is necessary and possible.
  576. */
  577. function getInstallationEntry(installations) {
  578. return __awaiter(this, void 0, void 0, function () {
  579. var registrationPromise, installationEntry;
  580. var _a;
  581. return __generator(this, function (_b) {
  582. switch (_b.label) {
  583. case 0: return [4 /*yield*/, update(installations.appConfig, function (oldEntry) {
  584. var installationEntry = updateOrCreateInstallationEntry(oldEntry);
  585. var entryWithPromise = triggerRegistrationIfNecessary(installations, installationEntry);
  586. registrationPromise = entryWithPromise.registrationPromise;
  587. return entryWithPromise.installationEntry;
  588. })];
  589. case 1:
  590. installationEntry = _b.sent();
  591. if (!(installationEntry.fid === INVALID_FID)) return [3 /*break*/, 3];
  592. _a = {};
  593. return [4 /*yield*/, registrationPromise];
  594. case 2:
  595. // FID generation failed. Waiting for the FID from the server.
  596. return [2 /*return*/, (_a.installationEntry = _b.sent(), _a)];
  597. case 3: return [2 /*return*/, {
  598. installationEntry: installationEntry,
  599. registrationPromise: registrationPromise
  600. }];
  601. }
  602. });
  603. });
  604. }
  605. /**
  606. * Creates a new Installation Entry if one does not exist.
  607. * Also clears timed out pending requests.
  608. */
  609. function updateOrCreateInstallationEntry(oldEntry) {
  610. var entry = oldEntry || {
  611. fid: generateFid(),
  612. registrationStatus: 0 /* RequestStatus.NOT_STARTED */
  613. };
  614. return clearTimedOutRequest(entry);
  615. }
  616. /**
  617. * If the Firebase Installation is not registered yet, this will trigger the
  618. * registration and return an InProgressInstallationEntry.
  619. *
  620. * If registrationPromise does not exist, the installationEntry is guaranteed
  621. * to be registered.
  622. */
  623. function triggerRegistrationIfNecessary(installations, installationEntry) {
  624. if (installationEntry.registrationStatus === 0 /* RequestStatus.NOT_STARTED */) {
  625. if (!navigator.onLine) {
  626. // Registration required but app is offline.
  627. var registrationPromiseWithError = Promise.reject(ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */));
  628. return {
  629. installationEntry: installationEntry,
  630. registrationPromise: registrationPromiseWithError
  631. };
  632. }
  633. // Try registering. Change status to IN_PROGRESS.
  634. var inProgressEntry = {
  635. fid: installationEntry.fid,
  636. registrationStatus: 1 /* RequestStatus.IN_PROGRESS */,
  637. registrationTime: Date.now()
  638. };
  639. var registrationPromise = registerInstallation(installations, inProgressEntry);
  640. return { installationEntry: inProgressEntry, registrationPromise: registrationPromise };
  641. }
  642. else if (installationEntry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */) {
  643. return {
  644. installationEntry: installationEntry,
  645. registrationPromise: waitUntilFidRegistration(installations)
  646. };
  647. }
  648. else {
  649. return { installationEntry: installationEntry };
  650. }
  651. }
  652. /** This will be executed only once for each new Firebase Installation. */
  653. function registerInstallation(installations, installationEntry) {
  654. return __awaiter(this, void 0, void 0, function () {
  655. var registeredInstallationEntry, e_1;
  656. return __generator(this, function (_a) {
  657. switch (_a.label) {
  658. case 0:
  659. _a.trys.push([0, 2, , 7]);
  660. return [4 /*yield*/, createInstallationRequest(installations, installationEntry)];
  661. case 1:
  662. registeredInstallationEntry = _a.sent();
  663. return [2 /*return*/, set(installations.appConfig, registeredInstallationEntry)];
  664. case 2:
  665. e_1 = _a.sent();
  666. if (!(isServerError(e_1) && e_1.customData.serverCode === 409)) return [3 /*break*/, 4];
  667. // Server returned a "FID can not be used" error.
  668. // Generate a new ID next time.
  669. return [4 /*yield*/, remove(installations.appConfig)];
  670. case 3:
  671. // Server returned a "FID can not be used" error.
  672. // Generate a new ID next time.
  673. _a.sent();
  674. return [3 /*break*/, 6];
  675. case 4:
  676. // Registration failed. Set FID as not registered.
  677. return [4 /*yield*/, set(installations.appConfig, {
  678. fid: installationEntry.fid,
  679. registrationStatus: 0 /* RequestStatus.NOT_STARTED */
  680. })];
  681. case 5:
  682. // Registration failed. Set FID as not registered.
  683. _a.sent();
  684. _a.label = 6;
  685. case 6: throw e_1;
  686. case 7: return [2 /*return*/];
  687. }
  688. });
  689. });
  690. }
  691. /** Call if FID registration is pending in another request. */
  692. function waitUntilFidRegistration(installations) {
  693. return __awaiter(this, void 0, void 0, function () {
  694. var entry, _a, installationEntry, registrationPromise;
  695. return __generator(this, function (_b) {
  696. switch (_b.label) {
  697. case 0: return [4 /*yield*/, updateInstallationRequest(installations.appConfig)];
  698. case 1:
  699. entry = _b.sent();
  700. _b.label = 2;
  701. case 2:
  702. if (!(entry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */)) return [3 /*break*/, 5];
  703. // createInstallation request still in progress.
  704. return [4 /*yield*/, sleep(100)];
  705. case 3:
  706. // createInstallation request still in progress.
  707. _b.sent();
  708. return [4 /*yield*/, updateInstallationRequest(installations.appConfig)];
  709. case 4:
  710. entry = _b.sent();
  711. return [3 /*break*/, 2];
  712. case 5:
  713. if (!(entry.registrationStatus === 0 /* RequestStatus.NOT_STARTED */)) return [3 /*break*/, 7];
  714. return [4 /*yield*/, getInstallationEntry(installations)];
  715. case 6:
  716. _a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;
  717. if (registrationPromise) {
  718. return [2 /*return*/, registrationPromise];
  719. }
  720. else {
  721. // if there is no registrationPromise, entry is registered.
  722. return [2 /*return*/, installationEntry];
  723. }
  724. case 7: return [2 /*return*/, entry];
  725. }
  726. });
  727. });
  728. }
  729. /**
  730. * Called only if there is a CreateInstallation request in progress.
  731. *
  732. * Updates the InstallationEntry in the DB based on the status of the
  733. * CreateInstallation request.
  734. *
  735. * Returns the updated InstallationEntry.
  736. */
  737. function updateInstallationRequest(appConfig) {
  738. return update(appConfig, function (oldEntry) {
  739. if (!oldEntry) {
  740. throw ERROR_FACTORY.create("installation-not-found" /* ErrorCode.INSTALLATION_NOT_FOUND */);
  741. }
  742. return clearTimedOutRequest(oldEntry);
  743. });
  744. }
  745. function clearTimedOutRequest(entry) {
  746. if (hasInstallationRequestTimedOut(entry)) {
  747. return {
  748. fid: entry.fid,
  749. registrationStatus: 0 /* RequestStatus.NOT_STARTED */
  750. };
  751. }
  752. return entry;
  753. }
  754. function hasInstallationRequestTimedOut(installationEntry) {
  755. return (installationEntry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */ &&
  756. installationEntry.registrationTime + PENDING_TIMEOUT_MS < Date.now());
  757. }
  758. /**
  759. * @license
  760. * Copyright 2019 Google LLC
  761. *
  762. * Licensed under the Apache License, Version 2.0 (the "License");
  763. * you may not use this file except in compliance with the License.
  764. * You may obtain a copy of the License at
  765. *
  766. * http://www.apache.org/licenses/LICENSE-2.0
  767. *
  768. * Unless required by applicable law or agreed to in writing, software
  769. * distributed under the License is distributed on an "AS IS" BASIS,
  770. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  771. * See the License for the specific language governing permissions and
  772. * limitations under the License.
  773. */
  774. function generateAuthTokenRequest(_a, installationEntry) {
  775. var appConfig = _a.appConfig, heartbeatServiceProvider = _a.heartbeatServiceProvider;
  776. return __awaiter(this, void 0, void 0, function () {
  777. var endpoint, headers, heartbeatService, heartbeatsHeader, body, request, response, responseValue, completedAuthToken;
  778. return __generator(this, function (_b) {
  779. switch (_b.label) {
  780. case 0:
  781. endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);
  782. headers = getHeadersWithAuth(appConfig, installationEntry);
  783. heartbeatService = heartbeatServiceProvider.getImmediate({
  784. optional: true
  785. });
  786. if (!heartbeatService) return [3 /*break*/, 2];
  787. return [4 /*yield*/, heartbeatService.getHeartbeatsHeader()];
  788. case 1:
  789. heartbeatsHeader = _b.sent();
  790. if (heartbeatsHeader) {
  791. headers.append('x-firebase-client', heartbeatsHeader);
  792. }
  793. _b.label = 2;
  794. case 2:
  795. body = {
  796. installation: {
  797. sdkVersion: PACKAGE_VERSION,
  798. appId: appConfig.appId
  799. }
  800. };
  801. request = {
  802. method: 'POST',
  803. headers: headers,
  804. body: JSON.stringify(body)
  805. };
  806. return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })];
  807. case 3:
  808. response = _b.sent();
  809. if (!response.ok) return [3 /*break*/, 5];
  810. return [4 /*yield*/, response.json()];
  811. case 4:
  812. responseValue = _b.sent();
  813. completedAuthToken = extractAuthTokenInfoFromResponse(responseValue);
  814. return [2 /*return*/, completedAuthToken];
  815. case 5: return [4 /*yield*/, getErrorFromResponse('Generate Auth Token', response)];
  816. case 6: throw _b.sent();
  817. }
  818. });
  819. });
  820. }
  821. function getGenerateAuthTokenEndpoint(appConfig, _a) {
  822. var fid = _a.fid;
  823. return "".concat(getInstallationsEndpoint(appConfig), "/").concat(fid, "/authTokens:generate");
  824. }
  825. /**
  826. * @license
  827. * Copyright 2019 Google LLC
  828. *
  829. * Licensed under the Apache License, Version 2.0 (the "License");
  830. * you may not use this file except in compliance with the License.
  831. * You may obtain a copy of the License at
  832. *
  833. * http://www.apache.org/licenses/LICENSE-2.0
  834. *
  835. * Unless required by applicable law or agreed to in writing, software
  836. * distributed under the License is distributed on an "AS IS" BASIS,
  837. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  838. * See the License for the specific language governing permissions and
  839. * limitations under the License.
  840. */
  841. /**
  842. * Returns a valid authentication token for the installation. Generates a new
  843. * token if one doesn't exist, is expired or about to expire.
  844. *
  845. * Should only be called if the Firebase Installation is registered.
  846. */
  847. function refreshAuthToken(installations, forceRefresh) {
  848. if (forceRefresh === void 0) { forceRefresh = false; }
  849. return __awaiter(this, void 0, void 0, function () {
  850. var tokenPromise, entry, authToken, _a;
  851. return __generator(this, function (_b) {
  852. switch (_b.label) {
  853. case 0: return [4 /*yield*/, update(installations.appConfig, function (oldEntry) {
  854. if (!isEntryRegistered(oldEntry)) {
  855. throw ERROR_FACTORY.create("not-registered" /* ErrorCode.NOT_REGISTERED */);
  856. }
  857. var oldAuthToken = oldEntry.authToken;
  858. if (!forceRefresh && isAuthTokenValid(oldAuthToken)) {
  859. // There is a valid token in the DB.
  860. return oldEntry;
  861. }
  862. else if (oldAuthToken.requestStatus === 1 /* RequestStatus.IN_PROGRESS */) {
  863. // There already is a token request in progress.
  864. tokenPromise = waitUntilAuthTokenRequest(installations, forceRefresh);
  865. return oldEntry;
  866. }
  867. else {
  868. // No token or token expired.
  869. if (!navigator.onLine) {
  870. throw ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */);
  871. }
  872. var inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry);
  873. tokenPromise = fetchAuthTokenFromServer(installations, inProgressEntry);
  874. return inProgressEntry;
  875. }
  876. })];
  877. case 1:
  878. entry = _b.sent();
  879. if (!tokenPromise) return [3 /*break*/, 3];
  880. return [4 /*yield*/, tokenPromise];
  881. case 2:
  882. _a = _b.sent();
  883. return [3 /*break*/, 4];
  884. case 3:
  885. _a = entry.authToken;
  886. _b.label = 4;
  887. case 4:
  888. authToken = _a;
  889. return [2 /*return*/, authToken];
  890. }
  891. });
  892. });
  893. }
  894. /**
  895. * Call only if FID is registered and Auth Token request is in progress.
  896. *
  897. * Waits until the current pending request finishes. If the request times out,
  898. * tries once in this thread as well.
  899. */
  900. function waitUntilAuthTokenRequest(installations, forceRefresh) {
  901. return __awaiter(this, void 0, void 0, function () {
  902. var entry, authToken;
  903. return __generator(this, function (_a) {
  904. switch (_a.label) {
  905. case 0: return [4 /*yield*/, updateAuthTokenRequest(installations.appConfig)];
  906. case 1:
  907. entry = _a.sent();
  908. _a.label = 2;
  909. case 2:
  910. if (!(entry.authToken.requestStatus === 1 /* RequestStatus.IN_PROGRESS */)) return [3 /*break*/, 5];
  911. // generateAuthToken still in progress.
  912. return [4 /*yield*/, sleep(100)];
  913. case 3:
  914. // generateAuthToken still in progress.
  915. _a.sent();
  916. return [4 /*yield*/, updateAuthTokenRequest(installations.appConfig)];
  917. case 4:
  918. entry = _a.sent();
  919. return [3 /*break*/, 2];
  920. case 5:
  921. authToken = entry.authToken;
  922. if (authToken.requestStatus === 0 /* RequestStatus.NOT_STARTED */) {
  923. // The request timed out or failed in a different call. Try again.
  924. return [2 /*return*/, refreshAuthToken(installations, forceRefresh)];
  925. }
  926. else {
  927. return [2 /*return*/, authToken];
  928. }
  929. }
  930. });
  931. });
  932. }
  933. /**
  934. * Called only if there is a GenerateAuthToken request in progress.
  935. *
  936. * Updates the InstallationEntry in the DB based on the status of the
  937. * GenerateAuthToken request.
  938. *
  939. * Returns the updated InstallationEntry.
  940. */
  941. function updateAuthTokenRequest(appConfig) {
  942. return update(appConfig, function (oldEntry) {
  943. if (!isEntryRegistered(oldEntry)) {
  944. throw ERROR_FACTORY.create("not-registered" /* ErrorCode.NOT_REGISTERED */);
  945. }
  946. var oldAuthToken = oldEntry.authToken;
  947. if (hasAuthTokenRequestTimedOut(oldAuthToken)) {
  948. return __assign(__assign({}, oldEntry), { authToken: { requestStatus: 0 /* RequestStatus.NOT_STARTED */ } });
  949. }
  950. return oldEntry;
  951. });
  952. }
  953. function fetchAuthTokenFromServer(installations, installationEntry) {
  954. return __awaiter(this, void 0, void 0, function () {
  955. var authToken, updatedInstallationEntry, e_1, updatedInstallationEntry;
  956. return __generator(this, function (_a) {
  957. switch (_a.label) {
  958. case 0:
  959. _a.trys.push([0, 3, , 8]);
  960. return [4 /*yield*/, generateAuthTokenRequest(installations, installationEntry)];
  961. case 1:
  962. authToken = _a.sent();
  963. updatedInstallationEntry = __assign(__assign({}, installationEntry), { authToken: authToken });
  964. return [4 /*yield*/, set(installations.appConfig, updatedInstallationEntry)];
  965. case 2:
  966. _a.sent();
  967. return [2 /*return*/, authToken];
  968. case 3:
  969. e_1 = _a.sent();
  970. if (!(isServerError(e_1) &&
  971. (e_1.customData.serverCode === 401 || e_1.customData.serverCode === 404))) return [3 /*break*/, 5];
  972. // Server returned a "FID not found" or a "Invalid authentication" error.
  973. // Generate a new ID next time.
  974. return [4 /*yield*/, remove(installations.appConfig)];
  975. case 4:
  976. // Server returned a "FID not found" or a "Invalid authentication" error.
  977. // Generate a new ID next time.
  978. _a.sent();
  979. return [3 /*break*/, 7];
  980. case 5:
  981. updatedInstallationEntry = __assign(__assign({}, installationEntry), { authToken: { requestStatus: 0 /* RequestStatus.NOT_STARTED */ } });
  982. return [4 /*yield*/, set(installations.appConfig, updatedInstallationEntry)];
  983. case 6:
  984. _a.sent();
  985. _a.label = 7;
  986. case 7: throw e_1;
  987. case 8: return [2 /*return*/];
  988. }
  989. });
  990. });
  991. }
  992. function isEntryRegistered(installationEntry) {
  993. return (installationEntry !== undefined &&
  994. installationEntry.registrationStatus === 2 /* RequestStatus.COMPLETED */);
  995. }
  996. function isAuthTokenValid(authToken) {
  997. return (authToken.requestStatus === 2 /* RequestStatus.COMPLETED */ &&
  998. !isAuthTokenExpired(authToken));
  999. }
  1000. function isAuthTokenExpired(authToken) {
  1001. var now = Date.now();
  1002. return (now < authToken.creationTime ||
  1003. authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER);
  1004. }
  1005. /** Returns an updated InstallationEntry with an InProgressAuthToken. */
  1006. function makeAuthTokenRequestInProgressEntry(oldEntry) {
  1007. var inProgressAuthToken = {
  1008. requestStatus: 1 /* RequestStatus.IN_PROGRESS */,
  1009. requestTime: Date.now()
  1010. };
  1011. return __assign(__assign({}, oldEntry), { authToken: inProgressAuthToken });
  1012. }
  1013. function hasAuthTokenRequestTimedOut(authToken) {
  1014. return (authToken.requestStatus === 1 /* RequestStatus.IN_PROGRESS */ &&
  1015. authToken.requestTime + PENDING_TIMEOUT_MS < Date.now());
  1016. }
  1017. /**
  1018. * @license
  1019. * Copyright 2019 Google LLC
  1020. *
  1021. * Licensed under the Apache License, Version 2.0 (the "License");
  1022. * you may not use this file except in compliance with the License.
  1023. * You may obtain a copy of the License at
  1024. *
  1025. * http://www.apache.org/licenses/LICENSE-2.0
  1026. *
  1027. * Unless required by applicable law or agreed to in writing, software
  1028. * distributed under the License is distributed on an "AS IS" BASIS,
  1029. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1030. * See the License for the specific language governing permissions and
  1031. * limitations under the License.
  1032. */
  1033. /**
  1034. * Creates a Firebase Installation if there isn't one for the app and
  1035. * returns the Installation ID.
  1036. * @param installations - The `Installations` instance.
  1037. *
  1038. * @public
  1039. */
  1040. function getId(installations) {
  1041. return __awaiter(this, void 0, void 0, function () {
  1042. var installationsImpl, _a, installationEntry, registrationPromise;
  1043. return __generator(this, function (_b) {
  1044. switch (_b.label) {
  1045. case 0:
  1046. installationsImpl = installations;
  1047. return [4 /*yield*/, getInstallationEntry(installationsImpl)];
  1048. case 1:
  1049. _a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;
  1050. if (registrationPromise) {
  1051. registrationPromise.catch(console.error);
  1052. }
  1053. else {
  1054. // If the installation is already registered, update the authentication
  1055. // token if needed.
  1056. refreshAuthToken(installationsImpl).catch(console.error);
  1057. }
  1058. return [2 /*return*/, installationEntry.fid];
  1059. }
  1060. });
  1061. });
  1062. }
  1063. /**
  1064. * @license
  1065. * Copyright 2019 Google LLC
  1066. *
  1067. * Licensed under the Apache License, Version 2.0 (the "License");
  1068. * you may not use this file except in compliance with the License.
  1069. * You may obtain a copy of the License at
  1070. *
  1071. * http://www.apache.org/licenses/LICENSE-2.0
  1072. *
  1073. * Unless required by applicable law or agreed to in writing, software
  1074. * distributed under the License is distributed on an "AS IS" BASIS,
  1075. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1076. * See the License for the specific language governing permissions and
  1077. * limitations under the License.
  1078. */
  1079. /**
  1080. * Returns a Firebase Installations auth token, identifying the current
  1081. * Firebase Installation.
  1082. * @param installations - The `Installations` instance.
  1083. * @param forceRefresh - Force refresh regardless of token expiration.
  1084. *
  1085. * @public
  1086. */
  1087. function getToken(installations, forceRefresh) {
  1088. if (forceRefresh === void 0) { forceRefresh = false; }
  1089. return __awaiter(this, void 0, void 0, function () {
  1090. var installationsImpl, authToken;
  1091. return __generator(this, function (_a) {
  1092. switch (_a.label) {
  1093. case 0:
  1094. installationsImpl = installations;
  1095. return [4 /*yield*/, completeInstallationRegistration(installationsImpl)];
  1096. case 1:
  1097. _a.sent();
  1098. return [4 /*yield*/, refreshAuthToken(installationsImpl, forceRefresh)];
  1099. case 2:
  1100. authToken = _a.sent();
  1101. return [2 /*return*/, authToken.token];
  1102. }
  1103. });
  1104. });
  1105. }
  1106. function completeInstallationRegistration(installations) {
  1107. return __awaiter(this, void 0, void 0, function () {
  1108. var registrationPromise;
  1109. return __generator(this, function (_a) {
  1110. switch (_a.label) {
  1111. case 0: return [4 /*yield*/, getInstallationEntry(installations)];
  1112. case 1:
  1113. registrationPromise = (_a.sent()).registrationPromise;
  1114. if (!registrationPromise) return [3 /*break*/, 3];
  1115. // A createInstallation request is in progress. Wait until it finishes.
  1116. return [4 /*yield*/, registrationPromise];
  1117. case 2:
  1118. // A createInstallation request is in progress. Wait until it finishes.
  1119. _a.sent();
  1120. _a.label = 3;
  1121. case 3: return [2 /*return*/];
  1122. }
  1123. });
  1124. });
  1125. }
  1126. /**
  1127. * @license
  1128. * Copyright 2019 Google LLC
  1129. *
  1130. * Licensed under the Apache License, Version 2.0 (the "License");
  1131. * you may not use this file except in compliance with the License.
  1132. * You may obtain a copy of the License at
  1133. *
  1134. * http://www.apache.org/licenses/LICENSE-2.0
  1135. *
  1136. * Unless required by applicable law or agreed to in writing, software
  1137. * distributed under the License is distributed on an "AS IS" BASIS,
  1138. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1139. * See the License for the specific language governing permissions and
  1140. * limitations under the License.
  1141. */
  1142. function deleteInstallationRequest(appConfig, installationEntry) {
  1143. return __awaiter(this, void 0, void 0, function () {
  1144. var endpoint, headers, request, response;
  1145. return __generator(this, function (_a) {
  1146. switch (_a.label) {
  1147. case 0:
  1148. endpoint = getDeleteEndpoint(appConfig, installationEntry);
  1149. headers = getHeadersWithAuth(appConfig, installationEntry);
  1150. request = {
  1151. method: 'DELETE',
  1152. headers: headers
  1153. };
  1154. return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })];
  1155. case 1:
  1156. response = _a.sent();
  1157. if (!!response.ok) return [3 /*break*/, 3];
  1158. return [4 /*yield*/, getErrorFromResponse('Delete Installation', response)];
  1159. case 2: throw _a.sent();
  1160. case 3: return [2 /*return*/];
  1161. }
  1162. });
  1163. });
  1164. }
  1165. function getDeleteEndpoint(appConfig, _a) {
  1166. var fid = _a.fid;
  1167. return "".concat(getInstallationsEndpoint(appConfig), "/").concat(fid);
  1168. }
  1169. /**
  1170. * @license
  1171. * Copyright 2019 Google LLC
  1172. *
  1173. * Licensed under the Apache License, Version 2.0 (the "License");
  1174. * you may not use this file except in compliance with the License.
  1175. * You may obtain a copy of the License at
  1176. *
  1177. * http://www.apache.org/licenses/LICENSE-2.0
  1178. *
  1179. * Unless required by applicable law or agreed to in writing, software
  1180. * distributed under the License is distributed on an "AS IS" BASIS,
  1181. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1182. * See the License for the specific language governing permissions and
  1183. * limitations under the License.
  1184. */
  1185. /**
  1186. * Deletes the Firebase Installation and all associated data.
  1187. * @param installations - The `Installations` instance.
  1188. *
  1189. * @public
  1190. */
  1191. function deleteInstallations(installations) {
  1192. return __awaiter(this, void 0, void 0, function () {
  1193. var appConfig, entry;
  1194. return __generator(this, function (_a) {
  1195. switch (_a.label) {
  1196. case 0:
  1197. appConfig = installations.appConfig;
  1198. return [4 /*yield*/, update(appConfig, function (oldEntry) {
  1199. if (oldEntry && oldEntry.registrationStatus === 0 /* RequestStatus.NOT_STARTED */) {
  1200. // Delete the unregistered entry without sending a deleteInstallation request.
  1201. return undefined;
  1202. }
  1203. return oldEntry;
  1204. })];
  1205. case 1:
  1206. entry = _a.sent();
  1207. if (!entry) return [3 /*break*/, 6];
  1208. if (!(entry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */)) return [3 /*break*/, 2];
  1209. // Can't delete while trying to register.
  1210. throw ERROR_FACTORY.create("delete-pending-registration" /* ErrorCode.DELETE_PENDING_REGISTRATION */);
  1211. case 2:
  1212. if (!(entry.registrationStatus === 2 /* RequestStatus.COMPLETED */)) return [3 /*break*/, 6];
  1213. if (!!navigator.onLine) return [3 /*break*/, 3];
  1214. throw ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */);
  1215. case 3: return [4 /*yield*/, deleteInstallationRequest(appConfig, entry)];
  1216. case 4:
  1217. _a.sent();
  1218. return [4 /*yield*/, remove(appConfig)];
  1219. case 5:
  1220. _a.sent();
  1221. _a.label = 6;
  1222. case 6: return [2 /*return*/];
  1223. }
  1224. });
  1225. });
  1226. }
  1227. /**
  1228. * @license
  1229. * Copyright 2019 Google LLC
  1230. *
  1231. * Licensed under the Apache License, Version 2.0 (the "License");
  1232. * you may not use this file except in compliance with the License.
  1233. * You may obtain a copy of the License at
  1234. *
  1235. * http://www.apache.org/licenses/LICENSE-2.0
  1236. *
  1237. * Unless required by applicable law or agreed to in writing, software
  1238. * distributed under the License is distributed on an "AS IS" BASIS,
  1239. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1240. * See the License for the specific language governing permissions and
  1241. * limitations under the License.
  1242. */
  1243. /**
  1244. * Sets a new callback that will get called when Installation ID changes.
  1245. * Returns an unsubscribe function that will remove the callback when called.
  1246. * @param installations - The `Installations` instance.
  1247. * @param callback - The callback function that is invoked when FID changes.
  1248. * @returns A function that can be called to unsubscribe.
  1249. *
  1250. * @public
  1251. */
  1252. function onIdChange(installations, callback) {
  1253. var appConfig = installations.appConfig;
  1254. addCallback(appConfig, callback);
  1255. return function () {
  1256. removeCallback(appConfig, callback);
  1257. };
  1258. }
  1259. /**
  1260. * @license
  1261. * Copyright 2020 Google LLC
  1262. *
  1263. * Licensed under the Apache License, Version 2.0 (the "License");
  1264. * you may not use this file except in compliance with the License.
  1265. * You may obtain a copy of the License at
  1266. *
  1267. * http://www.apache.org/licenses/LICENSE-2.0
  1268. *
  1269. * Unless required by applicable law or agreed to in writing, software
  1270. * distributed under the License is distributed on an "AS IS" BASIS,
  1271. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1272. * See the License for the specific language governing permissions and
  1273. * limitations under the License.
  1274. */
  1275. /**
  1276. * Returns an instance of {@link Installations} associated with the given
  1277. * {@link @firebase/app#FirebaseApp} instance.
  1278. * @param app - The {@link @firebase/app#FirebaseApp} instance.
  1279. *
  1280. * @public
  1281. */
  1282. function getInstallations(app) {
  1283. if (app === void 0) { app = getApp(); }
  1284. var installationsImpl = _getProvider(app, 'installations').getImmediate();
  1285. return installationsImpl;
  1286. }
  1287. /**
  1288. * @license
  1289. * Copyright 2019 Google LLC
  1290. *
  1291. * Licensed under the Apache License, Version 2.0 (the "License");
  1292. * you may not use this file except in compliance with the License.
  1293. * You may obtain a copy of the License at
  1294. *
  1295. * http://www.apache.org/licenses/LICENSE-2.0
  1296. *
  1297. * Unless required by applicable law or agreed to in writing, software
  1298. * distributed under the License is distributed on an "AS IS" BASIS,
  1299. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1300. * See the License for the specific language governing permissions and
  1301. * limitations under the License.
  1302. */
  1303. function extractAppConfig(app) {
  1304. var e_1, _a;
  1305. if (!app || !app.options) {
  1306. throw getMissingValueError('App Configuration');
  1307. }
  1308. if (!app.name) {
  1309. throw getMissingValueError('App Name');
  1310. }
  1311. // Required app config keys
  1312. var configKeys = [
  1313. 'projectId',
  1314. 'apiKey',
  1315. 'appId'
  1316. ];
  1317. try {
  1318. for (var configKeys_1 = __values(configKeys), configKeys_1_1 = configKeys_1.next(); !configKeys_1_1.done; configKeys_1_1 = configKeys_1.next()) {
  1319. var keyName = configKeys_1_1.value;
  1320. if (!app.options[keyName]) {
  1321. throw getMissingValueError(keyName);
  1322. }
  1323. }
  1324. }
  1325. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  1326. finally {
  1327. try {
  1328. if (configKeys_1_1 && !configKeys_1_1.done && (_a = configKeys_1.return)) _a.call(configKeys_1);
  1329. }
  1330. finally { if (e_1) throw e_1.error; }
  1331. }
  1332. return {
  1333. appName: app.name,
  1334. projectId: app.options.projectId,
  1335. apiKey: app.options.apiKey,
  1336. appId: app.options.appId
  1337. };
  1338. }
  1339. function getMissingValueError(valueName) {
  1340. return ERROR_FACTORY.create("missing-app-config-values" /* ErrorCode.MISSING_APP_CONFIG_VALUES */, {
  1341. valueName: valueName
  1342. });
  1343. }
  1344. /**
  1345. * @license
  1346. * Copyright 2020 Google LLC
  1347. *
  1348. * Licensed under the Apache License, Version 2.0 (the "License");
  1349. * you may not use this file except in compliance with the License.
  1350. * You may obtain a copy of the License at
  1351. *
  1352. * http://www.apache.org/licenses/LICENSE-2.0
  1353. *
  1354. * Unless required by applicable law or agreed to in writing, software
  1355. * distributed under the License is distributed on an "AS IS" BASIS,
  1356. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1357. * See the License for the specific language governing permissions and
  1358. * limitations under the License.
  1359. */
  1360. var INSTALLATIONS_NAME = 'installations';
  1361. var INSTALLATIONS_NAME_INTERNAL = 'installations-internal';
  1362. var publicFactory = function (container) {
  1363. var app = container.getProvider('app').getImmediate();
  1364. // Throws if app isn't configured properly.
  1365. var appConfig = extractAppConfig(app);
  1366. var heartbeatServiceProvider = _getProvider(app, 'heartbeat');
  1367. var installationsImpl = {
  1368. app: app,
  1369. appConfig: appConfig,
  1370. heartbeatServiceProvider: heartbeatServiceProvider,
  1371. _delete: function () { return Promise.resolve(); }
  1372. };
  1373. return installationsImpl;
  1374. };
  1375. var internalFactory = function (container) {
  1376. var app = container.getProvider('app').getImmediate();
  1377. // Internal FIS instance relies on public FIS instance.
  1378. var installations = _getProvider(app, INSTALLATIONS_NAME).getImmediate();
  1379. var installationsInternal = {
  1380. getId: function () { return getId(installations); },
  1381. getToken: function (forceRefresh) { return getToken(installations, forceRefresh); }
  1382. };
  1383. return installationsInternal;
  1384. };
  1385. function registerInstallations() {
  1386. _registerComponent(new Component(INSTALLATIONS_NAME, publicFactory, "PUBLIC" /* ComponentType.PUBLIC */));
  1387. _registerComponent(new Component(INSTALLATIONS_NAME_INTERNAL, internalFactory, "PRIVATE" /* ComponentType.PRIVATE */));
  1388. }
  1389. /**
  1390. * Firebase Installations
  1391. *
  1392. * @packageDocumentation
  1393. */
  1394. registerInstallations();
  1395. registerVersion(name, version);
  1396. // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
  1397. registerVersion(name, version, 'esm5');
  1398. export { deleteInstallations, getId, getInstallations, getToken, onIdChange };
  1399. //# sourceMappingURL=index.esm.js.map