The Firebase Extensions service is deprecated and will shut down on March 31, 2027. While already-installed extensions will execute indefinitely, key management features will no longer be available after this date. Additional migration guidance and tools will be released in September 2026.
Deprecation overview
Why are we deprecating Firebase Extensions?
Due to upcoming changes and deprecations within our underlying Google Cloud infrastructure, we will be sunsetting the managed Firebase Extensions service.
Will existing deployed extensions stop working after March 31, 2027?
No. Already deployed extensions run directly on standard Google Cloud infrastructure (such as Cloud Functions, Eventarc, Cloud Run, and Cloud Tasks) and will continue to execute indefinitely.
However, after March 31, 2027, you will lose all ability to update, reconfigure, or uninstall these extensions through the Firebase console or CLI. You will also lose the ability to download your existing extension configurations to aid in migrating to a function kit. We strongly recommend migrating or exporting extension configuration by March 31, 2027.
What happens if a user does nothing?
If a user takes no action, their existing deployed functions will continue to run as standard assets. However after March 31, 2027:
- They cannot change configuration parameters or update environment variables.
- They cannot apply bug fixes, security patches, or dependency upgrades.
- They cannot download extension configuration to help identically configure a replacement function kit.
- Most extensions are currently built on the legacy Cloud Functions v1 SDK, which is tied to older Node.js runtimes. Once these legacy runtimes are fully decommissioned by Google Cloud, the functions may stop running or be disabled. See Runtime support.
Is anything replacing Firebase Extensions?
We have added many features to Cloud Functions to make them capable of replacing extensions. Most notably function kits which can be distributed using npm and lets you deploy multiple instances of functions, similar to how you could install extensions multiple times in a single project.
However, it is up to each extension publisher to determine if they want to publish an official function kit replacement on npm. Since extensions are open source, if the publisher doesn't want to make an official replacement, any developer can fork it to make an unofficial replacement with Cloud Functions using our 2nd gen APIs in the Node SDK.
Publishers wishing to make a replacement should follow the instructions in the migration guide for publishers.
Users wanting to take advantage of official replacement packages or create their own replacements can follow the instructions in the migration guide for users.
What should I do as an extension user?
If you're an extension user and no longer use your installed extensions, uninstall them before March 31, 2027.
Post-decommissioning, the "Uninstall" button in the Firebase console and corresponding CLI commands will be removed. You must manually delete all associated Google Cloud resources, including the individual Cloud Functions, Secret Manager secrets, Cloud Tasks queues, and custom IAM service accounts, using the Google Cloud console.
However, if you actively use your installed extensions, we strongly recommend migrating to function kits. To move to function kits, use the instructions in our migration guide for users.
You can choose to not migrate to function kits, and in that case we highly recommend that you update all of your extensions to their latest versions, keep them updated, and export your existing extension configurations in case you want to migrate later.
What should I do as an extension publisher?
We encourage you to migrate your published extensions to function kits published on npm. You can start by migrating your extension to 2nd gen functions, which is a prerequisite for creating a function kit. This involves packaging your extension logic using the Cloud Functions v2 SDK. We've updated the Cloud Functions v2 SDK with support for features like declarative security and lifecycle events. You can now migrate your existing extension code to a 2nd gen function with minimal changes to your core business logic. These functions can be published using an npm package. For details, see our migration guide for publishers.
What if I have other questions?
Users who have questions can use our user migration guide. If you still have questions after using the guide, you can reach out to Firebase Support.
Publishers who have questions on how to migrate Firebase Extensions can use our migration guide for publishers. This guide includes instructions on how you can stay informed on updates and get help with providing an alternative to your published extensions.
Migration options and technical execution
What are the primary migration paths available?
Starting in September 2026, Firebase officially supports two primary migration pathways:
- Migrate to an NPM-Shared Function ("function kit"): Recommended for Stream Firestore to BigQuery and any other function kits that become available on npm. The core logic is packaged as a standard NPM library using the Cloud Functions v2 SDK. Users initialize a standard Cloud Functions codebase, install the package, re-export the functions, and deploy them independently using the CLI.
- Fork and Self-Manage: Recommended for all extensions that don't have a function kit available on npm. Users copy or fork the open-source extension source code, refactor the triggers into standard Firebase v2 Functions using best-effort AI migration skills or manual guides, and take full ownership of the codebase and its ongoing maintenance.
Which extensions are being migrated to function kits?
The Stream Firestore to
BigQuery
extension has been migrated to a function kit available as the npm package
@firebase-function-kits/firestore-bigquery-export.
Why does the migration require upgrading from Cloud Functions v1 to v2?
Cloud Functions v1 standard support ends with the Node.js 22 runtime. To prevent a "double migration" where developers migrate off Firebase Extensions only to be forced into a second manual refactoring when legacy runtimes sunset, Firebase strongly recommends upgrading all migrated functions to the v2 SDK immediately during this transition, and it is required for function kits.
As an Extensions user, you can also create your own function kits using the user migration guide.
Billing and pricing
Will migrating to self-managed Cloud Functions change a customer's billing?
Generally, no. Deployed extensions already charge customers for the underlying Google Cloud resources they consume, such as Cloud Functions invocations, Cloud Storage, or BigQuery storage and queries. However, during the migration window, customers may incur a small, temporary additional cost if they run both the legacy Firebase Extensions and their newly deployed replacement function in parallel to ensure a safe cutover.
How is billing handled for Mandiant or other specialized enterprise accounts?
This deprecation is a platform-wide change affecting all Firebase and Google Cloud projects. Standard billing and subscription arrangements are unaffected. If customers request SLA credits due to deprecation downtime or run into complex billing exceptions, escalate the case directly through normal billing support channels.
Troubleshooting and risk mitigation
What is the risk of data loss or service downtime during migration?
Transitioning managed resources to self-managed codebases runs a minor risk of service interruption or event loss.
- Trigger Disruption: If old triggers are deleted before new ones are active, a gap is created where events (e.g., Cloud Firestore document writes) are missed and permanently lost. We recommend deploying the replacement kit and validating it before removing the extension to avoid any data loss.
- Permission Gaps: If the newly deployed codebase lacks necessary IAM permissions, operations, like writing to BigQuery, will fail silently or crash at runtime. We've added declarative security for functions, so the first kit deploy done by an account that can query and set roles and generate a service account should mitigate this problem.
How do we prevent data loss for the critical Cloud Firestore-to-BigQuery Export extension?
To achieve a safe, zero-data-loss transition, support must advise users to follow an overlap-based cutover rather than a gap-based one. This is the default with the migration to kits:
- Deploy the replacement function kit while the extension is still installed and running. Wait a few minutes for Eventarc to fully provision.
- Write a test document to the watched Cloud Firestore collection and verify that the new self-managed function successfully writes a corresponding row to the BigQuery changelog table (carrying a new event ID).
- Once the new deployment is confirmed working, immediately uninstall or disable the legacy extension to terminate the double-writing behavior.
- Keep the overlap window as short as possible to minimize duplicate rows in the raw BigQuery changelog.
Dual writing during the migration window will result in two rows in the Raw Changelog Table (
*_raw_changelog) with the same document data and Cloud Firestore commit timestamp. However, the latest view of the table (*_raw_latest) will be correct.
More information on migrating this extension in particular and on how to recover from any data loss is detailed in the kit's README.md.
What should I do if the lifecycle provisioning step fails?
Under the managed service, setup tasks (such as creating BigQuery
datasets, tables, and views) were handled automatically. Under the self-managed
NPM model, these are triggered using a lifecycle task queue function; for
example, in firestore-bigquery-export this is called initBigQuerySync.
If this step fails or doesn't run automatically:
Verify that the Cloud Functions runtime service account has been granted the required IAM roles. For example, for
firestore-bigquery-exportthis includes:- To create resources and insert rows:
roles/bigquery.dataEditor - To run jobs and build views:
roles/bigquery.user - To enqueue the provisioning task:
roles/cloudtasks.enqueuer
- To create resources and insert rows:
Confirm that the caller has
roles/cloudtasks.enqueuerpermissions.Manually rerun the lifecycle initialization command using the CLI:
firebase functions:lifecycle:run afterInstall KIT_INSTANCE_IDCheck the Cloud Logging logs for both the trigger function and the task queue execution to diagnose any permission or configuration errors.
How are Secret Manager credentials migrated?
Under the managed model, Secret Manager resources were automatically
bound to the extension instances. When you use the ext:migrate or ext:export
--mode functions commands to export your extensions configuration to a function
kit, we stop extensions from managing these secrets so they stay in your project
after the extension is uninstalled. If you want to remove these secrets in the
future, you must do so manually in the Google Cloud console.
What if a user wants to run multiple instances of a migrated extension?
We introduced function kits as a way to support multiple instances of a function
similar to how you could have multiple versions of an extension. Each kit will
get a unique kit instance ID, which is similar to a codebase and can be used
interchangeably with codebases in CLI commands. When deployed, all functions in
a kit instance will be prefixed with kit-<instance-id>- to ensure every
function has a unique name, similar to the ext-<extension-instance-id>- prefix
in extensions. To learn more about how to use function kits as part of
migrating, see our user migration
guide.
Kit install uses npm; what if I want to use Yarn or another Node-compatible package manager?
We don't currently have plans to support Yarn or other package managers. The kit install works by directly executing npm commands when setting up the kit source code on first install.
As an alternative, you can create a source directory, install the kit npm
package yourself, and set it up with appropriate builds and exports. Refer to
our TypeScript index-kit templates in
firebase-tools
or look at an npm-installed kit as an example. Once you do this, you can install
it like a local kit using --directory rather than --package. Going forward,
you'll need to identify the kit by directory or ID, but you can use the kit
commands to add and remove instances.
My extension uses the Docker repository or KMS key advanced system parameters; how can I configure this in function kits?
Currently, we don't support configuring a Docker repository or KMS key in Cloud Functions for Firebase. If you're migrating from an extension with these system parameters configured and want to preserve this functionality, you can apply the parameters to your new kit's functions using the gcloud CLI.
Prerequisites
- Deploy your function kit initially following the migration guides so that the functions exist in Google Cloud.
Define your environment variables in your terminal:
export PROJECT_ID="YOUR_PROJECT_ID" export FUNCTION_REGION="YOUR_REGION" # e.g. us-east1 export KIT_NAME="YOUR_KIT_NAME" # e.g. firestore-bigquery-export export SOURCE_DIR="YOUR_KIT_SOURCE_DIR" # e.g. "./function-kits/${KIT_NAME}/source" export REPO_NAME="YOUR_DOCKER_REPO_NAME" export KEY_RING="YOUR_KMS_KEY_RING" export KEY_NAME="YOUR_KMS_KEY_NAME" # Retrieve Project Number automatically export PROJECT_NUMBER=$(gcloud projects describe "$PROJECT_ID" --format="value(projectNumber)")Pre-create
.gcloudignorein the kit's source root so compiled build files aren't ignored by.gitignore:cat << 'EOF' > "${SOURCE_DIR}/.gcloudignore" .gcloudignore .git .gitignore node_modules #!include:.gitignore !lib/** EOFGrant required IAM permissions:
For KMS keys (grants decryption access to the service agents):
for SERVICE_ACCOUNT in \ "service-${PROJECT_NUMBER}@serverless-robot-prod.iam.gserviceaccount.com" \ "service-${PROJECT_NUMBER}@gcf-admin-robot.iam.gserviceaccount.com" \ "service-${PROJECT_NUMBER}@gcp-sa-artifactregistry.iam.gserviceaccount.com" do gcloud kms keys add-iam-policy-binding "$KEY_NAME" \ --keyring="$KEY_RING" \ --location="$FUNCTION_REGION" \ --project="$PROJECT_ID" \ --member="serviceAccount:${SERVICE_ACCOUNT}" \ --role="roles/cloudkms.cryptoKeyEncrypterDecrypter" doneFor Artifact Registry (grants write access to Cloud Build and read access to Cloud Run):
# Grant the Cloud Build / Compute Service Account permission to write images to the repository gcloud artifacts repositories add-iam-policy-binding "$REPO_NAME" \ --location="$FUNCTION_REGION" \ --project="$PROJECT_ID" \ --member="serviceAccount:${PROJECT_NUMBER}-compute@developer.gserviceaccount.com" \ --role="roles/artifactregistry.writer" # Grant Cloud Run permission to pull images from the repository gcloud artifacts repositories add-iam-policy-binding "$REPO_NAME" \ --location="$FUNCTION_REGION" \ --project="$PROJECT_ID" \ --member="serviceAccount:service-${PROJECT_NUMBER}@serverless-robot-prod.iam.gserviceaccount.com" \ --role="roles/artifactregistry.reader"
Applying the settings using the gcloud CLI
Run gcloud functions deploy for each function in your kit:
gcloud functions deploy FUNCTION_NAME \
--project="$PROJECT_ID" \
--region="$FUNCTION_REGION" \
--source="./function-kits/${KIT_NAME}/source" \
--docker-repository="projects/${PROJECT_ID}/locations/${FUNCTION_REGION}/repositories/${REPO_NAME}" \
--kms-key="projects/${PROJECT_ID}/locations/${FUNCTION_REGION}/keyRings/${KEY_RING}/cryptoKeys/${KEY_NAME}"
Note that this workaround breaks under the following conditions:
- New kit instances: Adding an instance in
firebase.jsoncreates a new Cloud Functions v2 resource that defaults to Google-managed keys andgcf-artifacts. You must rungcloudfor each new instance. - Function recreation: Changing a trigger type (for example, from HTTPS to
a Cloud Firestore trigger), altering the entry point, or renaming causes
the Firebase CLI to delete the old function and create a new one. The new
function loses these settings until you run
gcloudagain. - Configuration drift: The Firebase CLI doesn't display KMS or Docker
repository status in
firebase functions:listor diff logs, which makes infrastructure auditing difficult.
Verifying success
To confirm the repository and encryption key were applied, run the following command:
gcloud functions describe FUNCTION_NAME \
--region="$FUNCTION_REGION" \
--project="$PROJECT_ID" \
--format="yaml(state, buildConfig.dockerRepository, kmsKeyName)"