From d65013ea144107d05bf49b223a0ad6a3b68db2e0 Mon Sep 17 00:00:00 2001 From: Ritik Taneja Date: Mon, 2 Nov 2026 13:08:10 +0530 Subject: [PATCH 1/4] chore(remote-config): deprecate RemoteConfigFetchResponse and FetchResponseData Remote Config server-side rendering (SSR) hydration of the client SDK has been deprecated; the backend rejects client fetches of server templates, and the JS SDK is deprecating templateId/initialFetchResponse in parallel. - Mark RemoteConfigFetchResponse and FetchResponseData @deprecated (to be removed in the next major release). - Log a one-time console warning when RemoteConfigFetchResponse is constructed. - No changes to getServerTemplate / initServerTemplate / evaluate(). --- etc/firebase-admin.remote-config.api.md | 7 +++--- src/remote-config/remote-config-api.ts | 4 ++++ src/remote-config/remote-config.ts | 23 +++++++++++++++++++ test/unit/remote-config/remote-config.spec.ts | 21 +++++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/etc/firebase-admin.remote-config.api.md b/etc/firebase-admin.remote-config.api.md index dc48662e8c..ffbe404968 100644 --- a/etc/firebase-admin.remote-config.api.md +++ b/etc/firebase-admin.remote-config.api.md @@ -81,7 +81,7 @@ export interface ExplicitParameterValue { value: string; } -// @public +// @public @deprecated export interface FetchResponseData { config?: { [key: string]: string; @@ -236,10 +236,11 @@ export const RemoteConfigErrorCode: { // @public export type RemoteConfigErrorCode = typeof RemoteConfigErrorCode[keyof typeof RemoteConfigErrorCode]; -// @public +// @public @deprecated export class RemoteConfigFetchResponse { + // @deprecated constructor(app: App, serverConfig: ServerConfig, requestEtag?: string); - // (undocumented) + // @deprecated (undocumented) toJSON(): FetchResponseData; } diff --git a/src/remote-config/remote-config-api.ts b/src/remote-config/remote-config-api.ts index 0f2648d797..588bad7523 100644 --- a/src/remote-config/remote-config-api.ts +++ b/src/remote-config/remote-config-api.ts @@ -879,6 +879,10 @@ export interface ServerConfig { /** * JSON-serializable representation of evaluated config values. This can be consumed by * Remote Config web client SDKs. + * + * @deprecated Remote Config server-side rendering (SSR) hydration of the + * client SDK is no longer supported. This type will be removed in the + * next major release. */ export interface FetchResponseData { /** diff --git a/src/remote-config/remote-config.ts b/src/remote-config/remote-config.ts index 7e74fc9381..ba47866fa1 100644 --- a/src/remote-config/remote-config.ts +++ b/src/remote-config/remote-config.ts @@ -704,8 +704,14 @@ class VersionImpl implements Version { const HTTP_NOT_MODIFIED = 304; const HTTP_OK = 200; +let fetchResponseDeprecationWarned = false; + /** * Represents a fetch response that can be used to interact with RC's client SDK. + * + * @deprecated Remote Config server-side rendering (SSR) hydration of the + * client SDK is no longer supported. This class will be removed in the + * next major release. */ export class RemoteConfigFetchResponse { private response: FetchResponseData; @@ -714,8 +720,21 @@ export class RemoteConfigFetchResponse { * @param app - The app for this RemoteConfig service. * @param serverConfig - The server config for which to generate a fetch response. * @param requestEtag - A request eTag with which to compare the current response. + * + * @deprecated Remote Config server-side rendering (SSR) hydration of the + * client SDK is no longer supported. This class will be removed in the + * next major release. */ constructor(app: App, serverConfig: ServerConfig, requestEtag?: string) { + if (!fetchResponseDeprecationWarned) { + fetchResponseDeprecationWarned = true; + console.warn( + 'RemoteConfigFetchResponse is deprecated and will be removed in the next major ' + + 'release. Remote Config server-side rendering (SSR) hydration of the client SDK ' + + 'is no longer supported.' + ); + } + const config: { [key: string]: string } = {}; for (const [param, value] of Object.entries(serverConfig.getAll())) { config[param] = value.asString(); @@ -740,6 +759,10 @@ export class RemoteConfigFetchResponse { /** * @returns JSON representation of the fetch response that can be consumed * by the RC client SDK. + * + * @deprecated Remote Config server-side rendering (SSR) hydration of the + * client SDK is no longer supported. This method will be removed in the + * next major release. */ public toJSON(): FetchResponseData { return this.response; diff --git a/test/unit/remote-config/remote-config.spec.ts b/test/unit/remote-config/remote-config.spec.ts index ffd65f79de..3d25105d35 100644 --- a/test/unit/remote-config/remote-config.spec.ts +++ b/test/unit/remote-config/remote-config.spec.ts @@ -1585,6 +1585,27 @@ describe('RemoteConfig', () => { }); describe('RemoteConfigFetchResponse', () => { + let warnStub: sinon.SinonStub; + + beforeEach(() => { + warnStub = sinon.stub(console, 'warn'); + }); + + afterEach(() => { + warnStub.restore(); + }); + + // This test must run before any other construction of RemoteConfigFetchResponse + // in this process, since the deprecation warning is emitted only once per process. + it('should log a deprecation warning only once', () => { + const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; + const template = remoteConfig.initServerTemplate({ template: templateData }); + new RemoteConfigFetchResponse(mockApp, template.evaluate()); + new RemoteConfigFetchResponse(mockApp, template.evaluate()); + expect(warnStub).to.have.been.calledOnce; + expect(warnStub.firstCall.args[0]).to.include('RemoteConfigFetchResponse is deprecated'); + }); + it('should return a 200 response when supplied with no etag', () => { const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; // Defines remote parameter values. From 4abf33eb1bcd5acc79d8ae6f0a17a3ba92c72073 Mon Sep 17 00:00:00 2001 From: Ritik Taneja Date: Wed, 11 Nov 2026 11:21:42 +0530 Subject: [PATCH 2/4] chore(remote-config): use static class property for deprecation warning flag Moves the one-time warning flag from module scope to a private static property on RemoteConfigFetchResponse and resets it in the test's beforeEach, so the warning test no longer depends on execution order. --- src/remote-config/remote-config.ts | 8 ++++---- test/unit/remote-config/remote-config.spec.ts | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/remote-config/remote-config.ts b/src/remote-config/remote-config.ts index ba47866fa1..aa07a3c8fa 100644 --- a/src/remote-config/remote-config.ts +++ b/src/remote-config/remote-config.ts @@ -704,8 +704,6 @@ class VersionImpl implements Version { const HTTP_NOT_MODIFIED = 304; const HTTP_OK = 200; -let fetchResponseDeprecationWarned = false; - /** * Represents a fetch response that can be used to interact with RC's client SDK. * @@ -714,6 +712,8 @@ let fetchResponseDeprecationWarned = false; * next major release. */ export class RemoteConfigFetchResponse { + private static deprecationWarned = false; + private response: FetchResponseData; /** @@ -726,8 +726,8 @@ export class RemoteConfigFetchResponse { * next major release. */ constructor(app: App, serverConfig: ServerConfig, requestEtag?: string) { - if (!fetchResponseDeprecationWarned) { - fetchResponseDeprecationWarned = true; + if (!RemoteConfigFetchResponse.deprecationWarned) { + RemoteConfigFetchResponse.deprecationWarned = true; console.warn( 'RemoteConfigFetchResponse is deprecated and will be removed in the next major ' + 'release. Remote Config server-side rendering (SSR) hydration of the client SDK ' + diff --git a/test/unit/remote-config/remote-config.spec.ts b/test/unit/remote-config/remote-config.spec.ts index 3d25105d35..b317373447 100644 --- a/test/unit/remote-config/remote-config.spec.ts +++ b/test/unit/remote-config/remote-config.spec.ts @@ -1589,14 +1589,13 @@ describe('RemoteConfig', () => { beforeEach(() => { warnStub = sinon.stub(console, 'warn'); + (RemoteConfigFetchResponse as any).deprecationWarned = false; }); afterEach(() => { warnStub.restore(); }); - // This test must run before any other construction of RemoteConfigFetchResponse - // in this process, since the deprecation warning is emitted only once per process. it('should log a deprecation warning only once', () => { const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; const template = remoteConfig.initServerTemplate({ template: templateData }); From ee4b1a4c60b25854f188d1d64195be4405b26b58 Mon Sep 17 00:00:00 2001 From: Ritik Taneja Date: Fri, 13 Nov 2026 13:18:58 +0530 Subject: [PATCH 3/4] change(rc): drop runtime deprecation warning in favor of JSDoc --- src/remote-config/remote-config.ts | 11 ---------- test/unit/remote-config/remote-config.spec.ts | 20 ------------------- 2 files changed, 31 deletions(-) diff --git a/src/remote-config/remote-config.ts b/src/remote-config/remote-config.ts index aa07a3c8fa..de3bedace8 100644 --- a/src/remote-config/remote-config.ts +++ b/src/remote-config/remote-config.ts @@ -712,8 +712,6 @@ const HTTP_OK = 200; * next major release. */ export class RemoteConfigFetchResponse { - private static deprecationWarned = false; - private response: FetchResponseData; /** @@ -726,15 +724,6 @@ export class RemoteConfigFetchResponse { * next major release. */ constructor(app: App, serverConfig: ServerConfig, requestEtag?: string) { - if (!RemoteConfigFetchResponse.deprecationWarned) { - RemoteConfigFetchResponse.deprecationWarned = true; - console.warn( - 'RemoteConfigFetchResponse is deprecated and will be removed in the next major ' + - 'release. Remote Config server-side rendering (SSR) hydration of the client SDK ' + - 'is no longer supported.' - ); - } - const config: { [key: string]: string } = {}; for (const [param, value] of Object.entries(serverConfig.getAll())) { config[param] = value.asString(); diff --git a/test/unit/remote-config/remote-config.spec.ts b/test/unit/remote-config/remote-config.spec.ts index b317373447..ffd65f79de 100644 --- a/test/unit/remote-config/remote-config.spec.ts +++ b/test/unit/remote-config/remote-config.spec.ts @@ -1585,26 +1585,6 @@ describe('RemoteConfig', () => { }); describe('RemoteConfigFetchResponse', () => { - let warnStub: sinon.SinonStub; - - beforeEach(() => { - warnStub = sinon.stub(console, 'warn'); - (RemoteConfigFetchResponse as any).deprecationWarned = false; - }); - - afterEach(() => { - warnStub.restore(); - }); - - it('should log a deprecation warning only once', () => { - const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; - const template = remoteConfig.initServerTemplate({ template: templateData }); - new RemoteConfigFetchResponse(mockApp, template.evaluate()); - new RemoteConfigFetchResponse(mockApp, template.evaluate()); - expect(warnStub).to.have.been.calledOnce; - expect(warnStub.firstCall.args[0]).to.include('RemoteConfigFetchResponse is deprecated'); - }); - it('should return a 200 response when supplied with no etag', () => { const templateData = deepCopy(SERVER_REMOTE_CONFIG_RESPONSE) as ServerTemplateData; // Defines remote parameter values. From ebf49dab409e1eb553d75bd22f7566090497cdaf Mon Sep 17 00:00:00 2001 From: Ritik Taneja Date: Fri, 13 Nov 2026 13:49:41 +0530 Subject: [PATCH 4/4] change(rc): add summary to RemoteConfigFetchResponse.toJSON docs --- etc/firebase-admin.remote-config.api.md | 2 +- src/remote-config/remote-config.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/etc/firebase-admin.remote-config.api.md b/etc/firebase-admin.remote-config.api.md index ffbe404968..fcd99cb8ed 100644 --- a/etc/firebase-admin.remote-config.api.md +++ b/etc/firebase-admin.remote-config.api.md @@ -240,7 +240,7 @@ export type RemoteConfigErrorCode = typeof RemoteConfigErrorCode[keyof typeof Re export class RemoteConfigFetchResponse { // @deprecated constructor(app: App, serverConfig: ServerConfig, requestEtag?: string); - // @deprecated (undocumented) + // @deprecated toJSON(): FetchResponseData; } diff --git a/src/remote-config/remote-config.ts b/src/remote-config/remote-config.ts index de3bedace8..a78ae5956f 100644 --- a/src/remote-config/remote-config.ts +++ b/src/remote-config/remote-config.ts @@ -745,9 +745,9 @@ export class RemoteConfigFetchResponse { } } - /** - * @returns JSON representation of the fetch response that can be consumed - * by the RC client SDK. + /** + * Returns the JSON representation of this fetch response, which can be + * consumed by the RC client SDK. * * @deprecated Remote Config server-side rendering (SSR) hydration of the * client SDK is no longer supported. This method will be removed in the