Cloud Functions for Firebase Async Await style - firebase

Looks like Cloud Functions does not support Async-Await notation. Is there a way I could use Babel until they do or is it recommended to use promises?
My current function that sits on Node is like so:
exports.getToken = async (req, res) => {
//1. Generate token from Braintree
const result = await gateway.clientToken.generate();
//2. Return the client token
res.json(result.clientToken);
};

Cloud Functions runs the LTS version of node.js, which according to the documentation is 6.14.0 at this moment in time. node 6.x supports EcmaScript 6, which does not include async/await.
However, you can write your code in TypeScript and have that transpiled down to ES5/ES6, which will effectively convert the use of async/await into promises. A web search suggests that perhaps this plugin can be used to help Babel with similar transpiling.
It's worth noting that the Firebase CLI now allow you to initialize a new Cloud Functions project with native TypeScript support, which is what the Firebase team is currently recommending to developers.
If you don't want to use TypeScript, you can now also choose node 8 (which is currently in beta, and does support async/await for plain JavaScript) as a deployment target. You can follow the documentation to edit your package.json to indicates that your functions should be deployed to node 8.

Now you can use Node.js version 8 by adding this in your functions/package.json:
"engines": {
"node": "8"
}
Example: https://github.com/firebase/functions-samples/blob/Node-8/authenticated-json-api/functions/package.json

Instead of transpile TypeScript, I have transpiled my javascript after follow this very nice post and take a look at this repository
Basically you can do:
npm install -g #babel/cli #babel/core #babel/preset-env
UPDATE:
I'm having troubles with version "7.0.0-beta.51" of babel. "7.0.0-beta.44" still ok.
Switch to stable version 6
npm install --save-dev babel-cli babel-preset-env
Create the file .babelrc inside your project folder
{
"presets": [
["#babel/env", {
"targets": {
"node": "6.11.5"
}
}]
]
}
Move your "functions" folder to "firebaseFunctions" folder and then run
babel firebaseFunctions --out-dir functions --copy-files --ignore firebaseFunctions/node_modules
Or run this command for each files you want to transpile
babel originalfile.js --out-file transpiledfile.js

The above solutions didn't work for me alone. I had to update to the latest firebase tools:
npm update -g firebase-tools
and then update my package.json with adding:
"engines": {"node": "8"}
and everything worked fine with async/await.
Credits to this blog https://howtofirebase.com/cloud-functions-migrating-to-node-8-9640731a8acc

In your functions/.eslintrc.json file set as 'ecmaVersion': 2017
this will remove eslint syntax error
"parserOptions": {
"ecmaVersion": 2017
},
In your functions/package.json file set node version to 8 by adding below
"engines": {
"node": "8"
},
this will update the cloud node version to 8 default node version is 6

as #adam said, solved my problem to reinstall/upgrade the global firebase package
the difference is in my case was using NVM (node version manager).
Somehow, my default node(v13.x) had the firebase-tools but i didnt installed globally at project node (v10/8)
so first:
nvm use 10
then:
npm i -g firebase-tools
reinstalling at correct node version got my async functions working properly.

Related

Make Dokku stay on major version

On my package.json file I have the following below. As expected it is installing version 16.x but I would like it to only install the latest 12.x. Is there a way to setup the app to only do that?
"engines": {
"node": ">=12.19.0"
},
If I understand your question correctly, you should be able to just use 12.x in your package.json. (Heroku Docs/NPM Docs)
"engines": {
"node": "12.x"
}
You can use NPM's semver syntax to define supported versions. If you only want versions greater than 12.19.0 but still within 12.x, you can use ^12.19.0.

Deploying to Firebase Functions with a monorepo

As per Firebase Functions with Yarn workspaces, I'd like to deploy a monorepo to Firebase using Yarn Workspaces. I can successfully deploy the "web" aspect to Firebase Hosting, which references a shared "core" workspace. However, attempts to do the same with the "functions" workspace on Firebase Functions fails.
I'm using Yarn Workspaces with the following folder structure:
packages/
core/ // name: firebase-monorepo-core: custom core package
functions/ // name: firebase-monorepo-functions: firebase functions package
web/ // name: firebase-monorepo-web: react package
These have been configured in the root package.json file:
"workspaces": {
"packages": [
"packages/*"
],
"nohoist": [
"**/firebase-monorepo-core"
]
}
In an attempt to enable Yarn workspaces in Firebase (and therefore share my core package) I've used the nohoist feature to create symlinks to the core workspace in functions and web as per twiz's Stackoverflow answer.
The core package also exists as a dependency in functions and web:
"dependencies": {
"firebase-monorepo-core": "*"
}
There are no problems when any of this runs locally, and in fact deployment of the web package to Firebase hosting works fine. However, deployment of the functions package to Firebase functions throws an error:
I've created a Github repository https://github.com/cjmyles/firebase-monorepo to demonstrate this, and the resultant web workspace can be viewed at https://fir-monorepo.firebaseapp.com.
I can get the functions package to deploy if I yarn pack the core workspace and reference it as a tarball in the package.json file, but I really don't like that solution and it will require more overhead to automate it.
Any advice would be appreciated to resolve this issue.
The issue is that firebase-tools assumes that all packages used by your function are available in npm.
A quick solution is to use firelink.
cd ./packages/functions
yarn add -D #rxdi/firelink
Add an equivalent section to your functions package.json for all shared dependencies.
"fireDependencies": {
"#org/common": "../../packages/common"
},
Change your deploy script to use firelink binary
"scripts": {
"build": "tsc --build tsconfig.build.json",
"predeploy": "yarn build",
"deploy:functions": "firelink deploy --only functions"
}
Just a heads up does not work with "devDependencies", but you should not be needing them in production anyway.
Update your firebase.json to run the predeploy target.
"functions": {
"predeploy": ["npm --prefix \"$RESOURCE_DIR\" run predeploy"],
"source": "packages/functions"
},
Lastly remove any local yarn.lock files in the workspace package. If you wish to lock the dependencies add npm install to your predeploy step. If anyone has a better solution to this let me know. It seem unfortunate that yarn does not have the ability to generate lock files on demand in a workspace.
one potential solution is to use Lerna.
You can then publish your core package to a private GitHub package and use Lerna to create a symlink to the core package for local development.
I got this to work but it was a pain and hacky. So far it's working well though. I'm using NPM Workspaces, but the concept should apply to any project where node modules are hoisted to the root folder. I'm also using GitHub Workflows / Actions for CI and TypeScript, so all of this works within those environments.
Build my dependent packages using TypeScript's tsc
Copy the compiled files into the functions folder (functions/src/domain to be exact) so that they get uploaded by Firebase CLI
cp -r packages/domain firebase/functions/src/domain
Insert local dependency inside functions/package.json. I'm doing it with sed, which GitHub actions supports:
sed -i 's/"dependencies": {/"dependencies": { "#mycompany\/domain": "file:src\/domain",/' package.json
Before that command, my package.json looks like this:
"dependencies": {
"lodash": "^4.17.20",
...
After that command, it looks like this:
"dependencies": { "#mycompany/domain": "file:src/domain",
"lodash": "^4.17.20",
...
Then deploy: firebase deploy --only functions
Not pretty, but it works with full automation. 😁

Firebase cloud functions node 8 engines fix

When I run firebase serve there is a warning message: You're using Node.js v8.12.0 but Google Cloud Functions only supports v6.11.5. but I already declared "engines": { "node": "8" }, on my functions/package.json file. And I'm using latest firebase-tools version 5. Any idea how to fix?
That's just a warning, and there is no "fix" for it. It's incorrect, but you can just ignore it. File a bug report if you feel strongly about it.

Error: Functions did not deploy properly

Functions deploy had errors. To continue deploying other features (such as database), run:
firebase deploy --except functions
Error:
Functions did not deploy properly.
Try running deploy with --debug. For example: firebase --debug deploy.
In my case the function looked like this:
exports.test = functions.firestore.document('chats').onCreate((snap, context) => {
...
});
The debug log contained the following error message:
fieldViolations=[field=event_trigger, description=Expected value chats to match regular expression [^/]+/[^/]+(/[^/]+/[^/]+)*]]
And that's when I realized that chats is not a document but a collection. I changed the path to that of the collection and everything worked fine.
EDIT:
To view more logs you can also try:
firebase functions:log
or
firebase functions:log --only <FUNCTION_NAME>
Link to documentation.
I had the same issue with Firestore ,my problem was that the path to the document was bad. I had a slash at the beginning and the end of the path to my document like I used to do with Firebase Realtime Database path.
Hope it helps someone.
Just close whatever IDE you're using and then reopen it. Then on node redeploy your functions. This should resolve the issue.
I got this error as well, I had the problem that a dependency was missing in the package.json file.
By running
firebase --debug deploy it returned an error on the user code.
firebase functions:log gave then the specifics, that a package was not included.
I deleted yarn.lock then error goes away. I think package-lock.json and yarn.lock should not exist together.
Check your json modules dependencies inside functions folder.
There's an specific json package there.
If some module you are including in the project and is not there (in json) you probably will have the error mentioned.
To install just run:
npm install <module> --save
or
yarn add <module> --save
and then run your deploy again:
firebase deploy --only functions
In my case firebase deploy failed with the error "Error: Functions did not deploy properly." and no further explanation. I noticed that no functions could be deployed even the ones I didn't touch.
So I checked for dependencies and I found that a library was not present in the "package.json".
So I execute this command:
cd functions && rm -rf node_modules && rm package-lock.json && npm install && npm install [specific Librairy not in package.json] && firebase deploy
After that the deployment succeeded and the missing dependency appeared in the package.json
Recently Firebase lets you use Functions only if you have the Blaze-Pay as you go plan. So you cannot deploy functions as well, and you will get this same error message without any further clarifications.
Mine was about;
"Function deployment failed because the billing account is not available."
So I had pending payment, after paying, it worked as expected.
I was running into the same generic error message, and ended up running (as mentioned in this question):
firebase --debug deploy --only functions:[functionName]
This revealed the actual issue (my project did not have a default GCP resource location, fix for this described here: Firebase Project Initialization Error: Cloud resource location is not set for this project)
Once I set the GCP resource location, function deployed without issue!
In my case, After a long time of searching, I found the reason to be that I had disabled billing for the project for debugging.
It worked fine now after I enabled it in the Google cloud console.
It's really sad how firebase can't show any useful error message to suggest the problem. I found this after many trials.
I faced a similar problem, but I was using Typescript.
It was basically targeting a non-supported javascript version (ES2020). I changed the tsconfig.json and it deployed normally
"lib": [
"es2019",
"es2020.bigint",
"es2020.string",
"es2020.symbol.wellknown"
],
"module": "commonjs",
"target": "es2019"
After getting the above deploy error, I edited the index.js file and changed the name of the function from "helloWorld" to "heyWorld" and suddenly the firebase deploy command worked.
If anyone gets here trying to deploy ssr functions in angular universal with firebase, it is because firebase is not included in your functions.
1.) cd functions
2.) npm i firebase#latest
3.) npm run deploy
4.) cd ..
5.) now when you run ng deploy it should work correctly... The key here is to add firebase, and deploy with npm run deploy first...
try to add this
"runtime": "nodejs12"
in your firebase,json
example :
"functions": {
"source": ".",
"ignore": [
".firebase/**",
"**/node_modules/**",
"**/public/**",
".firebaserc",
"firebase.json",
"postcss.config.js",
"README.md",
"tailwind.config.js"
],
"runtime": "nodejs12"
}
was with the same error, I ended up solving it by updating package.json
from:
"engines": {
"node": "12"
},
to:
"engines": {
"node": "14"
},
$ in path causes Error: Functions did not deploy properly.
before:
`export const newMessage = functions.firestore.document('chats/${chatId}/messages/${messageId}').onCreate(handleNewMessage())`
after:
`export const newMessage = functions.firestore.document('chats/{chatId}/messages/{messageId}').onCreate(handleNewMessage())`
In my case, the location for the Firestore was not correctly set. From the Functions Documentation:
By default, functions run in the us-central1 region.
In my case, Firestore was set up on a different location. You can find this under Project Settings, at Default GCP resource location.
To fix it, simply make the following change:
// Before
functions.firestore.document("...").onCreate(...)
// After
functions.region("asia-east2").firestore.document("...").onCreate(...)
Follow the steps below:
Deploy with debug enabled:
firebase --debug deploy
You will see the error printed in your console.
In most cases it is something similar to the line below:
npm install before continuing.\nnpm ERR! \nnpm ERR! \nnpm ERR! Invalid: lock file's body-parser#1.19.0 does not satisfy body-parser#~1.0.1\nnpm ERR!
If the error is similar to "lock file's body-parse" in 1) above:
Go to the views directory in your project and edit the dependencies section in your package.json file as below:
Change the body-parser version to the latest version shown in the error printed in 1) above. In my case it was from body-parser#~1.0.1 to body-parser#~1.19.0
Run: npm install
Re-deploy with: firebase deploy
This should work.
If you get a 403 error from your hosting URL after re-deploying, your CLI version could be out of date:
Login to you google cloud account and go your the google cloud console.
Delete your Cloud Functions
Update Firebase CLI using: npm install -g firebase-tools
Re-deploy: firebase deploy
My firebase couldnt find the modules firebase-functions and firebase-admin on deploy because I wrote them in devDependencies instead of just dependencies. But after it ... I still had an issue. But this solved it for me: https://github.com/nuxt/nuxt.js/issues/2714#issuecomment-423048343.
Just notice node 8 as engine object in your function's folder package.json and add the babel snippet in your nuxt config.
I had same problem with Firebase project deployment. Then figure out error and find that some module paths are cause problem. Then i changed the path of that module.
To try redeploying those functions, run:
firebase deploy --only functions:api,functions:createScream
To continue deploying other features (such as database), run:
firebase deploy --except functions
Error: Functions did not deploy properly.
The error shows that could not find modules.
Did you list all required modules in the package.json dependencies?
Detailed stack trace: Error: Cannot find module (../key/your secret key.json) '
Then i changed the path of my secret key that is required for login credentials and put it in different folder. Then run firebase deploy.
That work for me.
I had the same problem. The problem came from the fact that I had an index.js file and package.json file in the root folder and, after running the firebase functions init command, also an index.js and package.json in the functions folder. The dependencies are only listed in the package.json file in the root folder, not in the functions folder. I copied the dependencies to the package.json file in the functions folders and everything worked like a charm.
Deleting the build functions folder worked to me
firebase functions:log
This allowed me to find out the problem in my case: one of the packages was not listed among the dependencies in package.json
This worked for me today: Delete Function and Redeploy.
It happened the same to me but unfortunately I had not any error with --debug.
I then deleted all my deployed functions in the firebase console and
cd functions
rm -rf node_modules
npm install
firebase deploy --only functions
and it worked like magic.
I got the same error
Functions were working in emulator, but couldn't be deployed.
When I deployed functions using debug, I got no more specific info.
Then I found out, that my IDE accidentally imported lib (that I wasn't even using) from parent folder where is my Svelte project located.
Removing that import fixed my error, obviously.
I deleted the recently added 3rd party library (from package/package-lock.json as well). And checked the name of the function to not be a duplicate.
This worked for me.
If u are using SSR you need declare your node version In my case my node version is 14 and firebase was deploying with 10.0 I set this config on angular.json
"functionsNodeVersion": 14
"serve-ssr": {
"builder": "#nguniversal/builders:ssr-dev-server",
"options": {
"browserTarget": "Rioja-web:build",
"serverTarget": "Rioja-web:server"
},
"configurations": {
"production": {
"browserTarget": "Rioja-web:build:production",
"serverTarget": "Rioja-web:server:production"
}
}
},
"prerender": {
"builder": "#nguniversal/builders:prerender",
"options": {
"browserTarget": "Rioja-web:build:production",
"serverTarget": "Rioja-web:server:production",
"routes": [
"/"
]
},
"configurations": {
"production": {}
}
},
"deploy": {
"builder": "#angular/fire:deploy",
"options": {
"ssr": true,
"functionsNodeVersion": 14
}
}
}
I had the same problem.
updating node engine to 16 in package.json solved the issue.
My nodejs local version was 16.
{
...
"engines": {
"node": "16"
},
"main": "lib/index.js",
"dependencies": { ... }
}

How to install NPM package from GitHub for Meteor?

I have forked an npm package on GitHub, made changes to it, and now want to install the package in my Meteor app directly from GitHub.
My package.json looks like so:
{
"dependencies": {
"semantic-ui-react": "git+https://git#github.com/nolandg/Semantic-UI-React.git",
}
}
I then run
meteor npm install
Which appears to work fine and tells me it's installed the package:
semantic-ui-react#0.61.6 (git+https://git#github.com/nolandg/Semantic-UI-React.git#f27d5c736e5de1eed0acf7769f18caee57578526)
And indeed the package appears in the node_modules folder. But when I try to start my Meteor app, I get this error:
Cannot set property '/my-website/node_modules/semantic-ui-react/package.json' of undefined
at Resolver._resolvePkgJsonMain (/tools/isobuild/resolver.js:320:9)
Has anyone successfully install an npm package in a Meteor app directly from GitHub? I can't figure this one out. Thanks!
Meteor version: 1.4.2.3
The main reason why the package does not work when fetching from git is because it is not configured to work that way. This is not a Meteor specific problem, but a problem that a JS developer may face sometimes.
For this particular case there are two problems:
The whitelist files field in package.json only contains src and dist folder. That means when you fetch it by npm almost all config files needed to build the code are gone.
Code for this package requies to be built in order to work with your code. This is done when the author publish it to npm, but you fetch it directly from github so this step is undone.
Because you already folked and modified the package, so let modify the package.json as below (remove all the comments I added them to give you some explanation), push it to github, and fetch it again by npm:
// remove the "files" field
// ...
"scripts": {
// this script is used to build the package
"postinstall": "postinstall-build dist \"npm run build:commonjs\""
// ...
},
"dependencies": {
// this helps build the package
"postinstall-build": "^2.1.3"
},
// ...
Packages are not usually installed from github, they are published, which means that many versions of a package are available, you can choose which one you get. I'm not sure if what you are doing is possible, but it's certainly inadvisable.
If you want to make changes to a github package, you can download the it to your local machine and do npm link, so that it uses your local package instead of the one on npm. Read more about it at https://docs.npmjs.com/cli/link
Why do you not use simple command?
meteor npm install https://github.com/nolandg/Semantic-UI-React.git
I did:
meteor create test
cd test
meteor npm install
meteor add react react-dom
meteor npm install https://github.com/nolandg/Semantic-UI-React.git
meteor
And no errors (-:

Resources