From 9666f5a6d5921f784ac5871839a508073b3238b7 Mon Sep 17 00:00:00 2001 From: Corie Watson Date: Mon, 7 Sep 2026 04:16:10 +0100 Subject: [PATCH 1/3] fix(bigquery): preserve project on view updates Closes #3120 --- .../initializeLatestView.test.ts | 39 +++++++++++++++++++ .../src/bigquery/initializeLatestView.ts | 1 + 2 files changed, 40 insertions(+) diff --git a/firestore-bigquery-export/firestore-bigquery-change-tracker/src/__tests__/bigquery/materializedViews/initializeLatestView.test.ts b/firestore-bigquery-export/firestore-bigquery-change-tracker/src/__tests__/bigquery/materializedViews/initializeLatestView.test.ts index ab9d3aa848..27303d5e9b 100644 --- a/firestore-bigquery-export/firestore-bigquery-change-tracker/src/__tests__/bigquery/materializedViews/initializeLatestView.test.ts +++ b/firestore-bigquery-export/firestore-bigquery-change-tracker/src/__tests__/bigquery/materializedViews/initializeLatestView.test.ts @@ -80,5 +80,44 @@ describe("initializeLatestView", () => { expect(initializeLatestMaterializedView).not.toHaveBeenCalled(); }); + + it("uses the BigQuery project when updating an existing view", async () => { + const originalProjectId = process.env.PROJECT_ID; + process.env.PROJECT_ID = "function-project"; + const metadata = { + schema: { + fields: [{ name: "document_id" }, { name: "old_data" }], + }, + view: { query: "SELECT FIRST_VALUE(data)" }, + }; + mockView.getMetadata.mockResolvedValueOnce([metadata]); + + try { + await initializeLatestView({ + bq: { projectId: "bigquery-project" } as any, + dataset: { id: "test_dataset" } as any, + view: mockView as any, + viewExists: true, + rawChangeLogTableName: "test_raw_table", + rawLatestViewName: "test_raw_view", + changeTrackerConfig: { + ...mockConfig, + useNewSnapshotQuerySyntax: true, + }, + }); + + expect(mockView.setMetadata).toHaveBeenCalledWith(metadata); + expect(metadata.view.query).toContain( + "`bigquery-project.test_dataset.test_raw_table`" + ); + expect(metadata.view.query).not.toContain("function-project"); + } finally { + if (originalProjectId === undefined) { + delete process.env.PROJECT_ID; + } else { + process.env.PROJECT_ID = originalProjectId; + } + } + }); }); }); diff --git a/firestore-bigquery-export/firestore-bigquery-change-tracker/src/bigquery/initializeLatestView.ts b/firestore-bigquery-export/firestore-bigquery-change-tracker/src/bigquery/initializeLatestView.ts index b0e7fc9394..fe8ee95717 100644 --- a/firestore-bigquery-export/firestore-bigquery-change-tracker/src/bigquery/initializeLatestView.ts +++ b/firestore-bigquery-export/firestore-bigquery-change-tracker/src/bigquery/initializeLatestView.ts @@ -104,6 +104,7 @@ export async function initializeLatestView({ datasetId: config.datasetId, tableName: rawChangeLogTableName, schema, + bqProjectId: bq.projectId, useLegacyQuery: !config.useNewSnapshotQuerySyntax, }); From 6c19cf10eebf52f001f6b20b46da737390f1c61b Mon Sep 17 00:00:00 2001 From: Jacob Cable Date: Mon, 7 Sep 2026 18:05:40 +0100 Subject: [PATCH 2/3] chore(firestore-bigquery-change-tracker): release 2.2.1 --- .../firestore-bigquery-change-tracker/CHANGELOG.md | 4 ++++ .../firestore-bigquery-change-tracker/package-lock.json | 4 ++-- .../firestore-bigquery-change-tracker/package.json | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/firestore-bigquery-export/firestore-bigquery-change-tracker/CHANGELOG.md b/firestore-bigquery-export/firestore-bigquery-change-tracker/CHANGELOG.md index a4c97b0bc8..7c2d247200 100644 --- a/firestore-bigquery-export/firestore-bigquery-change-tracker/CHANGELOG.md +++ b/firestore-bigquery-export/firestore-bigquery-change-tracker/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 2.2.1 + +- Updating an existing `_raw_latest` view now builds the snapshot query with the configured BigQuery project. That path dropped `bqProjectId`, so the query fell back to `process.env.PROJECT_ID`, which is only set for extensions. On a kit or any other plain Cloud Function the view was written as `undefined..` and the update failed. + ## 2.2.0 - Works on `firebase-admin` 14. 2.1.1 widened the range but the package still used the namespaced API (`admin.apps`, `admin.firestore.Timestamp`), which firebase-admin 14 removes, so it threw at import wherever it was resolved against admin 14. Every use is now the modular API from `firebase-admin/app` and `firebase-admin/firestore`, which works on 13 and 14 alike. diff --git a/firestore-bigquery-export/firestore-bigquery-change-tracker/package-lock.json b/firestore-bigquery-export/firestore-bigquery-change-tracker/package-lock.json index 999ee96349..c48b68c381 100644 --- a/firestore-bigquery-export/firestore-bigquery-change-tracker/package-lock.json +++ b/firestore-bigquery-export/firestore-bigquery-change-tracker/package-lock.json @@ -1,12 +1,12 @@ { "name": "@firebaseextensions/firestore-bigquery-change-tracker", - "version": "2.2.0", + "version": "2.2.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@firebaseextensions/firestore-bigquery-change-tracker", - "version": "2.2.0", + "version": "2.2.1", "license": "Apache-2.0", "dependencies": { "@google-cloud/bigquery": "^7.6.0", diff --git a/firestore-bigquery-export/firestore-bigquery-change-tracker/package.json b/firestore-bigquery-export/firestore-bigquery-change-tracker/package.json index 0ebc3ea45b..ae4300fe2e 100644 --- a/firestore-bigquery-export/firestore-bigquery-change-tracker/package.json +++ b/firestore-bigquery-export/firestore-bigquery-change-tracker/package.json @@ -5,7 +5,7 @@ "url": "git+https://github.com/firebase/extensions.git", "directory": "firestore-bigquery-export/firestore-bigquery-change-tracker" }, - "version": "2.2.0", + "version": "2.2.1", "engines": { "node": ">=18" }, From 667f22006059b9cc2a95baeaf15f12007ba6ada8 Mon Sep 17 00:00:00 2001 From: Jacob Cable Date: Mon, 7 Sep 2026 18:15:12 +0100 Subject: [PATCH 3/3] chore(firestore-bigquery-change-tracker): tighten 2.2.1 changelog --- .../firestore-bigquery-change-tracker/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firestore-bigquery-export/firestore-bigquery-change-tracker/CHANGELOG.md b/firestore-bigquery-export/firestore-bigquery-change-tracker/CHANGELOG.md index 7c2d247200..2d74076c8b 100644 --- a/firestore-bigquery-export/firestore-bigquery-change-tracker/CHANGELOG.md +++ b/firestore-bigquery-export/firestore-bigquery-change-tracker/CHANGELOG.md @@ -2,7 +2,7 @@ ## 2.2.1 -- Updating an existing `_raw_latest` view now builds the snapshot query with the configured BigQuery project. That path dropped `bqProjectId`, so the query fell back to `process.env.PROJECT_ID`, which is only set for extensions. On a kit or any other plain Cloud Function the view was written as `undefined..
` and the update failed. +- Updating an existing `_raw_latest` view now builds the snapshot query with the configured BigQuery project. That path dropped `bqProjectId`, so the query fell back to `process.env.PROJECT_ID`, which is only set for extensions. On a kit, or any caller that passes `bqProjectId` but does not set `PROJECT_ID`, the query referenced `undefined..
` and BigQuery rejected the update. For an extension whose `BIGQUERY_PROJECT_ID` differs from `PROJECT_ID`, the update previously built the view against the functions project instead of the BigQuery project. ## 2.2.0