Unable to access environment variables in google cloud (node js express app) - node.js

I am a beginner trying to learn web development. I have built small node js app and deployed in heroku. I am trying to do the same in GCP and learn the platform.
Code used is # https://github.com/unnikrishnan-r/firstgcpdeployment
The issue that I am facing is Unable to access env variables in the app
My index.js
exports.envVar = (req, res) => {
// Sends 'bar' as response
console.log("bbbccc");
console.log(process.env.JAWSDB_URL);
res.status(200).send(process.env.JAWSDB_URL);
return process.env.JAWSDB_URL;
};
.env.yaml is
JAWSDB_URL: testtest456
I then used below to deploy the function to gcloud
gcloud functions deploy envVar --env-vars-file .env.yaml --runtime nodejs8 --trigger-http;
Deployment was successful and was tested using console and
https://us-central1-howtodeployingcp.cloudfunctions.net/envVar
During deploy this happened
Can some one help me here?

It seems this line is problematic:
var dbUrl = envVar.envVar();
You're calling the function without passing in req, res as it's expecting. Perhaps you forgot to comment out this line.

Related

can i run a node function on a react app directly

I am making a react app where I need to fetch some data using an API.
I want to deploy this app with Netlify so I cannot use a backend. So, I wrote a Firebase Cloud Function to handle the fetching. However, Google wouldn't allow third-party API requests on the free plan.
So either I have to learn using AWS or I will write a backend and deploy using another service.
Honestly, I don't want to do either. So, my question is, can I call this node function directly inside my react app if so how and is it advisable, if not are there any other alternatives?
The function is something like this:
const functions = require("firebase-functions");
const League = require("leagueapiwrapper");
require("dotenv").config();
exports.getFavorites = functions.https.onCall(async (data, context) => {
try {
const LeagueAPI = new League(process.env.API_KEY, Region.TR);
...
The only thing that actually requires node is the leagueapiwrapper package. (Obviously I will get rid of firebase related stuff).

Simple way to configure NodeJS environment

I am really just getting into cloud stuff and have been creating Node JS apps as a hobby for a long time. I am using MongoDB as my database. I have now pushed my app on Heroku and am happy that it runs, but I've only realized some things like there is no local storage and no database without addons. So now I have a free Atlas (MongoDB) hosting so my Heroku app can use that as its database.
My app starts with a simple npm start which does the build stuff (like grunt) and then runs the node app. But how can I change the environment to be production vs deploy so that if I did something like npm start -prod it would use the cloud hosted database, but npm start -dev would use my PC's MongoDB instance?
This what I do -
Loading environment variables from an .env file and passing them to the Node.js runtime would be the ideal case.
const loadEnvironment = async function () {
fs.readFile('.env', 'utf8', function (err, data) {
if (err) {
return console.log(err);
}
return (data);
});
}; //loadEnvironment
For instance, file name .env which contains 'prod' or 'dev'. Handle db connections based on the env obtain from this file.

Setting up dotenv in firebase functions

I am trying to move the tiny node-express app I made into firebase functions.
The file have dotenv variables. Earlier I thought If I just deploy and put dotenv in dependency, It will work but that didn't happen so..
So, I went to environment configuration article of firebase to understand how I can set .env
Which states to set things by doing something like this
firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"
But I have so many environment configuration and doing that some what seems to be cumbersome task.
So let's say this is environment file
# App port Address
PORT = 8080
# Google Secret
GOOGLE_CALLBACK_URL = http://localhost:8080/auth/google/callback
GOOGLE_CLIENT_ID = 4048108-bssbfjohpu69vl6jhpgs1ne0.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET = lTQHpjzY57oQpO
# Client Address
CLIENT_ADDRESS = http://localhost:3000/
# Meetup Secret
MEETUP_CALLBACK_URL = http://localhost:8080/auth/meetup/callback
MEETUP_CLIENT_ID = ef6i9f7m6k0jp33m9olgt
MEETUP_CLIENT_SECRET = sk3t5lnss2sdl1kgnt
#EventBrite Secret
EVENTBRITE_CALLBACK_URL = http://localhost:8080/auth/eventbrite/callback
EVENTBRITE_CLIENT_ID = UU2FXKGYHJRNHLN
EVENTBRITE_CLIENT_SECRET = NA55QG52FAOF6GDMLKSJBKYOPIGQU4R46HHEU4
How Can I best set up so that when I do firebase firebase serve --only functions,hosting it doesn't throw any errors such as
OAuth2Strategy requires a clientID option
As of Feb 16, 2022 Firebase now supports .env, .env.prod, .env.dev, .env.local files natively!
https://firebase.google.com/docs/functions/config-env
Set your variables in the corresponding environment, and then run firebase use dev or firebase use prod before you deploy.
Your variables can be accessed via process.env.VARIABLE_NAME
UPDATED 2019-06-04
I'm very sorry. This solution is wrong.
I found the correct way.
https://stackoverflow.com/a/45064266/1872674
You should put a .runtimeconfig.json into the functions directory. Your dotenv variables move to .runtimeconfig.json with json format.
This is my solution.
const functionConfig = () => {
if (process.env.RUN_LOCALLY) {
const fs = require('fs');
return JSON.parse(fs.readFileSync('.env.json'));
} else {
return functions.config();
}
};
The functionConfig() was called by your Firebase Function.
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("someservice id is: " + functionConfig().someservice.id);
});
.env.json is like:
{
"someservice": {
"key":"THE API KEY",
"id":"THE CLIENT ID"
}
}
Finally, run the command with the RUN_LOCALLY variable.
RUN_LOCALLY=1 firebase serve
When we will deploy functions,
don't forget to update the environment configuration in Firebase using the .env.json.
The Firebase CLI currently doesn't allow you to set process environment variables on deployment. This may change in the future. The configuration vars it supports today (that you linked to) are not actually process environment variables - they stored somewhere else that's not actually the process environment.
If you absolutely need to be able to set process environment variables, you will have to deploy your function with gcloud, which means that you also won't be able to use the firebase-functions module to define your function. Start with the Google Cloud Functions documentation to learn about deployment from a Cloud perspective.
If you want to use the Firebase tools, I'd recommend that you find a different way to configure your function that doesn't involve process environment variables.
If you want to have your functions use the process.env variables, you you can set them by going to google cloud console and cloud functions. You will be able to find the deployed firebase functions there. You can select each function one by one and then set the environment variables there.
what I did was create a env.json file into functions FOLDER:
//env.json
{
"send_email_config": {
"FOW_ADMIN_EMAIL": "admin.example#gmail.com",
"FOW_ADMIN_EMAIL_PASSWORD": "adminPassExample",
"FOW_ADMIN_RECEIVER_EMAIL": "adminReceiver.example#gmail.com"
}
}
then I created a file called env.js where I created a function to return the value of functions.config() which is kind of env module
//env.js
// TO UPDATE functions.config().env RUN INSIDE functions FOLDER:
// firebase functions:config:set env="$(cat env.json)"
const functions = require('firebase-functions');
const getEnvConfig = () => {
/*
I return functions.config().env cause I set the env.json values into env
property running firebase functions:config:set env="$(cat env.json)"
*/
return functions.config().env
}
exports.getEnvConfig = getEnvConfig;
exports.PROCESS_ENV = getEnvConfig();
then I just call PROCESS_ENV to access the values that I set on env.json file for example:
const { PROCESS_ENV } = require('./utils/env');
exports.mailCredentials = {
main: {
email: PROCESS_ENV.send_email_config.FOW_ADMIN_EMAIL,
password: PROCESS_ENV.send_email_config.FOW_ADMIN_EMAIL_PASSWORD
},
receiver: {
email: PROCESS_ENV.send_email_config.FOW_ADMIN_RECEIVER_EMAIL
}
}
IMPORTANT!!!!
for this to work you have to deploy functions.config().env with the values of the env.json file
to deploy functions.config().env you just have to run INSIDE the functions FOLDER the next command: firebase functions:config:set env="$(cat env.json)"
and also don't forget to add env.json in your .gitignore
if you have firebase functions FOLDER inside your react project just add */env.json into your react .gitignore file
your .env file need to be in the "functions" folder
Here you have the documentation about this
https://firebase.google.com/docs/functions/config-env
you can access variables like this :
This is your .env :
PLANET=Earth
AUDIENCE=Humans
and a firebase functions
// Responds with "Hello Earth and Humans"
exports.hello = functions.https.onRequest((request, response) => {
response.send(`Hello ${process.env.PLANET} and ${process.env.AUDIENCE}`);
});
For your local environment you can have a .env.local file and the contents of .env.local take precedence over .env when you are using the emulators suite

firebase-functions:hosting gives error: time to go build something extraordinary

I can deploy files through only hosting which works fine
but I try it with firebase functions it says :
Welcome
Firebase Hosting Setup Complete
You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something extraordinary!
OPEN HOSTING DOCUMENTATION
my index.js Code goes here :-
const functions = require('firebase-functions');
// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
link to my project:-
https://influence-cbc3f.firebaseapp.com/
If you want to deploy functions then use this:
firebase deploy --only functions
more info here:
https://firebase.google.com/docs/functions/get-started
If you're using Angular 6, instead of providing "dist" at the following step:
? what do you want to use as public directory
You will need to provide “dist/your_application_name”
Check out this excellent article
https://medium.com/#longboardcreator/deploying-angular-6-applications-to-firebase-hosting-b5dacde9c772

Google Cloud Functions, Node JS 8.9.x (LTS) and KOA library

How can I use Koa library, the express replacement, in Cloud Functions?
I know KOA use all great ES2017 and make more use of Async use of JavaScript.
or it might not be needed at all working with Cloud Functions because the Firebase system won't send multiple calls to the same Cloud Function until it ends the previous one?
it unclear to me.
it know demands Node 8.x and I know the NodeJs 8.9.x, has now LTS.
Reading from cloud functions doc:
Base Image Cloud Functions uses a Debian-based execution environment
and includes contents of the gcr.io/google-appengine/nodejs Docker
image, with the Node.js runtime installed in the version, specified
above:
FROM gcr.io/google-appengine/nodejs
RUN install_node v6.14.0
To see what is included in the image, you can check its GitHub
project, or pull and inspect the image itself. Updates to the language
runtime (Node.js) are generally done automatically (unless otherwise
notified), and include any changes in the definition of the base
image.
And I saw a pull request back in November 2017, adding Nodejs v8. Here's hoping it can finally land in Google Cloud Functions 🤞🏻
UPDATE: Google Cloud Functions now support Node.js 8 and even Python!
Referring to the release notes from Google... Cloud Functions Release Notes
Node version supported is still at v6, same for firebase. You need to wait awhile before they release it in v8. Am pretty sure they will move to v8 when v6 no longer supported, but hopefully earlier...
Use babel:
index.js:
----------=
'use strict';
require('#babel/register')
require('babel-polyfill')
const http = require('http')
const createApp = require('./app/app.js')
const handle = createApp().callback()
if (process.env.IS_LOCAL_DEPLOYMENT) {
// to use same code in local server
http.createServer(handle).listen(3000)
} else {
module.exports.http = (request, response) => {
handle(request, response)
};
}
app.js:
--------
'use strict';
const Koa = require('koa')
module.exports = () => {
const app = new Koa()
app.use(......)
return app
}
package.json
------------
"scripts": {
.
.
"start": "export IS_LOCAL_DEPLOYMENT=true && node index"
.
.
}
I just saw in Cloud Functions Console editor for one of my functions that Node 8 is now a runtime option. See screenshot:

Resources