From a5b90dafe570f0812d6edf1077372ec2fd650e68 Mon Sep 17 00:00:00 2001 From: jonathanedey Date: Mon, 1 Jun 2026 11:42:49 -0400 Subject: [PATCH 1/2] change(instance-id): Remove deprecated Instance ID service --- entrypoints.json | 4 - etc/firebase-admin.api.md | 11 - etc/firebase-admin.instance-id.api.md | 40 ---- package.json | 8 - src/app/firebase-namespace.ts | 19 +- src/firebase-namespace-api.ts | 6 - src/instance-id/error.ts | 69 ------ src/instance-id/index.ts | 77 ------- src/instance-id/instance-id-namespace.ts | 40 ---- src/instance-id/instance-id.ts | 87 -------- test/integration/instance-id.spec.ts | 31 --- .../integration/postcheck/esm/example.test.js | 6 - .../typescript/example-modular.test.ts | 6 - test/unit/app/firebase-app.spec.ts | 29 +-- test/unit/app/firebase-namespace.spec.ts | 44 +--- test/unit/index.spec.ts | 4 - test/unit/instance-id/index.spec.ts | 75 ------- test/unit/instance-id/instance-id.spec.ts | 199 ------------------ 18 files changed, 3 insertions(+), 752 deletions(-) delete mode 100644 etc/firebase-admin.instance-id.api.md delete mode 100644 src/instance-id/error.ts delete mode 100644 src/instance-id/index.ts delete mode 100644 src/instance-id/instance-id-namespace.ts delete mode 100644 src/instance-id/instance-id.ts delete mode 100644 test/integration/instance-id.spec.ts delete mode 100644 test/unit/instance-id/index.spec.ts delete mode 100644 test/unit/instance-id/instance-id.spec.ts diff --git a/entrypoints.json b/entrypoints.json index 27906c2fa8..e98cc09f6e 100644 --- a/entrypoints.json +++ b/entrypoints.json @@ -44,10 +44,6 @@ "typings": "./lib/installations/index.d.ts", "dist": "./lib/installations/index.js" }, - "firebase-admin/instance-id": { - "typings": "./lib/instance-id/index.d.ts", - "dist": "./lib/instance-id/index.js" - }, "firebase-admin/messaging": { "typings": "./lib/messaging/index.d.ts", "dist": "./lib/messaging/index.js" diff --git a/etc/firebase-admin.api.md b/etc/firebase-admin.api.md index 3c2ace43c1..3435f6d403 100644 --- a/etc/firebase-admin.api.md +++ b/etc/firebase-admin.api.md @@ -28,8 +28,6 @@ export namespace app { firestore(): firestore.Firestore; // (undocumented) installations(): installations.Installations; - // @deprecated (undocumented) - instanceId(): instanceId.InstanceId; // (undocumented) machineLearning(): machineLearning.MachineLearning; // (undocumented) @@ -336,15 +334,6 @@ export namespace installations { export type Installations = Installations; } -// @public -export function instanceId(app?: App): instanceId.InstanceId; - -// @public (undocumented) -export namespace instanceId { - // Warning: (ae-forgotten-export) The symbol "InstanceId" needs to be exported by the entry point default-namespace.d.ts - export type InstanceId = InstanceId; -} - // @public export function machineLearning(app?: App): machineLearning.MachineLearning; diff --git a/etc/firebase-admin.instance-id.api.md b/etc/firebase-admin.instance-id.api.md deleted file mode 100644 index 20d748a49c..0000000000 --- a/etc/firebase-admin.instance-id.api.md +++ /dev/null @@ -1,40 +0,0 @@ -## API Report File for "firebase-admin.instance-id" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts - -import { Agent } from 'http'; - -// Warning: (ae-forgotten-export) The symbol "FirebaseError" needs to be exported by the entry point index.d.ts -// -// @public -export class FirebaseInstanceIdError extends FirebaseError { - // Warning: (ae-forgotten-export) The symbol "ErrorInfo" needs to be exported by the entry point index.d.ts - constructor(info: ErrorInfo, message?: string); -} - -// Warning: (ae-forgotten-export) The symbol "App" needs to be exported by the entry point index.d.ts -// -// @public @deprecated -export function getInstanceId(app?: App): InstanceId; - -// @public @deprecated -export class InstanceId { - get app(): App; - deleteInstanceId(instanceId: string): Promise; -} - -// @public -export const InstanceIdErrorCode: { - readonly INVALID_ARGUMENT: "invalid-argument"; - readonly INVALID_PROJECT_ID: "invalid-project-id"; - readonly INVALID_INSTALLATION_ID: "invalid-installation-id"; - readonly API_ERROR: "api-error"; - readonly INVALID_INSTANCE_ID: "invalid-instance-id"; -}; - -// @public -export type InstanceIdErrorCode = typeof InstanceIdErrorCode[keyof typeof InstanceIdErrorCode]; - -``` diff --git a/package.json b/package.json index 0044d6c3d7..666e456959 100644 --- a/package.json +++ b/package.json @@ -97,9 +97,6 @@ "installations": [ "lib/installations" ], - "instance-id": [ - "lib/instance-id" - ], "machine-learning": [ "lib/machine-learning" ], @@ -177,11 +174,6 @@ "require": "./lib/installations/index.js", "import": "./lib/esm/installations/index.js" }, - "./instance-id": { - "types": "./lib/instance-id/index.d.ts", - "require": "./lib/instance-id/index.js", - "import": "./lib/esm/instance-id/index.js" - }, "./machine-learning": { "types": "./lib/machine-learning/index.d.ts", "require": "./lib/machine-learning/index.js", diff --git a/src/app/firebase-namespace.ts b/src/app/firebase-namespace.ts index 80daf6867c..f5725bee2b 100644 --- a/src/app/firebase-namespace.ts +++ b/src/app/firebase-namespace.ts @@ -19,7 +19,7 @@ import { App as AppCore } from './core'; import { AppStore, defaultAppStore } from './lifecycle'; import { app, appCheck, auth, messaging, machineLearning, storage, firestore, database, - instanceId, installations, projectManagement, securityRules , remoteConfig, AppOptions, + installations, projectManagement, securityRules , remoteConfig, AppOptions, } from '../firebase-namespace-api'; import { cert, refreshToken, applicationDefault } from './credential-factory'; import { getSdkVersion } from '../utils/index'; @@ -30,7 +30,6 @@ import Auth = auth.Auth; import Database = database.Database; import Firestore = firestore.Firestore; import Installations = installations.Installations; -import InstanceId = instanceId.InstanceId; import MachineLearning = machineLearning.MachineLearning; import Messaging = messaging.Messaging; import ProjectManagement = projectManagement.ProjectManagement; @@ -217,18 +216,6 @@ export class FirebaseNamespace { return Object.assign(fn, { Installations: installations }); } - /** - * Gets the `InstanceId` service namespace. The returned namespace can be used to get the - * `Instance` service for the default app or an explicitly specified app. - */ - get instanceId(): FirebaseServiceNamespace { - const fn: FirebaseServiceNamespace = (app?: App) => { - return this.ensureApp(app).instanceId(); - }; - const instanceId = require('../instance-id/instance-id').InstanceId; - return Object.assign(fn, { InstanceId: instanceId }); - } - /** * Gets the `ProjectManagement` service namespace. The returned namespace can be used to get the * `ProjectManagement` service for the default app or an explicitly specified app. @@ -365,10 +352,6 @@ function extendApp(app: AppCore): App { return fn(app); }; - result.instanceId = () => { - const fn = require('../instance-id/index').getInstanceId; - return fn(app); - } result.installations = () => { const fn = require('../installations/index').getInstallations; diff --git a/src/firebase-namespace-api.ts b/src/firebase-namespace-api.ts index 0d908f4915..38459d0009 100644 --- a/src/firebase-namespace-api.ts +++ b/src/firebase-namespace-api.ts @@ -18,7 +18,6 @@ import { appCheck } from './app-check/app-check-namespace'; import { auth } from './auth/auth-namespace'; import { database } from './database/database-namespace'; import { firestore } from './firestore/firestore-namespace'; -import { instanceId } from './instance-id/instance-id-namespace'; import { installations } from './installations/installations-namespace'; import { machineLearning } from './machine-learning/machine-learning-namespace'; import { messaging } from './messaging/messaging-namespace'; @@ -46,10 +45,6 @@ export namespace app { database(url?: string): database.Database; firestore(): firestore.Firestore; installations(): installations.Installations; - /** - * @deprecated Use {@link firebase-admin.installations#Installations} instead. - */ - instanceId(): instanceId.InstanceId; machineLearning(): machineLearning.MachineLearning; messaging(): messaging.Messaging; projectManagement(): projectManagement.ProjectManagement; @@ -83,7 +78,6 @@ export { appCheck } from './app-check/app-check-namespace'; export { auth } from './auth/auth-namespace'; export { database } from './database/database-namespace'; export { firestore } from './firestore/firestore-namespace'; -export { instanceId } from './instance-id/instance-id-namespace'; export { installations } from './installations/installations-namespace'; export { machineLearning } from './machine-learning/machine-learning-namespace'; export { messaging } from './messaging/messaging-namespace'; diff --git a/src/instance-id/error.ts b/src/instance-id/error.ts deleted file mode 100644 index 6774296971..0000000000 --- a/src/instance-id/error.ts +++ /dev/null @@ -1,69 +0,0 @@ -/*! - * Copyright 2026 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 { FirebaseError, ErrorInfo } from '../utils/error'; -import { installationsClientErrorCode } from '../installations/error'; - -/** - * The constant mapping for valid Instance ID client error codes. - */ -export const InstanceIdErrorCode = { - INVALID_ARGUMENT: 'invalid-argument', - INVALID_PROJECT_ID: 'invalid-project-id', - INVALID_INSTALLATION_ID: 'invalid-installation-id', - API_ERROR: 'api-error', - INVALID_INSTANCE_ID: 'invalid-instance-id', -} as const; - -/** - * The type definition for valid Instance ID client error codes. - */ -export type InstanceIdErrorCode = typeof InstanceIdErrorCode[keyof typeof InstanceIdErrorCode]; - -/** - * Internal Instance ID client error code mapping used to construct ErrorInfo. - */ -export const instanceIdClientErrorCode: { readonly [K in keyof typeof InstanceIdErrorCode]: ErrorInfo } = { - ...installationsClientErrorCode, - INVALID_INSTANCE_ID: { - code: InstanceIdErrorCode.INVALID_INSTANCE_ID, - message: 'Invalid instance ID provided.', - }, -}; - -/** - * Firebase Instance ID error code structure. This extends `FirebaseError`. - */ -export class FirebaseInstanceIdError extends FirebaseError { - /** @internal */ - protected readonly codePrefix = 'instance-id'; - - /** - * - * @param info - The error code info. - * @param message - The error message. This will override the default - * message if provided. - */ - constructor(info: ErrorInfo, message?: string) { - // Override default message if custom message provided. - super({ - code: `instance-id/${info.code}`, - message: message || info.message, - httpResponse: info.httpResponse, - cause: info.cause, - }); - } -} diff --git a/src/instance-id/index.ts b/src/instance-id/index.ts deleted file mode 100644 index a774c0a75b..0000000000 --- a/src/instance-id/index.ts +++ /dev/null @@ -1,77 +0,0 @@ -/*! - * Copyright 2020 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. - */ - -/** - * Firebase Instance ID service. - * - * @packageDocumentation - */ - -import { App, getApp } from '../app/index'; -import { InstanceId } from './instance-id'; -import { FirebaseApp } from '../app/firebase-app'; - -export { InstanceId }; - -/** - * Gets the {@link InstanceId} service for the default app or a given app. - * - * This API is deprecated. Developers are advised to use the - * {@link firebase-admin.installations#getInstallations} - * API to delete their instance IDs and Firebase installation IDs. - * - * `getInstanceId()` can be called with no arguments to access the default - * app's `InstanceId` service or as `getInstanceId(app)` to access the - * `InstanceId` service associated with a specific app. - * - * @example - * ```javascript - * // Get the Instance ID service for the default app - * const defaultInstanceId = getInstanceId(); - * ``` - * - * @example - * ```javascript - * // Get the Instance ID service for a given app - * const otherInstanceId = getInstanceId(otherApp); - *``` - * - * This API is deprecated. Developers are advised to use the `admin.installations()` - * API to delete their instance IDs and Firebase installation IDs. - * - * @param app - Optional app whose `InstanceId` service to - * return. If not provided, the default `InstanceId` service will be - * returned. - * - * @returns The default `InstanceId` service if - * no app is provided or the `InstanceId` service associated with the - * provided app. - * - * @deprecated Use {@link firebase-admin.installations#getInstallations} instead. - */ -export function getInstanceId(app?: App): InstanceId { - if (typeof app === 'undefined') { - app = getApp(); - } - - const firebaseApp: FirebaseApp = app as FirebaseApp; - return firebaseApp.getOrInitService('instanceId', (app) => new InstanceId(app)); -} - -export { - FirebaseInstanceIdError, - InstanceIdErrorCode, -} from './error'; diff --git a/src/instance-id/instance-id-namespace.ts b/src/instance-id/instance-id-namespace.ts deleted file mode 100644 index 285828e472..0000000000 --- a/src/instance-id/instance-id-namespace.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { App } from '../app/index'; -import { InstanceId as TInstanceId } from './instance-id'; - -/** - * Gets the {@link firebase-admin.instance-id#InstanceId} service for the - * default app or a given app. - * - * `admin.instanceId()` can be called with no arguments to access the default - * app's `InstanceId` service or as `admin.instanceId(app)` to access the - * `InstanceId` service associated with a specific app. - * - * @example - * ```javascript - * // Get the Instance ID service for the default app - * var defaultInstanceId = admin.instanceId(); - * ``` - * - * @example - * ```javascript - * // Get the Instance ID service for a given app - * var otherInstanceId = admin.instanceId(otherApp); - *``` - * - * @param app - Optional app whose `InstanceId` service to - * return. If not provided, the default `InstanceId` service will be - * returned. - * - * @returns The default `InstanceId` service if - * no app is provided or the `InstanceId` service associated with the - * provided app. - */ -export declare function instanceId(app?: App): instanceId.InstanceId; - -/* eslint-disable @typescript-eslint/no-namespace */ -export namespace instanceId { - /** - * Type alias to {@link firebase-admin.instance-id#InstanceId}. - */ - export type InstanceId = TInstanceId; -} diff --git a/src/instance-id/instance-id.ts b/src/instance-id/instance-id.ts deleted file mode 100644 index 4564cd56ed..0000000000 --- a/src/instance-id/instance-id.ts +++ /dev/null @@ -1,87 +0,0 @@ -/*! - * Copyright 2020 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 { getInstallations } from '../installations'; -import { FirebaseInstallationsError, installationsClientErrorCode } from '../installations/error'; -import { App } from '../app/index'; -import { FirebaseInstanceIdError, instanceIdClientErrorCode } from './error'; -import * as validator from '../utils/validator'; - -/** - * The `InstanceId` service enables deleting the Firebase instance IDs - * associated with Firebase client app instances. - * - * @deprecated Use {@link firebase-admin.installations#Installations} instead. - */ -export class InstanceId { - - private app_: App; - - /** - * @param app - The app for this InstanceId service. - * @constructor - * @internal - */ - constructor(app: App) { - if (!validator.isNonNullObject(app) || !('options' in app)) { - throw new FirebaseInstanceIdError( - instanceIdClientErrorCode.INVALID_ARGUMENT, - 'First argument passed to instanceId() must be a valid Firebase app instance.', - ); - } - - this.app_ = app; - } - - /** - * Deletes the specified instance ID and the associated data from Firebase. - * - * Note that Google Analytics for Firebase uses its own form of Instance ID to - * keep track of analytics data. Therefore deleting a Firebase Instance ID does - * not delete Analytics data. See - * {@link https://firebase.google.com/support/privacy/manage-iids#delete_an_instance_id | - * Delete an Instance ID} - * for more information. - * - * @param instanceId - The instance ID to be deleted. - * - * @returns A promise fulfilled when the instance ID is deleted. - */ - public deleteInstanceId(instanceId: string): Promise { - return getInstallations(this.app).deleteInstallation(instanceId) - .catch((err) => { - if (err instanceof FirebaseInstallationsError) { - let code = err.code.replace('installations/', ''); - if (code === installationsClientErrorCode.INVALID_INSTALLATION_ID.code) { - code = instanceIdClientErrorCode.INVALID_INSTANCE_ID.code; - } - - throw new FirebaseInstanceIdError({ code, message: err.message }); - } - - throw err; - }); - } - - /** - * Returns the app associated with this InstanceId instance. - * - * @returns The app associated with this InstanceId instance. - */ - get app(): App { - return this.app_; - } -} diff --git a/test/integration/instance-id.spec.ts b/test/integration/instance-id.spec.ts deleted file mode 100644 index fe3cccc935..0000000000 --- a/test/integration/instance-id.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -/*! - * Copyright 2018 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 * as chai from 'chai'; -import * as chaiAsPromised from 'chai-as-promised'; -import { getInstanceId } from '../../lib/instance-id/index'; - -chai.should(); -chai.use(chaiAsPromised); - -describe('admin.instanceId', () => { - it('deleteInstanceId() fails when called with fictive-ID0 instance ID', () => { - // instance ids have to conform to /[cdef][A-Za-z0-9_-]{9}[AEIMQUYcgkosw048]/ - return getInstanceId().deleteInstanceId('fictive-ID0') - .should.eventually.be - .rejectedWith('Installation ID "fictive-ID0": Failed to find the installation ID.'); - }); -}); diff --git a/test/integration/postcheck/esm/example.test.js b/test/integration/postcheck/esm/example.test.js index 6ac8540196..01de94d0b4 100644 --- a/test/integration/postcheck/esm/example.test.js +++ b/test/integration/postcheck/esm/example.test.js @@ -23,7 +23,6 @@ import { getAuth, Auth } from 'firebase-admin/auth'; import { getDatabase, getDatabaseWithUrl, ServerValue } from 'firebase-admin/database'; import { getFirestore, DocumentReference, Firestore, FieldValue } from 'firebase-admin/firestore'; import { getFunctions } from 'firebase-admin/functions'; -import { getInstanceId, InstanceId } from 'firebase-admin/instance-id'; import { getMachineLearning, MachineLearning } from 'firebase-admin/machine-learning'; import { getMessaging, Messaging } from 'firebase-admin/messaging'; import { getProjectManagement, ProjectManagement } from 'firebase-admin/project-management'; @@ -117,11 +116,6 @@ describe('ESM entry points', () => { expect(typeof fn.taskQueue).to.equal('function'); }); - it('Should return an InstanceId client', () => { - const client = getInstanceId(app); - expect(client).to.be.instanceOf(InstanceId); - }); - it('Should return a MachineLearning client', () => { const client = getMachineLearning(app); expect(client).to.be.instanceOf(MachineLearning); diff --git a/test/integration/postcheck/typescript/example-modular.test.ts b/test/integration/postcheck/typescript/example-modular.test.ts index 76e10a9c33..ee3b37303c 100644 --- a/test/integration/postcheck/typescript/example-modular.test.ts +++ b/test/integration/postcheck/typescript/example-modular.test.ts @@ -23,7 +23,6 @@ import { getAuth, Auth } from 'firebase-admin/auth'; import { getDatabase, getDatabaseWithUrl, Database, ServerValue } from 'firebase-admin/database'; import { getFirestore, DocumentReference, Firestore, FieldValue } from 'firebase-admin/firestore'; import { getFunctions, Functions } from 'firebase-admin/functions'; -import { getInstanceId, InstanceId } from 'firebase-admin/instance-id'; import { getMachineLearning, MachineLearning } from 'firebase-admin/machine-learning'; import { getMessaging, Messaging } from 'firebase-admin/messaging'; import { getProjectManagement, ProjectManagement } from 'firebase-admin/project-management'; @@ -121,11 +120,6 @@ describe('Modular API', () => { expect(typeof fn.taskQueue).to.equal('function'); }); - it('Should return an InstanceId client', () => { - const client = getInstanceId(app); - expect(client).to.be.instanceOf(InstanceId); - }); - it('Should return a MachineLearning client', () => { const client = getMachineLearning(app); expect(client).to.be.instanceOf(MachineLearning); diff --git a/test/unit/app/firebase-app.spec.ts b/test/unit/app/firebase-app.spec.ts index ce2b07cdbc..77af41e325 100644 --- a/test/unit/app/firebase-app.spec.ts +++ b/test/unit/app/firebase-app.spec.ts @@ -33,7 +33,7 @@ import { FirebaseNamespace } from '../../../src/app/firebase-namespace'; import { AppStore, FIREBASE_CONFIG_VAR } from '../../../src/app/lifecycle'; import { auth, messaging, machineLearning, storage, firestore, database, - instanceId, installations, projectManagement, securityRules, remoteConfig, appCheck, + installations, projectManagement, securityRules, remoteConfig, appCheck, } from '../../../src/firebase-namespace-api'; import { FirebaseAppError, AppErrorCode } from '../../../src/app/error'; @@ -44,7 +44,6 @@ import MachineLearning = machineLearning.MachineLearning; import Storage = storage.Storage; import Firestore = firestore.Firestore; import Installations = installations.Installations; -import InstanceId = instanceId.InstanceId; import ProjectManagement = projectManagement.ProjectManagement; import SecurityRules = securityRules.SecurityRules; import RemoteConfig = remoteConfig.RemoteConfig; @@ -612,32 +611,6 @@ describe('FirebaseApp', () => { }); }); - describe('instanceId()', () => { - it('should throw if the app has already been deleted', () => { - const app = firebaseNamespace.initializeApp(mocks.appOptions, mocks.appName); - - return app.delete().then(() => { - expect(() => { - return app.instanceId(); - }).to.throw(`Firebase app named "${mocks.appName}" has already been deleted.`); - }); - }); - - it('should return the InstanceId client', () => { - const app = firebaseNamespace.initializeApp(mocks.appOptions, mocks.appName); - - const iid: InstanceId = app.instanceId(); - expect(iid).not.be.null; - }); - - it('should return a cached version of InstanceId on subsequent calls', () => { - const app = firebaseNamespace.initializeApp(mocks.appOptions, mocks.appName); - const service1: InstanceId = app.instanceId(); - const service2: InstanceId = app.instanceId(); - expect(service1).to.equal(service2); - }); - }); - describe('projectManagement()', () => { it('should throw if the app has already been deleted', () => { const app = firebaseNamespace.initializeApp(mocks.appOptions, mocks.appName); diff --git a/test/unit/app/firebase-namespace.spec.ts b/test/unit/app/firebase-namespace.spec.ts index 694c6f5ffe..bf76da7d90 100644 --- a/test/unit/app/firebase-namespace.spec.ts +++ b/test/unit/app/firebase-namespace.spec.ts @@ -50,11 +50,10 @@ import { getSdkVersion } from '../../../src/utils/index'; import { app, auth, messaging, machineLearning, storage, firestore, database, - instanceId, installations, projectManagement, securityRules, remoteConfig, appCheck, + installations, projectManagement, securityRules, remoteConfig, appCheck, } from '../../../src/firebase-namespace-api'; import { AppCheck as AppCheckImpl } from '../../../src/app-check/app-check'; import { Auth as AuthImpl } from '../../../src/auth/auth'; -import { InstanceId as InstanceIdImpl } from '../../../src/instance-id/instance-id'; import { Installations as InstallationsImpl } from '../../../src/installations/installations'; import { MachineLearning as MachineLearningImpl } from '../../../src/machine-learning/machine-learning'; import { Messaging as MessagingImpl } from '../../../src/messaging/messaging'; @@ -71,7 +70,6 @@ import Auth = auth.Auth; import Database = database.Database; import Firestore = firestore.Firestore; import Installations = installations.Installations; -import InstanceId = instanceId.InstanceId; import MachineLearning = machineLearning.MachineLearning; import Messaging = messaging.Messaging; import ProjectManagement = projectManagement.ProjectManagement; @@ -659,46 +657,6 @@ describe('FirebaseNamespace', () => { }); }); - describe('#instanceId()', () => { - it('should throw when called before initializing an app', () => { - expect(() => { - firebaseNamespace.instanceId(); - }).to.throw(DEFAULT_APP_NOT_FOUND); - }); - - it('should throw when default app is not initialized', () => { - firebaseNamespace.initializeApp(mocks.appOptions, 'testApp'); - expect(() => { - firebaseNamespace.instanceId(); - }).to.throw(DEFAULT_APP_NOT_FOUND); - }); - - it('should return a valid namespace when the default app is initialized', () => { - const app: App = firebaseNamespace.initializeApp(mocks.appOptions); - const iid: InstanceId = firebaseNamespace.instanceId(); - expect(iid).to.not.be.null; - expect(iid.app).to.be.deep.equal(app); - }); - - it('should return a valid namespace when the named app is initialized', () => { - const app: App = firebaseNamespace.initializeApp(mocks.appOptions, 'testApp'); - const iid: InstanceId = firebaseNamespace.instanceId(app); - expect(iid).to.not.be.null; - expect(iid.app).to.be.deep.equal(app); - }); - - it('should return a reference to InstanceId type', () => { - expect(firebaseNamespace.instanceId.InstanceId).to.be.deep.equal(InstanceIdImpl); - }); - - it('should return a cached version of InstanceId on subsequent calls', () => { - firebaseNamespace.initializeApp(mocks.appOptions); - const service1: InstanceId = firebaseNamespace.instanceId(); - const service2: InstanceId = firebaseNamespace.instanceId(); - expect(service1).to.equal(service2); - }); - }); - describe('#projectManagement()', () => { it('should throw when called before initializing an app', () => { expect(() => { diff --git a/test/unit/index.spec.ts b/test/unit/index.spec.ts index 9f2fecc1a1..889ce33eae 100644 --- a/test/unit/index.spec.ts +++ b/test/unit/index.spec.ts @@ -76,10 +76,6 @@ import './installations/installations-request-handler.spec'; import './installations/installations.spec'; import './installations/installations-request-handler.spec'; -// InstanceId -import './instance-id/index.spec'; -import './instance-id/instance-id.spec'; - // ProjectManagement import './project-management/index.spec'; import './project-management/project-management.spec'; diff --git a/test/unit/instance-id/index.spec.ts b/test/unit/instance-id/index.spec.ts deleted file mode 100644 index a33da021c7..0000000000 --- a/test/unit/instance-id/index.spec.ts +++ /dev/null @@ -1,75 +0,0 @@ -/*! - * @license - * Copyright 2021 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. - */ - -'use strict'; - -import * as chai from 'chai'; -import * as sinonChai from 'sinon-chai'; -import * as chaiAsPromised from 'chai-as-promised'; - -import * as mocks from '../../resources/mocks'; -import { App } from '../../../src/app/index'; -import { getInstanceId, InstanceId } from '../../../src/instance-id/index'; - -chai.should(); -chai.use(sinonChai); -chai.use(chaiAsPromised); - -const expect = chai.expect; - -describe('InstanceId', () => { - let mockApp: App; - let mockCredentialApp: App; - - const noProjectIdError = 'Failed to determine project ID for Installations. Initialize the SDK ' - + 'with service account credentials or set project ID as an app option. Alternatively set the ' - + 'GOOGLE_CLOUD_PROJECT environment variable.'; - - beforeEach(() => { - mockApp = mocks.app(); - mockCredentialApp = mocks.mockCredentialApp(); - }); - - describe('getInstanceId()', () => { - it('should throw when default app is not available', () => { - expect(() => { - return getInstanceId(); - }).to.throw('The default Firebase app does not exist.'); - }); - - it('should reject given an invalid credential without project ID', () => { - // Project ID not set in the environment. - delete process.env.GOOGLE_CLOUD_PROJECT; - delete process.env.GCLOUD_PROJECT; - const iid = getInstanceId(mockCredentialApp); - return iid.deleteInstanceId('iid') - .should.eventually.rejectedWith(noProjectIdError); - }); - - it('should not throw given a valid app', () => { - expect(() => { - return getInstanceId(mockApp); - }).not.to.throw(); - }); - - it('should return the same instance for a given app instance', () => { - const iid1: InstanceId = getInstanceId(mockApp); - const iid2: InstanceId = getInstanceId(mockApp); - expect(iid1).to.equal(iid2); - }); - }); -}); diff --git a/test/unit/instance-id/instance-id.spec.ts b/test/unit/instance-id/instance-id.spec.ts deleted file mode 100644 index 34eea41101..0000000000 --- a/test/unit/instance-id/instance-id.spec.ts +++ /dev/null @@ -1,199 +0,0 @@ -/*! - * @license - * Copyright 2017 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. - */ - -'use strict'; - -import * as _ from 'lodash'; -import * as chai from 'chai'; -import * as sinon from 'sinon'; -import * as sinonChai from 'sinon-chai'; -import * as chaiAsPromised from 'chai-as-promised'; - -import * as utils from '../utils'; -import * as mocks from '../../resources/mocks'; - -import { InstanceId } from '../../../src/instance-id/index'; -import { Installations } from '../../../src/installations/index'; -import { FirebaseApp } from '../../../src/app/firebase-app'; -import { - FirebaseInstanceIdError, - instanceIdClientErrorCode, -} from '../../../src/instance-id/error'; -import { - FirebaseInstallationsError, - installationsClientErrorCode, -} from '../../../src/installations/error'; - -chai.should(); -chai.use(sinonChai); -chai.use(chaiAsPromised); - -const expect = chai.expect; - -describe('InstanceId', () => { - let iid: InstanceId; - let mockApp: FirebaseApp; - let mockCredentialApp: FirebaseApp; - let getTokenStub: sinon.SinonStub; - - let nullAccessTokenClient: InstanceId; - let malformedAccessTokenClient: InstanceId; - let rejectedPromiseAccessTokenClient: InstanceId; - - let googleCloudProject: string | undefined; - let gcloudProject: string | undefined; - - const noProjectIdError = 'Failed to determine project ID for Installations. Initialize the SDK ' - + 'with service account credentials or set project ID as an app option. Alternatively set the ' - + 'GOOGLE_CLOUD_PROJECT environment variable.'; - - beforeEach(() => { - mockApp = mocks.app(); - getTokenStub = utils.stubGetAccessToken(undefined, mockApp); - mockCredentialApp = mocks.mockCredentialApp(); - iid = new InstanceId(mockApp); - - googleCloudProject = process.env.GOOGLE_CLOUD_PROJECT; - gcloudProject = process.env.GCLOUD_PROJECT; - - nullAccessTokenClient = new InstanceId(mocks.appReturningNullAccessToken()); - malformedAccessTokenClient = new InstanceId(mocks.appReturningMalformedAccessToken()); - rejectedPromiseAccessTokenClient = new InstanceId(mocks.appRejectedWhileFetchingAccessToken()); - }); - - afterEach(() => { - getTokenStub.restore(); - process.env.GOOGLE_CLOUD_PROJECT = googleCloudProject; - process.env.GCLOUD_PROJECT = gcloudProject; - return mockApp.delete(); - }); - - - describe('Constructor', () => { - const invalidApps = [null, NaN, 0, 1, true, false, '', 'a', [], [1, 'a'], {}, { a: 1 }, _.noop]; - invalidApps.forEach((invalidApp) => { - it('should throw given invalid app: ' + JSON.stringify(invalidApp), () => { - expect(() => { - const iidAny: any = InstanceId; - return new iidAny(invalidApp); - }).to.throw('First argument passed to instanceId() must be a valid Firebase app instance.'); - }); - }); - - it('should throw given no app', () => { - expect(() => { - const iidAny: any = InstanceId; - return new iidAny(); - }).to.throw('First argument passed to instanceId() must be a valid Firebase app instance.'); - }); - - it('should reject given an invalid credential without project ID', () => { - // Project ID not set in the environment. - delete process.env.GOOGLE_CLOUD_PROJECT; - delete process.env.GCLOUD_PROJECT; - const instanceId = new InstanceId(mockCredentialApp); - return instanceId.deleteInstanceId('iid') - .should.eventually.rejectedWith(noProjectIdError); - }); - - it('should not throw given a valid app', () => { - expect(() => { - return new InstanceId(mockApp); - }).not.to.throw(); - }); - }); - - describe('app', () => { - it('returns the app from the constructor', () => { - // We expect referential equality here - expect(iid.app).to.equal(mockApp); - }); - - it('is read-only', () => { - expect(() => { - (iid as any).app = mockApp; - }).to.throw('Cannot set property app of # which has only a getter'); - }); - }); - - describe('deleteInstanceId()', () => { - - // Stubs used to simulate underlying api calls. - let stubs: sinon.SinonStub[] = []; - const testInstanceId = 'test-iid'; - - afterEach(() => { - _.forEach(stubs, (stub) => stub.restore()); - stubs = []; - }); - - it('should be rejected given no instance ID', () => { - return (iid as any).deleteInstanceId() - .should.eventually.be.rejected.and.have.property('code', 'instance-id/invalid-instance-id'); - }); - - it('should be rejected given an invalid instance ID', () => { - return iid.deleteInstanceId('') - .should.eventually.be.rejected.and.have.property('code', 'instance-id/invalid-instance-id'); - }); - - it('should be rejected given an app which returns null access tokens', () => { - return nullAccessTokenClient.deleteInstanceId(testInstanceId) - .should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should be rejected given an app which returns invalid access tokens', () => { - return malformedAccessTokenClient.deleteInstanceId(testInstanceId) - .should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should be rejected given an app which fails to generate access tokens', () => { - return rejectedPromiseAccessTokenClient.deleteInstanceId(testInstanceId) - .should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); - }); - - it('should resolve without errors on success', () => { - const stub = sinon.stub(Installations.prototype, 'deleteInstallation') - .resolves(); - stubs.push(stub); - return iid.deleteInstanceId(testInstanceId) - .then(() => { - // Confirm underlying API called with expected parameters. - expect(stub).to.have.been.calledOnce.and.calledWith(testInstanceId); - }); - }); - - it('should throw a FirebaseInstanceIdError error when the backend returns an error', () => { - // Stub deleteInstanceId to throw a backend error. - const originalError = new FirebaseInstallationsError(installationsClientErrorCode.API_ERROR); - const stub = sinon.stub(Installations.prototype, 'deleteInstallation') - .rejects(originalError); - stubs.push(stub); - return iid.deleteInstanceId(testInstanceId) - .then(() => { - throw new Error('Unexpected success'); - }, (error) => { - // Confirm underlying API called with expected parameters. - expect(stub).to.have.been.calledOnce.and.calledWith(testInstanceId); - // Confirm expected error returned. - const expectedError = new FirebaseInstanceIdError(instanceIdClientErrorCode.API_ERROR); - expect(error).to.be.instanceOf(FirebaseInstanceIdError) - expect(error).to.deep.include(expectedError); - }); - }); - }); -}); From 790674601e9ecd430a27db8f0b5f88130f9c1474 Mon Sep 17 00:00:00 2001 From: jonathanedey Date: Mon, 1 Jun 2026 12:35:19 -0400 Subject: [PATCH 2/2] fix: Address formatting and duplicate imports from gemini review --- src/app/firebase-namespace.ts | 3 +-- test/unit/index.spec.ts | 8 -------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/app/firebase-namespace.ts b/src/app/firebase-namespace.ts index f5725bee2b..1580f208af 100644 --- a/src/app/firebase-namespace.ts +++ b/src/app/firebase-namespace.ts @@ -19,7 +19,7 @@ import { App as AppCore } from './core'; import { AppStore, defaultAppStore } from './lifecycle'; import { app, appCheck, auth, messaging, machineLearning, storage, firestore, database, - installations, projectManagement, securityRules , remoteConfig, AppOptions, + installations, projectManagement, securityRules, remoteConfig, AppOptions, } from '../firebase-namespace-api'; import { cert, refreshToken, applicationDefault } from './credential-factory'; import { getSdkVersion } from '../utils/index'; @@ -352,7 +352,6 @@ function extendApp(app: AppCore): App { return fn(app); }; - result.installations = () => { const fn = require('../installations/index').getInstallations; return fn(app); diff --git a/test/unit/index.spec.ts b/test/unit/index.spec.ts index 889ce33eae..15b8fe17e2 100644 --- a/test/unit/index.spec.ts +++ b/test/unit/index.spec.ts @@ -68,14 +68,6 @@ import './firestore/index.spec'; import './installations/installations.spec'; import './installations/installations-request-handler.spec'; -// Installations -import './installations/installations.spec'; -import './installations/installations-request-handler.spec'; - -// Installations -import './installations/installations.spec'; -import './installations/installations-request-handler.spec'; - // ProjectManagement import './project-management/index.spec'; import './project-management/project-management.spec';