UNPKG

quodolores

Version:

Monorepo for the Firebase JavaScript SDK

107 lines (96 loc) 3.62 kB
/** * @license * Copyright 2019 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { DB, deleteDb, openDb } from 'idb'; import { FirebaseInternalDependencies } from '../interfaces/internal-dependencies'; import { TokenDetails } from '../interfaces/token-details'; import { migrateOldDatabase } from '../helpers/migrate-old-database'; // Exported for tests. export const DATABASE_NAME = 'firebase-messaging-database'; const DATABASE_VERSION = 1; const OBJECT_STORE_NAME = 'firebase-messaging-store'; let dbPromise: Promise<DB> | null = null; function getDbPromise(): Promise<DB> { if (!dbPromise) { dbPromise = openDb(DATABASE_NAME, DATABASE_VERSION, upgradeDb => { // We don't use 'break' in this switch statement, the fall-through behavior is what we want, // because if there are multiple versions between the old version and the current version, we // want ALL the migrations that correspond to those versions to run, not only the last one. // eslint-disable-next-line default-case switch (upgradeDb.oldVersion) { case 0: upgradeDb.createObjectStore(OBJECT_STORE_NAME); } }); } return dbPromise; } /** Gets record(s) from the objectStore that match the given key. */ export async function dbGet( firebaseDependencies: FirebaseInternalDependencies ): Promise<TokenDetails | undefined> { const key = getKey(firebaseDependencies); const db = await getDbPromise(); const tokenDetails = await db .transaction(OBJECT_STORE_NAME) .objectStore(OBJECT_STORE_NAME) .get(key); if (tokenDetails) { return tokenDetails; } else { // Check if there is a tokenDetails object in the old DB. const oldTokenDetails = await migrateOldDatabase( firebaseDependencies.appConfig.senderId ); if (oldTokenDetails) { await dbSet(firebaseDependencies, oldTokenDetails); return oldTokenDetails; } } } /** Assigns or overwrites the record for the given key with the given value. */ export async function dbSet( firebaseDependencies: FirebaseInternalDependencies, tokenDetails: TokenDetails ): Promise<TokenDetails> { const key = getKey(firebaseDependencies); const db = await getDbPromise(); const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite'); await tx.objectStore(OBJECT_STORE_NAME).put(tokenDetails, key); await tx.complete; return tokenDetails; } /** Removes record(s) from the objectStore that match the given key. */ export async function dbRemove( firebaseDependencies: FirebaseInternalDependencies ): Promise<void> { const key = getKey(firebaseDependencies); const db = await getDbPromise(); const tx = db.transaction(OBJECT_STORE_NAME, 'readwrite'); await tx.objectStore(OBJECT_STORE_NAME).delete(key); await tx.complete; } /** Deletes the DB. Useful for tests. */ export async function dbDelete(): Promise<void> { if (dbPromise) { (await dbPromise).close(); await deleteDb(DATABASE_NAME); dbPromise = null; } } function getKey({ appConfig }: FirebaseInternalDependencies): string { return appConfig.appId; }