You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Below are comments for each extension to kit migration. Each comment displays the differences between the extension and the corresponding kit.
Valid differences
Some changes are due to migrations from gen1 functions to gen2. These specific changes have been excluded from the comments below.
yes / no params changed to booleans (with defineBoolean) in kits.
Service account params have been removed in kits, as they conflict with declarative security (requiresRole) stuff.
LOCATION params have been removed in kits, as kits builds this feature in.
Some changes may be due to dependency upgrades, or more recent Node versions.
Extensions previously didn't support a number type, so they used text/string type with regex (e.g. validation: ^[0-9]) for validation. Kits now use defineInt, so they don't require the regex validation.
required: defaults to true when omitted in extension.yaml, and several extensions omit it on params their own code and descriptions treat as optional (BACKUP_COLLECTION, DEFAULT_REPLY_TO, USERS_COLLECTION, TEMPLATES_COLLECTION). Kits match the code behaviour (optional, empty → undefined), not the yaml.
defineSecret cannot be optional — SecretParamOptions only takes label/description, so any bound secret must exist at deploy. Extension params declared type: secret, required: false (API_KEY, GOOGLE_AI_API_KEY, GEMINI_API_KEY, OPENAI_API_KEY, and the send-email SMTP/OAuth secrets) therefore become mandatory-at-deploy in kits. Platform constraint, not a kit choice.
Where an extension's yaml default disagreed with its own code fallback (firestore-genai-chatbot / firestore-vector-searchCOLLECTION_NAME, delete-user-dataAUTO_DISCOVERY_SEARCH_FIELDS), kits standardise on the yaml default.
No firebase-functions/params equivalent of the ${DATABASE_INSTANCE} system param. In the extension, the built-in FIREBASE_CONFIG.databaseURL resolves without prompting. This is something kit has to handle itself. Only applicable in rtdb-limit-child-nodes extension/kit.
IMG_BUCKET / EXTENSION_BUCKET use the params BUCKET_PICKER (a ResourceInput), which cannot also carry a validationRegex or example, so those two params keep the picker instead of the extensions' regex and example. The picker constrains input to real buckets, which is stronger, and this will stay as is.
Function resource properties (timeout, memory, maxInstances from each extension's resources[].properties) have not been systematically compared against the kit function definitions, and no sweep is planned — this may be something firebase-tools handles itself when deploying kits.
Kits have no deploy-time status surface. Extensions reported progress and failures through getExtensions().runtime().setProcessingState(...); nothing equivalent exists for kits, so deploy-time outcomes are only visible in function logs. Affects bigquery-firestore-export (10 call sites), firestore-bigquery-export (lifecycle hooks), firestore-translate-text (backfill) and firestore-vector-search (backfill gating).
billingRequired: true has no kit equivalent, so kits cannot declare the billing requirement that firestore-translate-text and rtdb-limit-child-nodes declared in their yaml.
rtdb-limit-child-nodes renamed NODE_PATH to RTDB_NODE_PATH and will keep it: Node.js reserves NODE_PATH for module resolution, so the original name is overwritten at runtime.
Event payload shapes changed with the gen1 to gen2 migration: { change, context } became { data, params } (firestore-counter, firestore-translate-text), and speech-to-text now publishes { message, stack } where the extension published a non-enumerable Error that serialised to {}. Consumers reading context.params need updating.
firestore-vector-search publishes Eventarc events where the extension published none (it declared the event types in extension.yaml but never published them). The kit exceeds the extension here rather than falling short.
extension.yaml used to have a reason for roles and APIs. Now with kits, only requiresAPI accepts a reason param. requiresRole doesn't accept a reason.
Cross-kit: no kit that publishes events declares roles/eventarc.publisher (firestore-counter, firestore-translate-text, firestore-bigquery-export, speech-to-text); with EVENTARC_CHANNEL set the awaited publish 403s and the function fails before doing any work - issue kits: declare roles/eventarc.publisher so event publishing does not 403 #3125
Cross-kit: AI-provider location fallback — firestore-genai-chatbotVERTEX_AI_MODEL_LOCATION=null no longer means "function region" (§3); firestore-translate-text vertex region from FUNCTION_REGION/genkit default (§2); firestore-vector-search same class (§5) — knock-on of the LOCATION removal, one decision — issue decision(kits): AI-provider location fallback after the LOCATION removal #3028 - as an example fbe had DATABASE_REGION (or similar) that is removed in the kit now, on kits branch.
Notes candidates (won't fix — differences to justify in Notes instead)
No deploy-time status surface in kits (no setProcessingState equivalent) — firestore-bigquery-export §3d, firestore-translate-text, firestore-vector-search §9d
billingRequired: true has no kit equivalent (firestore-translate-text, rtdb-limit-child-nodes)
firestore-bigquery-export: no onConfigure lifecycle equivalent (§3a) — DECISION: investigate — investigated: no gap, afterRedeploy covers it. firebase-tools hashes each endpoint as source+env+secrets, so an .env-only change marks the endpoint for update, which counts as a resource modification and fires afterRedeploy (release/lifecycle.js skips the hook only when nothing changed). The extension wired onUpdate and onConfigure to the same handler, and the kit wires afterRedeploy to the same idempotent setupBigQuerySync reconcile task, so behaviour is equivalent
firestore-translate-text: backfill removed, along with the "only fill missing languages" semantics — DECISION: no fix — the extension's backfill never deploys (resource and DO_BACKFILL commented out in its yaml), so no-backfill is parity — issue feat(firestore-translate-text): design backfill #3032
Below are comments for each extension to kit migration. Each comment displays the differences between the extension and the corresponding kit.
Valid differences
yes / noparams changed to booleans (withdefineBoolean) in kits.requiresRole) stuff.LOCATIONparams have been removed in kits, as kits builds this feature in.validation: ^[0-9]) for validation. Kits now usedefineInt, so they don't require the regex validation.required:defaults totruewhen omitted inextension.yaml, and several extensions omit it on params their own code and descriptions treat as optional (BACKUP_COLLECTION,DEFAULT_REPLY_TO,USERS_COLLECTION,TEMPLATES_COLLECTION). Kits match the code behaviour (optional, empty →undefined), not the yaml.defineSecretcannot be optional —SecretParamOptionsonly takeslabel/description, so any bound secret must exist at deploy. Extension params declaredtype: secret, required: false(API_KEY,GOOGLE_AI_API_KEY,GEMINI_API_KEY,OPENAI_API_KEY, and the send-email SMTP/OAuth secrets) therefore become mandatory-at-deploy in kits. Platform constraint, not a kit choice.firestore-genai-chatbot/firestore-vector-searchCOLLECTION_NAME,delete-user-dataAUTO_DISCOVERY_SEARCH_FIELDS), kits standardise on the yaml default.firebase-functions/paramsequivalent of the${DATABASE_INSTANCE}system param. In the extension, the built-inFIREBASE_CONFIG.databaseURLresolves without prompting. This is something kit has to handle itself. Only applicable inrtdb-limit-child-nodesextension/kit.IMG_BUCKET/EXTENSION_BUCKETuse the paramsBUCKET_PICKER(aResourceInput), which cannot also carry avalidationRegexorexample, so those two params keep the picker instead of the extensions' regex and example. The picker constrains input to real buckets, which is stronger, and this will stay as is.timeout,memory,maxInstancesfrom each extension'sresources[].properties) have not been systematically compared against the kit function definitions, and no sweep is planned — this may be something firebase-tools handles itself when deploying kits.getExtensions().runtime().setProcessingState(...); nothing equivalent exists for kits, so deploy-time outcomes are only visible in function logs. Affectsbigquery-firestore-export(10 call sites),firestore-bigquery-export(lifecycle hooks),firestore-translate-text(backfill) andfirestore-vector-search(backfill gating).billingRequired: truehas no kit equivalent, so kits cannot declare the billing requirement thatfirestore-translate-textandrtdb-limit-child-nodesdeclared in their yaml.rtdb-limit-child-nodesrenamedNODE_PATHtoRTDB_NODE_PATHand will keep it: Node.js reservesNODE_PATHfor module resolution, so the original name is overwritten at runtime.{ change, context }became{ data, params }(firestore-counter,firestore-translate-text), andspeech-to-textnow publishes{ message, stack }where the extension published a non-enumerableErrorthat serialised to{}. Consumers readingcontext.paramsneed updating.firestore-vector-searchpublishes Eventarc events where the extension published none (it declared the event types inextension.yamlbut never published them). The kit exceeds the extension here rather than falling short.extension.yamlused to have areasonfor roles and APIs. Now with kits, onlyrequiresAPIaccepts a reason param.requiresRoledoesn't accept areason.Look into
Potentially could useAnswered: yes - firebase-tools >= 15.27.0 injects it for kit instances (discovery, deploy, emulator, serve). It must be read viaFIREBASE_KIT_INSTANCE_ID?process.env, never declared as a param (the params machinery only consults.env, and theFIREBASE_prefix is reserved there). Implemented for delete-user-data in fix(delete-user-data): read the kit instance id from FIREBASE_KIT_INSTANCE_ID #3060; migration of the remaining kits tracked in refactor(kits): migrate all kits from the INSTANCE_ID param to the injected FIREBASE_KIT_INSTANCE_ID #3063.Remaining parity work
Correctness / production-firing
bigquery-firestore-export: soft failures → hard failures — cases the extension reportedPROCESSING_COMPLETEnow throw underretry: true→ retry storms (§7a–7c, §8) - fix(bigquery-firestore-export): stop retrying deploy-time misconfigurations #2983 — fix(bigquery-firestore-export): stop retrying deploy-time misconfigurations #2983 @IzaakGough look into this, what should the kit behaviour be — fix(bigquery-firestore-export): stop retrying the two failures the extension treated as terminal #3086 (merged) stops retrying the two terminal failures; config-validation residual tracked in issue fix(bigquery-firestore-export): soft failures throw and retry-storm #3008firestore-send-email: SendGrid +AUTH_TYPE=OAuth2sends fail — secret gating forcesapiKey: undefined,setApiKeynever called — issue fix(firestore-send-email): SendGrid sends fail with AUTH_TYPE=OAuth2 #3009 — fix(firestore-send-email): keep SMTP_PASSWORD available so SendGrid works with AUTH_TYPE=OAuth2 #3089 (open)storage-resize-images: partial-env crashes — issue fix(storage-resize-images): degrade gracefully against a partial env #3138 - fix(storage-resize-images): degrade gracefully against a partial env #3002 (approved, unmerged)storage-resize-images:CONTENT_FILTER_LEVEL"Off" option stored the stringFalseinstead ofOFF, so every resize with the filter off threw at runtime — issue fix(storage-resize-images): the "Off" content-filter selection stores "False" and fails every event #3047 — fix(storage-resize-images): map the Off content-filter option to OFF #3064 (open, Needs Changes; follow-ups fix(storage-resize-images): IS_ANIMATED select label is True, the extension says Yes #3123 label, feat(storage-resize-images): reject unknown IMAGE_TYPE values at config resolve time #3124 staleIMAGE_TYPEvalidation)firestore-send-email:DATABASE_REGIONused as function region — the conflation fixed for firestore-bigquery-export by fix(firestore-bigquery-export): stop using DATABASE_REGION as the function region #3066/fix(firestore-bigquery-export): place functions from DATABASE_REGION with a multi-region mapping #3101 is still live here:kits/firestore-send-email/src/config.ts:378passesparams.databaseRegionstraight toregion, andeur3/nam5/nam7remain selectable, so deploy hard-fails on a multi-region database — issue fix(firestore-send-email): DATABASE_REGION used as function region breaks multi-region deploys #3069 — fix(firestore-send-email): map DATABASE_REGION to a Cloud Run region for function placement #3102 (open, unmerged)PROJECT_IDresolution — the extension readsprocess.env.PROJECT_ID(functions/src/config.ts:166), injected by the Extensions runtime, and defaultsBIGQUERY_PROJECT_IDto the${PROJECT_ID}system param; kits usefirebase-functions/paramsprojectID(kits/firestore-bigquery-export/src/config.ts:119,627), which resolves fromFIREBASE_CONFIG.projectIdand yields""when that is absent. Surfaced by 🐛 [@firebase-function-kits/firestore-bigquery-export] afterFirstDeploy taskqueue initialization failed from missing PROJECT_ID #3120 (and the older 🐛 [firestore-bigquery-export] Project ID resolves to undefined in Gen2 / Cloud Run functions #2778); the shared change-tracker fallbackbqProjectId || process.env.PROJECT_ID(firestore-bigquery-change-tracker/src/bigquery/snapshot.ts:68) is fixed in fix(bigquery): preserve project on view updates #3121 (open), which the kit inherits via@firebaseextensions/firestore-bigquery-change-tracker@^2.1.0roles/eventarc.publisher(firestore-counter,firestore-translate-text,firestore-bigquery-export,speech-to-text); withEVENTARC_CHANNELset the awaited publish 403s and the function fails before doing any work - issue kits: declare roles/eventarc.publisher so event publishing does not 403 #3125Migration / consumer breaks
firestore-vector-search: status field shape change —status.<instanceId>.stateconsumers break (§6) - issue decision(firestore-vector-search): status field shape, nested per-instance vs flat #3139 (decision; fix(firestore-vector-search): restore terminal-state skip on embedOnWrite #3092 leaves the shape out of scope)firestore-vector-search: OpenAI index dimension does not match the vectors written —dimensionFor()returns 512 for openai (kits/firestore-vector-search/src/export-config.ts:105) while ada-002 writes 1536 (src/embeddings/client/text/open_ai.ts:34), sofindNearestcannot use the index. Inherited from the extension and reproduced exactly by fix(firestore-vector-search): restore the extension's embedding defaults #3096; decision(firestore-vector-search): embedding model and dimension defaults #3029 decided the model, not the dimension — issue decision(firestore-vector-search): OpenAI vector index is 512 dimensions while the vectors are 1536 #3105.createIndexnever compares dimension (src/queries/setup.ts:49-56), so any fix needs a delete-the-old-index migration notefirestore-bigquery-export: legacy back-compat event types dropped — the extension published bothfirebase.extensions.firestore-counter.v1.*(legacy) and…firestore-bigquery-export.v1.*; the kit publishes only the new ones — issue fix(firestore-bigquery-export): republish the legacy firestore-counter event types #3108 — fix(firestore-bigquery-export): republish the legacy firestore-counter event types #3111 @cabljac @CorieWspeech-to-text: transcoded.wavlands in a different Storage location (§1, including the.txtpath's retainedreplace("tmp/", …)) -.txtremnant fixed in fix(speech-to-text): stop stripping tmp/ from the .txt transcription path #3073; the.wavlocation decision remains open - issue decision(speech-to-text): transcoded .wav lands in a different Storage location #3140{change, context}→{data, params}(firestore-counter§5,firestore-translate-text),speech-to-texterror{}→{message, stack}— decision recorded in issue decision(kits): event payload shape {change, context} vs {data, params} #3027 (open): NOT intentional gen2 design, fix — fix(kits): restore the extensions' event payload shapes #3098 @CorieWEvents gaps
firestore-translate-text: early-returns on!event.datawithout emitting start/completion events; the extension always emitted both — issue fix(firestore-translate-text): always emit start and completion events #3020 @cabljacBehavior divergence (fix or decide)
firestore-vector-search: re-embed-on-update flipped (the extension never re-embeds terminal docs) + ERROR-retry flipped (§6a/6b) — issue fix(firestore-vector-search): restore re-embed and ERROR-retry semantics #3011 DECISION: parity where possible with extension — fix(firestore-vector-search): restore terminal-state skip on embedOnWrite #3092 @CorieWfirestore-vector-search: backfill de-batched — per-document tasks and embedding calls, metadata-doc gate lost,collection().get()loads every document into memory → every redeploy re-embeds the whole collection (§9) — DECISION: fix, aim for parity — issue fix(firestore-vector-search): restore batched backfill #3012 — fix(firestore-vector-search): restore batched backfill #3097 @CorieWfirestore-vector-search: multimodal unimplemented yet still an offeredEMBEDDING_PROVIDERvalue (§3) - fix(firestore-vector-search): remove the unimplemented multimodal provider value #3074 — fix(firestore-vector-search): remove the unimplemented multimodal provider value #3074 — DECISION: fix, aim for parity @CorieW + @cabljacfirestore-genai-chatbot: startup fail-fast removed (validateRequiredEnvVars()) — DECISION: track as follow-up — issue fix(firestore-genai-chatbot): validate conditional config combinations at first invocation #3022firestore-genai-chatbotVERTEX_AI_MODEL_LOCATION=nullno longer means "function region" (§3);firestore-translate-textvertex region fromFUNCTION_REGION/genkit default (§2);firestore-vector-searchsame class (§5) — knock-on of theLOCATIONremoval, one decision — issue decision(kits): AI-provider location fallback after the LOCATION removal #3028 - as an example fbe had DATABASE_REGION (or similar) that is removed in the kit now, on kits branch.globalVertex AI endpoint. Partial coverage: vector search is untouched, and decision(kits): AI-provider location fallback after the LOCATION removal #3028’s explicit-region decision is not fully implemented. This task remains open.storage-resize-images: programmatic default flips —deleteOriginalunsetonSuccess→never;isAnimatedunsetfalse→true(§1–2) — DECISION: deleteOriginal parity (onSuccess); isAnimated stays true, the extension's unset-false was a shipped bug (|| undefined), fixed and documented in README — issue fix(storage-resize-images): restore programmatic defaults for deleteOriginal and isAnimated #3024 — fix(storage-resize-images): restore the extension's default for an omitted deleteOriginal #3100bigquery-firestore-export:DISPLAY_NAMEedits silently no-op — never added to the DTS update mask — issue fix(bigquery-firestore-export): DISPLAY_NAME edits silently no-op on update #3141 - fix(bigquery-firestore-export): apply DISPLAY_NAME changes on update #2980 (open)bigquery-firestore-export: BigQuery job/billing project nowconfig.projectId— the extension used the ADC default (§10) — decide/Note @IzaakGoughbigquery-firestore-export:TRANSFER_CONFIG_NAMEenables the extension's dead link-config branch — behavior beyond the extension (§3) — decide/Note fix(bigquery-firestore-export): notify this instance's topic when linking a config #2960firestore-translate-text:nullinput routes differently —typeof null === "object", so the extension sends{ input: null }totranslateMultipleand throws inObject.entries(functions/src/translate/translateMultiple.ts:35); the kit'sinput !== nullguard (kits/firestore-translate-text/src/translate/translateDocument.ts:44) routes it totranslateSingle, and fix(firestore-translate-text): stop coercing non-string input before translation #3109's test pins that (tests/translate-document.test.ts:116) — decide/Note - issue decision(firestore-translate-text): null input routes to translateSingle instead of throwing #3142firestore-bigquery-export:EXCLUDE_OLD_DATA/USE_NEW_SNAPSHOT_QUERY_SYNTAX- extension acceptedyes/no, kitdefineBooleanacceptstrueonly, so a migrated.envwithyessilently reads as false - issue firestore-bigquery-export kit: EXCLUDE_OLD_DATA and USE_NEW_SNAPSHOT_QUERY_SYNTAX read 'yes' as false #3126 - decide/NoteFeature-scale (design first)
firestore-bigquery-export: write-path buffering — the extension buffers in Cloud Tasks; the kit rethrows and can hot-loop (§1) — issue feat(firestore-bigquery-export): design write-path buffering #3031 — DECISION: reinstate the Cloud Tasks buffer (option D, migration safety) — feat(firestore-bigquery-export): reinstate the Cloud Tasks write buffer #3103 closed 2026-09-07 in favour of stack #3132, bottom to top: chore(firestore-bigquery-export): bump firebase-admin to ^14.2.0 #3127 (firebase-admin ^14.2.0), feat(firestore-bigquery-export): add the sync task enqueue module #3128 (enqueue module), feat(firestore-bigquery-export): add the sync queue params #3129 (queue params), feat(firestore-bigquery-export): reinstate the Cloud Tasks write buffer #3130 (the behaviour change), docs(firestore-bigquery-export): document failure handling and recovery #3131 (docs), all open @cabljacNotes candidates (won't fix — differences to justify in Notes instead)
setProcessingStateequivalent) —firestore-bigquery-export§3d,firestore-translate-text,firestore-vector-search§9dbillingRequired: truehas no kit equivalent (firestore-translate-text,rtdb-limit-child-nodes)Event payload shape, if ruled intentional gen2 design— ruled NOT intentional in issue decision(kits): event payload shape {change, context} vs {data, params} #3027 (open); fix in fix(kits): restore the extensions' event payload shapes #3098Minor / cosmetic (batchable)
storage-resize-images:IS_ANIMATEDselect label readsTruewhere the extension saysYes(kits/storage-resize-images/src/config.ts:189vsextension.yaml:289-292) — issue fix(storage-resize-images): IS_ANIMATED select label is True, the extension says Yes #3123Completed
Correctness / production-firing
storage-resize-images: deletion risk — emptyimageTypes→ zero outputs counts as success → original deleted underon_success(§6) - fix(storage-resize-images): failed resize can delete the original image #3037 (merged)firestore-counter:deep-equalcalled without{ strict: true }in the worker (§1) - fix(firestore-counter): compare worker metadata with strict deep-equal #3072 (merged)storage-resize-images: content-filter region readsFUNCTION_REGIONand throws when absent; the extension fell back tous-central1(§5) - fix(storage-resize-images): restore the us-central1 content-filter fallback #3090 (merged)firestore-vector-search:queryOnWriteprefilterscast unvalidated — the extension zod-parses them (§7b) - fix(firestore-vector-search): validate prefilters on the query onWrite path #3065 (merged)firestore-vector-search:queryOnWriteself-retrigger loop (§7) - fix(firestore-vector-search): stop queryOnWrite retriggering itself #3038 (merged; stored-request guard, self-heals the stale-overwrite race — supersedes fix(firestore-vector-search): guard queryOnWrite with the extension's status #3095, which is still open and should be closed)bigquery-firestore-export: Pub/Sub topic renamedext-→kit-, update path rewrotenotification_pubsub_topic(§4) - fix(bigquery-firestore-export): make the DTS notification topic configurable #3088 (merged; topic configurable viaPUB_SUB_TOPIC, set it to the oldext-topic to preserve notifications across migration)firestore-bigquery-export:DATABASE_REGIONused as function region —eur3/nam5/nam7aren't Cloud Run regions → deploy hard-fails (§2) - fix(firestore-bigquery-export): stop using DATABASE_REGION as the function region #3066 (merged, live-verified on a nam5 database; the same conflation is still live in firestore-send-email: fix(firestore-send-email): DATABASE_REGION used as function region breaks multi-region deploys #3069 (open), tracked under Remaining parity work. NOTE: fix(firestore-bigquery-export): stop using DATABASE_REGION as the function region #3066's param removal partially reverted by fix(firestore-bigquery-export): place functions from DATABASE_REGION with a multi-region mapping #3101, which restores DATABASE_REGION as a placement param with the dual-region mapping, per the firebase-tools team's minimal-divergence decision and upstream bug Functions deploy: region resolution runs before param substitution, parameterized Firestore trigger database silently falls back to us-central1 firebase-tools#11020)Migration / consumer breaks
firestore-vector-search: OpenAI model changed — ada-002 → 3-small@512, incompatible with existing indexes (§2) — decision recorded in issue decision(firestore-vector-search): embedding model and dimension defaults #3029 (revert to the extension's defaults) — fix(firestore-vector-search): restore the extension's embedding defaults #3096 (merged)firestore-vector-search: gemini/vertex embedding dimensions changed — extension hardcodedoutputDimensionality: 768with no truncation; kit passesconfig.dimensionand truncates the result (§5) — fix(firestore-vector-search): restore the extension's embedding defaults #3096 (merged)Events gaps
firestore-bigquery-export:onSuccessnever published, and the kit README claims it is — doc bug, small standalone fix - docs(firestore-bigquery-export): stop claiming the kit publishes onSuccess and onCompletion #3071 (merged; doc-only, no code change needed)firestore-vector-search: events published only fromhandleEmbedOnWrite— nothing from the query/backfill/update/init paths — fix(firestore-vector-search): stop publishing events the extension never sent #3094 (merged) resolves issue fix(firestore-vector-search): publish events from all paths #3016 by REMOVING the kit-only events instead (the extension never published any; parity) @CorieWBehavior divergence (fix or decide)
firestore-bigquery-export: noonConfigurelifecycle equivalent (§3a) — DECISION: investigate — investigated: no gap,afterRedeploycovers it. firebase-tools hashes each endpoint as source+env+secrets, so an.env-only change marks the endpoint for update, which counts as a resource modification and firesafterRedeploy(release/lifecycle.jsskips the hook only when nothing changed). The extension wiredonUpdateandonConfigureto the same handler, and the kit wiresafterRedeployto the same idempotentsetupBigQuerySyncreconcile task, so behaviour is equivalentfirestore-genai-chatbot: generation options now reach the model — DECISION: forward — README note in docs(kits): note that genai chatbot generation options now reach the model #3087 (merged)firestore-translate-text: newTranslationServiceper invocation — fresh client per event, performance (§5f) - fix(firestore-translate-text): construct the translation client once per process #3075 (merged)firestore-vector-search: vector-store error codes collapsed tounknown— the extension mapped 15 Firestore codes toHttpsError(§8) — DECISION: fix, parity — issue fix(firestore-vector-search): map vector-store errors to HttpsError codes #3015 — fix(firestore-vector-search): map vector-store errors to HttpsError codes #3093 (merged)firestore-send-email:TESTINGenv path gone — the kit cannot enter testing mode via env — issue fix(firestore-send-email): restore the TESTING env path #3107 — fix(firestore-send-email): restore the TESTING env path #3110 (merged) @CorieWfirestore-translate-text: non-string input coerced —42→"42"reaches the API (§4b) — minor, decide — DECISION: fix, aim for parity — issue fix(firestore-translate-text): stop coercing non-string input before translation #3106 — fix(firestore-translate-text): stop coercing non-string input before translation #3109 (merged) @CorieWFeature-scale (design first)
firestore-counter: no client libraries (Android/iOS/Dart/node/web), shard format undocumented — closed as not planned (feat(firestore-counter): client libraries and shard format documentation #3033): migration only; the existing extension clients keep working against the unchanged shard formatfirestore-translate-text: backfill removed, along with the "only fill missing languages" semantics — DECISION: no fix — the extension's backfill never deploys (resource andDO_BACKFILLcommented out in its yaml), so no-backfill is parity — issue feat(firestore-translate-text): design backfill #3032firestore-bigquery-export: user-facing tooling absent — import, gen-schema-view, cross-project scripts, guides — DECISION: reference existing extension scripts/tooling — issue feat(firestore-bigquery-export): user-facing tooling #3034Notes candidates (won't fix — differences to justify in Notes instead)
rtdb-limit-child-nodes:NODE_PATHrename (Node.js reserves the name)Minor / cosmetic (batchable)
firestore-bigquery-export:logs.start()called with no argument → logsundefined(§4) - chore(firestore-bigquery-export): drop unused config parameter from logs.start #3039 (merged)firestore-vector-search: custom-endpoint content-type check dropped (§4c) - fix(firestore-vector-search): reject non-JSON responses from the custom embeddings endpoint #3042 (merged)firestore-send-email:formatZodErrorinvalid_stringbranch dropped - fix(firestore-send-email): restore the invalid_string branch in formatZodError #3040 (merged)storage-resize-images:BLOCK_NONEaccepted where the extension threw (§4);cacheControlHeader: ""set literally (§7) - fix(storage-resize-images): reject BLOCK_NONE and treat empty Cache-Control as unset #3044 (merged)bigquery-firestore-export: dropped log helpers;MAX_STALENESSdoc example 8h → 4h - chore(bigquery-firestore-export): restore dropped log helper and MAX_STALENESS doc example #3045 (merged)delete-user-data:node-fetch@2where the extension used globalfetch- chore(delete-user-data): replace node-fetch with the Node global fetch #3041 (merged)firestore-translate-text: dead backfill remnants (filterLanguagesFn, unused log helpers) - chore(firestore-translate-text): delete dead backfill remnants from the kit #3043 (merged)firestore-genai-chatbot: localSafetySettingtype (no enum check);PROJECT_IDerror text - fix(firestore-genai-chatbot): type safety settings against the SDK enums and restore the PROJECT_ID error text #3046 (merged; whole minor-cleanups batch issue chore(kits): minor parity cleanups #3036 now complete)Coverage
bigquery-firestore-export: 1330 unit + 3170 E2E lines → 550 unit;ensureNotificationTopicuntested - test(bigquery-firestore-export): port legacy unit coverage into the kit #3056 (merged; 19 → 65 tests)firestore-genai-chatbot: emulator E2E + logger/overrides/config suites gone - test(firestore-genai-chatbot): port missing coverage from the legacy extension #3058 (merged; incl. emulator flow test, now run in PR CI via ci(kits): run emulator-gated kit suites on pull requests #3070)firestore-counter: no emulator tests - test(firestore-counter): port the active legacy emulator tests #3054 (merged; run in PR CI via ci(kits): run emulator-gated kit suites on pull requests #3070)delete-user-data: lazygetContext()path untested - closed by fix(delete-user-data): resolve the RTDB client on first use #2955 and test(delete-user-data): pin context memoization and client wiring #3055 (both merged)firestore-send-email: 2540 → 483 lines - test(firestore-send-email): port the legacy unit suites into the kit #3057 (merged; 121 tests, coverage audit found no decrease vs the legacy suite)