Skip to content

Add deprecation warnings for functions.config() API #8808

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 21, 2025
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
- Added a deprecation warning for functions.config() to stderr on deploy and all functions:config commands. (#8808)
- Added analytics to track runtime config usage in functions deployments (#8870).
- Fixed issue where `__name__` fields with DESCENDING order were incorrectly filtered from index listings, causing duplicate index issues (#7629) and deployment conflicts (#8859). The fix now preserves `__name__` fields with explicit DESCENDING order while filtering out implicit ASCENDING `__name__` fields.
2 changes: 2 additions & 0 deletions src/commands/functions-config-clone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import * as functionsConfig from "../functionsConfig";
import { functionsConfigClone } from "../functionsConfigClone";
import * as utils from "../utils";
import { logFunctionsConfigDeprecationWarning } from "../functions/deprecationWarnings";

export const command = new Command("functions:config:clone")
.description("clone environment config from another project")
Expand All @@ -28,22 +29,22 @@
])
.before(functionsConfig.ensureApi)
.action(async (options) => {
const projectId = needProjectId(options);

Check warning on line 32 in src/commands/functions-config-clone.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe argument of type `any` assigned to a parameter of type `{ projectId?: string | undefined; project?: string | undefined; rc?: RC | undefined; }`
if (!options.from) {

Check warning on line 33 in src/commands/functions-config-clone.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .from on an `any` value
throw new FirebaseError(
`Must specify a source project in ${clc.bold("--from <projectId>")} option.`,
);
} else if (options.from === projectId) {

Check warning on line 37 in src/commands/functions-config-clone.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .from on an `any` value
throw new FirebaseError("From project and destination can't be the same project.");
} else if (options.only && options.except) {

Check warning on line 39 in src/commands/functions-config-clone.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .except on an `any` value

Check warning on line 39 in src/commands/functions-config-clone.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .only on an `any` value
throw new FirebaseError("Cannot use both --only and --except at the same time.");
}

let only: string[] | undefined;
let except: string[] = [];
if (options.only) {

Check warning on line 45 in src/commands/functions-config-clone.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .only on an `any` value
only = options.only.split(",");

Check warning on line 46 in src/commands/functions-config-clone.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe call of an `any` typed value

Check warning on line 46 in src/commands/functions-config-clone.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .only on an `any` value

Check warning on line 46 in src/commands/functions-config-clone.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe assignment of an `any` value
} else if (options.except) {

Check warning on line 47 in src/commands/functions-config-clone.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .except on an `any` value
except = options.except.split(",");
}

Expand All @@ -56,4 +57,5 @@
"firebase deploy --only functions",
)}\n`,
);
logFunctionsConfigDeprecationWarning();
});
2 changes: 2 additions & 0 deletions src/commands/functions-config-get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { logger } from "../logger";
import { needProjectId } from "../projectUtils";
import { requirePermissions } from "../requirePermissions";
import * as functionsConfig from "../functionsConfig";
import { logFunctionsConfigDeprecationWarning } from "../functions/deprecationWarnings";

async function materialize(projectId: string, path?: string): Promise<any> {
if (path === undefined) {
Expand All @@ -31,5 +32,6 @@ export const command = new Command("functions:config:get [path]")
.action(async (path, options) => {
const result = await materialize(needProjectId(options), path);
logger.info(JSON.stringify(result, null, 2));
logFunctionsConfigDeprecationWarning();
return result;
});
2 changes: 2 additions & 0 deletions src/commands/functions-config-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { needProjectId } from "../projectUtils";
import { requirePermissions } from "../requirePermissions";
import * as functionsConfig from "../functionsConfig";
import * as utils from "../utils";
import { logFunctionsConfigDeprecationWarning } from "../functions/deprecationWarnings";

export const command = new Command("functions:config:set [values...]")
.description("set environment config with key=value syntax")
Expand Down Expand Up @@ -49,4 +50,5 @@ export const command = new Command("functions:config:set [values...]")
"firebase deploy --only functions",
)}\n`,
);
logFunctionsConfigDeprecationWarning();
});
2 changes: 2 additions & 0 deletions src/commands/functions-config-unset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as functionsConfig from "../functionsConfig";
import * as runtimeconfig from "../gcp/runtimeconfig";
import * as utils from "../utils";
import { FirebaseError } from "../error";
import { logFunctionsConfigDeprecationWarning } from "../functions/deprecationWarnings";

export const command = new Command("functions:config:unset [keys...]")
.description("unset environment config at the specified path(s)")
Expand Down Expand Up @@ -44,4 +45,5 @@ export const command = new Command("functions:config:unset [keys...]")
"firebase deploy --only functions",
)}\n`,
);
logFunctionsConfigDeprecationWarning();
});
4 changes: 4 additions & 0 deletions src/deploy/functions/prepareFunctionsUpload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import * as functionsConfig from "../../functionsConfig";
import * as utils from "../../utils";
import * as fsAsync from "../../fsAsync";
import * as projectConfig from "../../functions/projectConfig";
import { logFunctionsConfigDeprecationWarning } from "../../functions/deprecationWarnings";

const CONFIG_DEST_FILE = ".runtimeconfig.json";

Expand Down Expand Up @@ -99,6 +100,9 @@ async function packageSource(
name: CONFIG_DEST_FILE,
mode: 420 /* 0o644 */,
});

// Log deprecation warning when runtime config is being packaged
logFunctionsConfigDeprecationWarning();
}
await pipeAsync(archive, fileStream);
} catch (err: any) {
Expand Down
8 changes: 8 additions & 0 deletions src/experiments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ export const ALL_EXPERIMENTS = experiments({
"of how that image was created.",
public: true,
},
dangerouslyAllowFunctionsConfig: {
shortDescription: "Allows the use of deprecated functions.config() API",
fullDescription:
"The functions.config() API is deprecated and will be removed on December 31, 2025. " +
"This experiment allows continued use of the API during the migration period.",
default: true,
public: true,
},

// Emulator experiments
emulatoruisnapshot: {
Expand Down
22 changes: 22 additions & 0 deletions src/functions/deprecationWarnings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { logWarningToStderr } from "../utils";

const FUNCTIONS_CONFIG_DEPRECATION_MESSAGE = `DEPRECATION NOTICE: Action required to deploy after Dec 31, 2025
functions.config() API is deprecated.
Cloud Runtime Configuration API, the Google Cloud service used to store function configuration data, will be shut down on December 31, 2025. As a result, you must migrate away from using functions.config() to continue deploying your functions after December 31, 2025.
What this means for you:
- The Firebase CLI commands for managing this configuration (functions:config:set, get, unset, clone, and export) are deprecated. These commands no longer work after December 31, 2025.
- firebase deploy command will fail for functions that use the legacy functions.config() API after December 31, 2025.
Existing deployments will continue to work with their current configuration.
See your migration options at: https://firebase.google.com/docs/functions/config-env#migrate-to-dotenv`;

/**
* Logs a deprecation warning for functions.config() usage
*/
export function logFunctionsConfigDeprecationWarning(): void {
logWarningToStderr(FUNCTIONS_CONFIG_DEPRECATION_MESSAGE);
}
8 changes: 8 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,14 @@ export function logWarning(
logger[type](clc.yellow(clc.bold(`${WARNING_CHAR} `)), message, data);
}

/**
* Log a warning statement to stderr, regardless of logger configuration.
*/
export function logWarningToStderr(message: string): void {
const prefix = clc.bold(`${WARNING_CHAR} `);
process.stderr.write(clc.yellow(prefix + message) + "\n");
}

/**
* Log an info statement with a gray bullet at the start of the line.
*/
Expand Down
Loading