Issue Description:
I am having trouble setting the region
property of my Gen 2 Firebase Functions using TypeScript and a parameterized variable due to type mismatch issues. Here’s a sample of my .env
file:
LOCATION="australia-southeast1"
I have attempted to define the region
both globally and at the function level.
1. Defining region globally using setGlobalOptions
I would prefer to define the region
globally using setGlobalOptions
.
The global region
property on setGlobalOptions
has a type of GlobalOptions.region?: string | Expression<string> | ResetValue | undefined
. This is slightly different from the function level type HttpsOptions.region?: string | string[] | Expression<string> | ResetValue | undefined
as the global level only allows for a singular string
and no string[]
.
No matter what I do at the global level, it fails. All three of these attempts give a deployment error Error: Illegal type coercion of param LOCATION to type string[]
:
setGlobalOptions({
region: defineString("LOCATION"),
});
setGlobalOptions({
region: defineString("LOCATION") as unknown as string,
});
setGlobalOptions({
region: defineList("LOCATION") as unknown as string,
});
Therefore, I am unsure how to define region
on setGlobalOptions
using a parameterized variable.
2. Defining region at the function level
When I tried defining region
at the function level, the IDE showed region
as HttpsOptions.region?: string | string[] | Expression<string> | ResetValue | undefined
.
I thought defineString()
would work as it returns a string
. Although there were no errors in the IDE, during deployment I received this error Error: Illegal type coercion of param LOCATION to type string[]
.
import { onCall } from "firebase-functions/v2/https";
import { testValidators } from "../../../services/tests";
import { defineString } from "firebase-functions/params";
export const functionName = onCall(
{
region: defineString("LOCATION"),
},
(request) => {
testValidators(request);
}
);
Next, I tried to define the region
using defineList()
, but that produced a type error in the IDE:
import { onCall } from "firebase-functions/v2/https";
import { testValidators } from "../../../services/tests";
import { defineString } from "firebase-functions/params";
export const functionName = onCall(
{
region: defineList("LOCATION"),
},
(request) => {
testValidators(request);
}
);
Here is the IDE error:
Type 'ListParam' is not assignable to type 'string | string[] | Expression<string> | ResetValue | undefined'.
Type 'ListParam' is not assignable to type 'Expression<string>'.
The types returned by 'value()' are incompatible between these types.
Type 'string[]' is not assignable to type 'string'.ts(2322)
The following works, but it is confusing because region
should accept a string
, so why do I need to use defineList()
and further assert it with defineList("LOCATION") as unknown as string[]
?
import { onCall } from "firebase-functions/v2/https";
import { testValidators } from "../../../services/tests";
import { defineString } from "firebase-functions/params";
export const functionName = onCall(
{
region: defineList("LOCATION") as unknown as string[],
},
(request) => {
testValidators(request);
}
);
Overall there seems to be a lot of problems with the typing for region
both at the function and global level.
I managed to get the function level working with an assertion, but I would still prefer to use region
on setGlobalOptions
with a parameterized variable.
Any help to resolve this issue would be greatly appreciated!
Environment:
- Node.js: 16.16.0
- firebase-functions: 4.4.1
- firebase-tools: 12.4.4
- firebase-admin: 11.10.1
2
Answers
I reported this as an issue and Google has put out a fix that will be merged soon.
According to this answer provided by Jed Choi you have to set the region using
DefineList
as unknown then use it asregion: <string[]>secret_value,
Here’s updated code for you :
If you choose to use firebase functions gen1 then you can follow this answer
Update:
I have tested : You can set the region globally with
setGlobalOptions
with thedefineList
but you need to specify it as a string so at runtime you will get delimiter,
: