skip to Main Content

I am trying to use Firebase Parameterized configuration with Typescript for Cloud Functions. Specifically, I am trying to use them at deploy time to specify a service account to use because I have three environments (dev, staging, prod) in separate firebase projects, with separate firestore databases.

I am following the instructions here https://firebase.google.com/docs/functions/config-env

I have no issue accessing these environment variable at runtime like in the instructions by calling .value()

I define my service account environment variable like so:

config.ts

import { defineString } from "firebase-functions/params"

export const SERVICE_ACCOUNT = defineString("SERVICE_ACCOUNT")

.env.

SERVICE_ACCOUNT = './service-account-dev.json'

Then when I would like to use this environment variable at deploy time I get some errors

index.ts

import * as admin from "firebase-admin"
import { SERVICE_ACCOUNT } from "./config"

admin.initializeApp({
  credential: admin.credential.cert(SERVICE_ACCOUNT),
})

Typescript error: "Argument of type ‘StringParam’ is not assignable to parameter of type ‘string | ServiceAccount’.ts(2345)"

And then, when I try to get the value here like so:
index.ts

import * as admin from "firebase-admin"
import { SERVICE_ACCOUNT } from "./config"

admin.initializeApp({
  credential: admin.credential.cert(SERVICE_ACCOUNT.value()),
})

With this code I now get no issues from typescript because the value is a string, but instead I get the an error when deploying to firebase (which is expected and mentioned in the instructions I linked at the top).

The error is as follows:

{"severity":"WARNING","message":"params.SERVICE_ACCOUNT.value() invoked during function deployment, instead of during runtime."}
{"severity":"WARNING","message":"This is usually a mistake. In configs, use Params directly without calling .value()."}
{"severity":"WARNING","message":"example: { memory: memoryParam } not { memory: memoryParam.value() }"}

So the issue I have is that I cannot use just the Param because typescript won’t compile, and then when I get the value from the param to make typescript happy I cannot deploy.

Can anyone help me out here? Thanks in advance

I am using the following packages for firebase functions and admin:

"firebase-admin": "^11.3.0",
"firebase-functions": "^4.1.0",

2

Answers


  1. defineString().value is a getter function. so you should use it as a parameter, not a method.

    import * as admin from "firebase-admin"
    import { SERVICE_ACCOUNT } from "./config"
    
    admin.initializeApp({
      credential: admin.credential.cert(SERVICE_ACCOUNT.value),
    })
    Login or Signup to reply.
  2. This is likely to be because it’s treating your

    admin.initializeApp({
      credential: admin.credential.cert(SERVICE_ACCOUNT),
    })
    

    As being at "build time", rather than as run time, if it’s outside of the main function execution.

    If you initializeApp inside the https.onCall(...) => {, (or onUpdate or whichever flavour you’re using) block itself, it should work as expected.

    I have seen other instances where the typing is incorrect, in some of the runWith options. (see https://github.com/firebase/firebase-tools/issues/5347) but casting to any makes the TS build work.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search