Skip to content

fix(firestore): fallback to valid resource path in createSnapshotFromJson - #1942

Open
ajperel wants to merge 2 commits into
masterfrom
ajp/fix-1922
Open

fix(firestore): fallback to valid resource path in createSnapshotFromJson#1942
ajperel wants to merge 2 commits into
masterfrom
ajp/fix-1922

Conversation

@ajperel

@ajperel ajperel commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Description

If the document payload is missing the name field (e.g., during an onDocumentDeleted trigger where the "after" snapshot payload is intentionally absent), createSnapshotFromJson construct a mocked snapshot and defaults the resource path to the event.source.

However, the event.source for Firestore CloudEvents is typically just the database prefix (e.g. //cloudevents.googleapis.com/projects/YOUR_PROJECT/databases/(default)), which is an invalid Firestore document resource path as it lacks the documents/DOC_ID suffix. Falling back to this caused Firestore#snapshot_ to crash with invalid resource path errors in various edge cases (such as PubSub fallbacks).

This commit updates the fallback to use getPath(event) instead, synthesizing a valid projects/{project}/databases/{database}/documents/{document} resource path to correctly mock the snapshot.

Also removes our cache of the Firestore instance to rely instead on the better (per db) cache inside of Admin SDK.

Partially addresses #1922

Scenarios Tested

npm test
firebase deploy --only functions (with a bug repro case)

Release notes

relnote: fix(firestore): fallback to valid resource path in createSnapshotFromJson (#1922)

…Json

If the document payload is missing the `name` field (e.g., during an `onDocumentDeleted` trigger where the "after" snapshot payload is intentionally absent), `createSnapshotFromJson` construct a mocked snapshot and defaults the resource path to the `event.source`.

However, the `event.source` for Firestore CloudEvents is typically just the database prefix (e.g. `//cloudevents.googleapis.com/projects/YOUR_PROJECT/databases/(default)`), which is an invalid Firestore document resource path as it lacks the `documents/DOC_ID` suffix. Falling back to this caused `Firestore#snapshot_` to crash with invalid resource path errors in various edge cases (such as PubSub fallbacks).

This commit updates the fallback to use `getPath(event)` instead, synthesizing a valid `projects/{project}/databases/{database}/documents/{document}` resource path to correctly mock the snapshot.

Partially addresses #1922

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the Firestore provider to use getPath(event) instead of event.source when creating snapshots from JSON, ensuring the correct path is resolved even when the document value is missing. It also adds corresponding unit tests and updates helper documentation. The review feedback highlights two main improvement opportunities: first, using optional chaining when casting and accessing event.data to prevent potential runtime TypeError crashes if event.data is null or undefined; second, refactoring the global firestoreInstance caching mechanism to prevent cross-database bugs in multi-database environments.

Comment thread src/v2/providers/firestore.ts Outdated
Comment thread src/v2/providers/firestore.ts Outdated
Comment thread src/common/providers/firestore.ts
const snapshot = firestore.createBeforeSnapshot(rawEvent);

expect(snapshot.exists).to.be.false;
expect(snapshot.ref.path).to.eq("foo/fGRodw71mHutZ4wGDuT8");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extreme nit: i think pretty much everything in this codebase uses .equal, which is identical to .eq because javascript devs are just Like That

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants