I am upgrading my firebase functions to V2 and I want to use the new way of managing secrets via defineSecret
described here:
https://firebase.google.com/docs/functions/config-env?hl=en&gen=2nd
It is not clear to me how this works with onRequest
to host a function via express
that can be accessed from outside the firebase framework.
Here is a minimal version of my setups (which worked with firebase functions V1):
import express from "express"
import cors from "cors"
import { onRequest } from "firebase-functions/v2/https"
const app = express()
app.use(
cors({
origin: function (origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void) {
if (!origin) return callback(null, true)
return callback(null, true)
},
}),
)
import { handleNewProfile } from "./handlers/profiles" // needs a secret key for external service like sendgrid
app.post("/profiles/", handleNewProfile)
export const api = onRequest({ region: "europe-west1" }, app) // how to pass secret to app?
I can add the secrets to the first argument like this:
import { defineSecret } from "firebase-functions/params"
{ region: DEFAULT_REGION, secrets: [secretDiscordToken] }
But how do I hand it down to handleNewProfile
?
I have not found this case in the docs and ChatGPT also does not know! :)
Any help would be greatly appreciated.
Thanks for the help Doug Stevenson!
I am including a complete answer since it may be helpful to the next person!
I first thought I needed to hand down a secret explicitly in the file where it is defined via defineSecret
and passed down to a firebase function like onRequest
.
What I learned is, that any function called via onRequest
can access the secret. There is no need to hand it down explicitly.
Below is a working minimal example of how it can work.
// ./handlers/secretTest.ts
import { Request, Response } from "express"
import { defineSecret, defineString } from "firebase-functions/params"
const blubb = defineString("BLUBB")
const secretTest = defineSecret("TEST_NOT_REALLY_SECRET")
const printSecret = (req: Request, res: Response) => {
const envVar = `${blubb.value()}`
const secret = `${secretTest.value()}`
res.send(`secret: ${secret} - envVar: ${envVar}!`)
}
export { printSecret }
Here is the main file where the secret is added to the dependency array of onRequest
. Even though there are a few indirections (with using express) until the secret is referenced, it all works:
// index.ts
import express, { Request, Response } from "express"
import cors from "cors"
import { onRequest } from "firebase-functions/v2/https"
import { defineSecret } from "firebase-functions/params"
import { printSecret } from "./handlers/secretTest"
const secretTest = defineSecret("TEST_NOT_REALLY_SECRET")
const app = express()
app.use(
cors({
origin: function (origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void) {
// allow requests with no origin
// (like mobile apps or curl requests)
if (!origin) return callback(null, true)
// return the callers origin - Access-Control-Allow-Origin: <origin>
// Note for testing locally: Some browsers may reject "localhost" as origin.
return callback(null, true)
},
}),
)
app.get("/test", printSecret)
export const api = onRequest({ region: "europe-west1", secrets: [secretTest] }, app)