Skip to content

feat(functions): Implement TaskQueue Scopes#3210

Open
inlined wants to merge 7 commits into
firebase:mainfrom
inlined:feat/task-queue-scopes
Open

feat(functions): Implement TaskQueue Scopes#3210
inlined wants to merge 7 commits into
firebase:mainfrom
inlined:feat/task-queue-scopes

Conversation

@inlined

@inlined inlined commented Jul 9, 2026

Copy link
Copy Markdown
Member

Description

This PR introduces Task Queue Scopes to the Firebase Admin SDK functions module. It decouples the legacy backward-compatible string-to-scope migration logic from the stateless client and isolates it inside the API wrapper layer (TaskQueue).

Key Changes

  1. API Wrapper Retry & Upgrade (TaskQueue):
    • TaskQueue.enqueue() and delete() now capture 404 errors for legacy string parameters ('extensionOrKit' scope).
    • On a 404 error, they automatically retry using a temporary kit scope.
    • If the retry succeeds, the wrapper mutates the stateful scope to 'kit' and logs a legacy targeting warning.
  2. Immediate Self-Targeting Warning:
    • Matches targeting parameters against process.env.EXT_INSTANCE_ID and process.env.KIT_INSTANCE_ID at construction time.
    • If self-targeting is detected, it logs an immediate deprecation/performance warning and mutates the scope immediately to 'extension' or 'kit', bypassing unnecessary 404 fallback call roundtrips.
  3. Design style: chose to make the migration logic part of the API type and not the API internals type to more obviously collect what is transitionary/migration logic that can be removed later
  4. Unit Tests:
    • Added unit tests verifying scope resolves to global if no environment variables are set.
    • Added unit tests verifying self-targeting warnings and direct namespaced resolution for both extensions and kits.

@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 introduces a new FunctionScope type to represent the scope of a function in a task queue, deprecating the legacy extensionId string parameter. It updates FunctionsApiClient, Functions, and TaskQueue to support these scopes (including current, global, extension, and internal kit scopes) with fallback logic for migration, and adds comprehensive unit tests. The review feedback highlights a few issues and improvement opportunities: correcting a typo ('peformance') and an invalid scope value ({ scope: "self" } instead of { scope: "current" }) in warning messages (and their corresponding tests), removing a redundant type check in TaskQueue, and improving type safety in FunctionsApiClient by avoiding an as any cast through discriminated union narrowing.

Comment thread src/functions/functions.ts
Comment thread src/functions/functions.ts
Comment thread src/functions/functions.ts Outdated
Comment thread test/unit/functions/functions-api-client-internal.spec.ts Outdated
Comment thread src/functions/functions-api-client-internal.ts Outdated

@lahirumaramba lahirumaramba left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you for submitting this!
LGTM! Added a couple of comments.

Comment thread src/functions/functions.ts Outdated
Comment thread src/functions/functions-api-client-internal.ts Outdated
* @param id - The ID of the task to delete.
* @param functionName - The function name of the queue.
* @param extensionId - Optional canonical ID of the extension.
* @param scope - Optional FunctionScope configuration.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could we get a TW review on these new docstrings, please?

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.

This looks like a literal, FunctionScope. Though, would just "function scope" work as a common noun/general term?

See bottom note here: https://docs.google.com/presentation/d/1Ezb4sp4XD6ItHISccnME-EVH_oJj59R5Naq0IskLrAo/edit?slide=id.g1cd7eabb964_0_10#slide=id.g1cd7eabb964_0_10

@lahirumaramba lahirumaramba added release:stage Stage a release candidate and removed release:stage Stage a release candidate labels Jul 14, 2026
@inlined inlined requested a review from egilmorez July 14, 2026 16:59

@egilmorez egilmorez 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.

Thanks, I do have some nits! :)

* @param id - The ID of the task to delete.
* @param functionName - The function name of the queue.
* @param extensionId - Optional canonical ID of the extension.
* @param scope - Optional FunctionScope configuration.

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.

This looks like a literal, FunctionScope. Though, would just "function scope" work as a common noun/general term?

See bottom note here: https://docs.google.com/presentation/d/1Ezb4sp4XD6ItHISccnME-EVH_oJj59R5Naq0IskLrAo/edit?slide=id.g1cd7eabb964_0_10#slide=id.g1cd7eabb964_0_10

* @param data - The data payload of the task.
* @param functionName - The functionName of the queue.
* @param extensionId - Optional canonical ID of the extension.
* @param scope - Optional FunctionScope configuration.

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.

Same as above; literal?

@@ -132,10 +140,15 @@ export class FunctionsApiClient {
*
* @param data - The data payload of the task.
* @param functionName - The functionName of the queue.

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.

Should be either functionName or just "function name."

Better yet, more words might make it all more clear. Is it the name of the function associated with the queue, or some even better verb than "associate?"

*
* @param functionName - The name of the function.
* @param extensionId - Optional Firebase extension ID.
* @param scope - Optional FunctionScope configuration. Only needed if targeting a scope other than the current one.

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.

I think this should be FunctionScope with code font for the literal.

* @param functionName - The name of the function.
* @param client - The `FunctionsApiClient` instance.
* @param extensionId - Optional canonical ID of the extension.
* @param scope - Optional FunctionScope configuration. Only needed if targeting a scope other than the current one.

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.

Same as above RE literal.

/**
* @param functionName - The name of the function.
* @param client - The `FunctionsApiClient` instance.
* @param extensionIdOrScope - Optional canonical ID of the extension or FunctionScope.

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.

Probably FunctionScope

}).not.to.throw();
});

it('should not throw given a valid scope object: current', () => {

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.

LMK if these "it('...." comments are public. I think they are not.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants