firebase / firebase/extensions

[firestore-bigquery-change-tracker] initializeLatestView update path mutates the shared RawChangelogViewSchema constant

Open Beginner friendly
#3,144 0 comments 0 reactions 0 assignees View on GitHub
extension: firestore-bigquery-export type: bug
Dominant language
TypeScript
Stars
979
Forks
433
Avg merge
1d 22h
Merged PRs (30d)
127

Description

Package: `@firebaseextensions/firestore-bigquery-change-tracker`, `src/bigquery/initializeLatestView.ts` on `next`.

The existing-view path aliases the module-level constant and mutates it:

```ts
const schema = RawChangelogViewSchema; // line 77
...
if (config.wildcardIds) {
schema.fields.push(documentPathParams); // line 86
}
```

The create path copies first (`const schema = { fields: [...RawChangelogViewSchema.fields] }`, line 124), so only the update path leaks. Each `initializeLatestView` call in the same process with `wildcardIds` set appends another `path_params` field to the shared constant. Later readers of `RawChangelogViewSchema` in the same process see the duplicates, including `view.setMetadata({ schema: RawChangelogViewSchema })` on line 144 of the create path.

In a long-lived function instance that initialises more than once (several trackers, or the `initBigQuerySync` task followed by the trigger) the schema sent to BigQuery grows by one duplicate `path_params` per init. BigQuery rejects duplicate column names in a schema update, so after the first re-init the update path fails until the instance is recycled.

Fix: copy on the update path the same way the create path does.

```ts
const schema = { fields: [...RawChangelogViewSchema.fields] };
```

And pin it with a test that calls `initializeLatestView` twice with `wildcardIds: true` and asserts `RawChangelogViewSchema.fields` is unchanged.

Found during the adversarial review of #3137. Not reproduced live.

Contributor guide

Open the contributing guide

Research direction

Start in src/bigquery/initializeLatestView.ts at initializeLatestView and compare the existing-view path with the create path's schema copy. Call initializeLatestView twice with wildcardIds: true and verify that RawChangelogViewSchema.fields is unchanged, while the update path still receives the added path_params field without duplicates.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
databases
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
92/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.