firebase-tools icon indicating copy to clipboard operation
firebase-tools copied to clipboard

Firebase Emulator simply does not initialize .env || .env.local || .env.default

Open polisen opened this issue 3 years ago • 47 comments

Related issues

https://github.com/firebase/firebase-functions/issues/1084

[REQUIRED] Version info

**node:**v14.17.6

**firebase-functions:**3.20.1 **firebase-tools:**10.6.0

**firebase-admin:**10.1.0

[REQUIRED] Test case

  • Create local firebase project
  • insert and populate .env, .env.local, .env.default (for good measure)
  • start emulator suite
  • log process.env

[REQUIRED] Steps to reproduce

[REQUIRED] Expected behavior

For process.env to have been populated with local .env values.

[REQUIRED] Actual behavior

.env values are nowhere to be found.

Were you able to successfully deploy your functions?

Technically, yes.

polisen avatar May 04 '22 18:05 polisen

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

google-oss-bot avatar May 04 '22 18:05 google-oss-bot

One issue I've seen with other customer is that the .env files were located outside the functions directory, e.g.

repo/
  firebase.json
  functions/
    .env
    .env.local

Can you share your directory setup to confirm?

taeold avatar May 04 '22 18:05 taeold

I can confirm that the folder is located within functions. The .env format is also correct. I have rimraffed and re-installed everything, reconfigured emulators, removed .runtimeconfig.json but no dice.

polisen avatar May 04 '22 18:05 polisen

Thanks, everyone for your research. I faced the same issue when locally "firebase-functions" did not get the environment variables. Maybe this will help somebody while we are waiting to fix this issue:

  1. Install dotenv. npm install dotenv --save
  2. Use dotenv package in your function(for instance in index.ts) to load environment variables:
import { api } from './http';
import dotenv from 'dotenv';

dotenv.config();

export {
  api,
}

Now you can access your .env using process.env.AWESOME_VAR_NAME

UPDATE: In my case, I found out how to solve the issue without using the "dotenv" package. I have added an env variable named FIREBASE_PROJECT_NAME, and this was a mistake, I used reserved environment variables. One of the rules says, Do not use any of these keys in your .env files: "All keys starting with FIREBASE_". When I removed FIREBASE_PROJECT_NAME variable from the .env file everything start working locally as expected.

Verbunix avatar Jun 05 '22 11:06 Verbunix

not working with firebase-tools 11, process.env doesn't set at all event if the .env is under functions/.env

hellsingblack avatar Jun 29 '22 19:06 hellsingblack

@Verbunix Thanks for the hint. It sounds like the Emulator is silently ignoring badly configured environment variables. That's a pain - I'll follow up here if I can improve that.

@polisen @hellsingblack Can you review/share content of your dotenv files (to extent it's safe! I don't want to see your API keys)? Maybe you guys are hitting similar issue.

taeold avatar Jun 30 '22 19:06 taeold

Hey @polisen. We need more information to resolve this issue but there hasn't been an update in 7 weekdays. I'm marking the issue as stale and if there are no new updates in the next 3 days I will close it automatically.

If you have more information that will help us get to the bottom of this, just add a comment!

google-oss-bot avatar Jul 11 '22 01:07 google-oss-bot

Since there haven't been any recent updates here, I am going to close this issue.

@polisen if you're still experiencing this problem and want to continue the discussion just leave a comment here and we are happy to re-open this.

google-oss-bot avatar Jul 14 '22 01:07 google-oss-bot

Seems related to this issue: https://stackoverflow.com/questions/71254427/firebase-functions-dotenv-variable-undefined

calclavia avatar Jul 19 '22 05:07 calclavia

The .env is not loaded when using the --import option. firebase emulators:start --export-on-exit --import <my-folder>.

When using only firebase emulators:start, it is working fine.

Sutil avatar Aug 15 '22 16:08 Sutil

Seems related to this issue: https://stackoverflow.com/questions/71254427/firebase-functions-dotenv-variable-undefined

@Sutil I was able to fix this by setting the same node version in package.json as you have in terminal. Also ensure that your package.json is using the same firebase-tools version. Once I was running the latest, it all worked

rishabh-rastogi215 avatar Oct 04 '22 13:10 rishabh-rastogi215

Is there any news on this? I'm pretty sure this is still an issue.

Zachcodes avatar Oct 28 '22 23:10 Zachcodes

I'm having the same problem - I'm using firebase emulators:start --import=myImportFolder --export-on-exit .

When I run this from my main project folder (C:/myProject) I am able to import and export my data successfully but none of my .env.local variables are available.

If I cd functions/ (C:/myProject/functions) and execute the same command there, I get all my variables BUT I'm not able to export successfully. When the emulator shuts down, it deletes the import folder and creates TWO firebase-export-{alphanumericString} folders, both appear to be a copy of the exported data.

Also worth noting that if I try to run firebase emulators:export {importFolder} while running in the functions folder, I get this error in the emulator logs (does not happen when running in project root):
! emulators: Export failed: EPERM: operation not permitted, rename 'firebase-export-1667420687188p1aAWH' -> 'C:\myProject\functions\myImportFolder'

I tried copying my .env.local into the project root but that seems to have had no effect. No vars when I start emulators from root, faulty export when I start from the functions folder.

joshorvis avatar Nov 02 '22 20:11 joshorvis

Confirmed this is still an issue.

I'm running firebase-tools 11.24.0.

The Functions Emulator would not load the .env files into process.env before the function bootstraps even when I see this logged to the console:

functions: Loaded environment variables from .env, .env.<projectId>, .env.local. 

In some places it worked if I added this to my ./index.js root/entry file:

import dotenv from 'dotenv';

dotenv.config();

But this doesn't work:

export const api = functions
  .region(process.env.region)
  .https.onRequest(app);

Which seems to defeat the purpose of the autoloading mechanism that's documented here:

https://firebase.google.com/docs/functions/config-env#emulator_support

and here:

https://firebase.google.com/docs/emulator-suite/connect_functions#configure_a_local_testing_environment

rscotten avatar Feb 27 '23 22:02 rscotten

I've encountered the same issue when --import is used. Only .env is loaded, .env.local is ignored. Any workaround?

nerder avatar Feb 28 '23 21:02 nerder

@polisen Can you leave a comment here so the bot will reopen the issue? I can confirm it is still happening with [email protected] and [email protected]

Padreco-lbr avatar Apr 03 '23 18:04 Padreco-lbr

I had this issue of variables not being loaded, but my case was related to a misunderstanding with the doc. Both the .env and .env.dev files are loaded, but the behavior of variable replacement is not what I expected. TL;DR: To fix the issue, I defined all variables in .env and redefined them accordingly in .env.dev.

I understood that different env files are replaced depending on the project alias. For example, .env.dev would replace .env if I am in firebase use dev. But this is not the case: a variable in .env.dev only replaces a variable from .env if it exists in .env in the first place.

Previously, my understanding was of a union behavior: variables from .env are loaded, then variables from .env.dev are loaded, and they replace existent variables from .env. Now, my understanding is as follows: variables from .env are loaded and only this set of loaded variables can be redefined in .env.dev, no new variables can be added.

jhonatanoliveira avatar Apr 21 '23 20:04 jhonatanoliveira

I had this issue of variables not being loaded, but my case was related to a misunderstanding with the doc. Both the .env and .env.dev files are loaded, but the behavior of variable replacement is not what I expected. TL;DR: To fix the issue, I defined all variables in .env and redefined them accordingly in .env.dev.

I understood that different env files are replaced depending on the project alias. For example, .env.dev would replace .env if I am in firebase use dev. But this is not the case: a variable in .env.dev only replaces a variable from .env if it exists in .env in the first place.

Previously, my understanding was of a union behavior: variables from .env are loaded, then variables from .env.dev are loaded, and they replace existent variables from .env. Now, my understanding is as follows: variables from .env are loaded and only this set of loaded variables can be redefined in .env.dev, no new variables can be added.

If this is true, can you write the docs instead? I'll test this out later tonight

juane1000 avatar Apr 21 '23 23:04 juane1000

@polisen Can you please re-open this issue? The bot closed it for inactivity but since then more people complained, including me.

I'm having the same problem. I opened a SOF issue there and then I found this GH issue so I thought I would share. The problem seems to be that environment variables are not being loaded during the deployment process. We should have a way to tell the deployment process to load the dotenv files.

(BTW @nerder and @jhonatanoliveira you guys are talking about a very different problem...)


Update: I confirm the following snippet:

export const myfunction = onDocumentCreated(
	`users/{uid}/${process.env.TEST_KEY}/{id}`,
	(event) => {
		console.log(process.env.TEST_KEY);
	}
);

will produce the following trigger details in Google Cloud Console

image

vdegenne avatar Jun 16 '23 21:06 vdegenne

My testing so far has shown that all variables I define inside my .env files are available inside my function body, but only inside them.

So if I have an condition in my index.ts, where the function exports are defined, then process.env will only log the google firebase environment variables. But if I log the same process.env again inside one of my functions, then the correct and expected process.env content, which is defined in my .env-file will be printed.

This is somewhat understandable, as firebase does only include the .env file(s) in the package that gets uploaded and deployed. So the actual building step uses the host system variables which has started the build/deploy process. Be it a pipeline or the local shell on your computer.

But now the strange, and to me unexplainable, part starts.

If I run for example this command: export NODE_ENV=production && export TEST=test && export STAGE=stage && firebase emulators:start --only functions and put this logging near the top of my index.ts file:

console.log('NODE_ENV', process.env.NODE_ENV )
console.log('TEST', process.env.TEST )
console.log('STAGE', process.env.STAGE )

this is the output:

NODE_ENV production
TEST undefined
STAGE undefined

and if I only start it without any exports, like so: firebase emulators:start --only functions

then the output changes to this:

NODE_ENV undefined
TEST undefined
STAGE undefined

I have no idea why only the NODE_ENV survives and everything else gets lost. Given, there are still a lot of firebase related variables if I print my whole process.env but I have not idea where to look further for some explanation why my host system environment variables are mostly ignored, apart from NODE_ENV.

I also tested to start it with a random NODE_ENV value, to make sure its not from some build process and pure coincidence: export NODE_ENV=foobar && export TEST=test && export STAGE=stage && firebase emulators:start --only functions

That resulted in this output:

NODE_ENV foobar
TEST undefined
STAGE undefined

If anyone has any clues on what is wrong here or how this can get fixed I would be very grateful.

Diesmo avatar Jul 06 '23 22:07 Diesmo

I can validate this. The simplest reproducible case is:

# main.py
import os
if not int(os.getenv("WORKS", 0)):
    raise ValueError("This won't get raised")
if not int(os.getenv("FAILS", 0)):
    raise ValueError("This does get raised")
# .env
WORKS=1
# .env.local
FAILS=1

@Diesmo As a clue, the secret injection is also broken. I suuuuspect for the same reason: the environment variable injection system is bricked. I've been hunting around for the relevant source code, but only in spare time. Please update here if you find something.


Even if, as suggested above, default values are established in .env, the same failure occurs:

# .env
FAILS=0

TL;DR: To fix the issue, I defined all variables in .env and redefined them accordingly in .env.dev.

That is, this ^ didn't work.

ekalosak avatar Sep 28 '23 21:09 ekalosak

Running into the same issue here.

OskarGroth avatar Nov 06 '23 13:11 OskarGroth

Transferring the issue to Firebase Tools repository where emulator is implemented.

taeold avatar Nov 06 '23 18:11 taeold

.env variables are only accessible from INSIDE the function ! (not outside, meaning inside onRequest( ( request, response ) => {...} ). That's it.

As the doc says : "Once your custom environment variables are deployed, your function code can access them..."

sk8killer avatar Nov 23 '23 23:11 sk8killer

So there is no way at all to make a trigger that grabs the current environment bucket, for example: onObjectFinalized({ bucket: '${process.env.UPLOAD_BUCKET}' }? I need different buckets for each environment

OskarGroth avatar Nov 24 '23 12:11 OskarGroth

I am facing the same issue where I need to load different environment variables to trigger my cloud function according to my projectId. However, I could access the env variables inside the function body.

eg:

functions.region(process.env.REGION).storage.bucket().object(process.env.CUSTOM_BUCKET).onDelete((obj)=>{
    console.log(process.env.CUSTOM_BUCKET) // This will print the value of CUSTOM_BUCKET, But the trigger is not set on the function
})

mohammedmarjan-aTeam avatar Dec 28 '23 07:12 mohammedmarjan-aTeam

Same issue here, the deployment is failing due to the code requiring an environment variable to exists. The variable is already defined in the .env and no reserved name is being used in the file. Still the deployment does not print the below line (which is documented in Firebase)

$ firebase deploy --only functions
# ...
# i functions: Loaded environment variables from .env.
# ...

Using "firebase-functions": "^4.6.0" & "firebase-tools": "^13.0.2"

a7md0 avatar Jan 06 '24 08:01 a7md0

Same issue here, the deployment is failing due to the code requiring an environment variable to exists. The variable is already defined in the .env and no reserved name is being used in the file. Still the deployment does not print the below line (which is documented in Firebase)

$ firebase deploy --only functions
# ...
# i functions: Loaded environment variables from .env.
# ...

Using "firebase-functions": "^4.6.0" & "firebase-tools": "^13.0.2"

If none of yours environment variables are used inside one of your firebase function, the .env variable file will not be loaded. It is the normal behavior.

sk8killer avatar Jan 06 '24 08:01 sk8killer

deployment is failing due to the code requiring an environment variable to exis

My code will throw an exception if that environment variable in not defined, and that's what is happening during the analysis.

a7md0 avatar Jan 06 '24 09:01 a7md0

I try to migrate using gen2 for firebase functions but it seems like it is not possible any more to set simple environmental variables . So what other option do I have? My firebase functions depend on a package inside the node_modules directory and it expects some environmental variables to be setup to get initialized correctly. How will I communicate the variables into my code that lives outside the function body?

mustafaekim avatar Feb 06 '24 12:02 mustafaekim