Serving Firebase Functions doesn't hot reload on Windows - firebase

Serving Firebase Functions locally with the firebase serve command is supposed to enable hot reloading but this doesn't seem to work on windows, even with watchman installed. Is there a better solution aside from running npm build after each code change?

I mixed the 2 answers:
"scripts": {
"serve": "npm run build -- --watch | firebase emulators:start --only functions",
...
}

I do it the following way (additionally to galki`s answer):
firebase serve --only functions
and in another terminal tab I just use
npm run build -- --watch
from within functions directory. This way you have some kind of faster dev cycle.

To enable hot reloading on firebase functions with typescript you can add this 2 commands to your package.json file
"build:watch": "tsc -w"
"serve:watch": "npm run build:watch | firebase emulators:start --only functions",
If you want also to use path aliases feature you will be required to install 2 additional dev packages in order to make it work
npm install --save-dev tsc-alias concurrently
tsc-alias is for replacing alias paths with relative paths after typescript compilation of tsc compiler because the compiler alone can't resolve the alias paths
concurrently is for runing multiple commands concurrently
After installing the 2 packages you will need to add this 2 scripts to your package.json file
"build:watch": "concurrently --kill-others \"tsc -w\" \"tsc-alias -w\"",
"serve:watch": "npm run build:watch | firebase emulators:start --only functions",
Starting of development with hot reload then will be as easy as running only in the terminal
npm run serve:watch
Please Note:
I am using this versions of the packages
"firebase-admin": "^10.0.1",
"firebase-functions": "^3.14.1",
"tsc-alias": "^1.5.0",
"typescript": "^4.5.5",
"concurrently": "^7.0.0",
Older or newer versions might introduce some issues with compiling the code

Try following npm script
"serve": "./node_modules/.bin/tsc --watch | firebase serve --only functions"

It works as of the current point in time (firebase-tools 8.0.0).
Both
firebase serve --only functions
and
firebase emulators:start --only functions
work but one still needs to run npm run build manually each time.

Related

Firebase emulators:exec with 'npm test' script returns immediately

I'm running some React integration tests with npm, and need the Firebase emulator for them. I've set up my npm scripts as follows:
"scripts": {
"test:integration:runner": "cross-env RTL_SKIP_AUTO_CLEANUP=true FIREBASE_DATABASE_EMULATOR_HOST=\"localhost:9000\" FIREBASE_FUNCTIONS_EMULATOR_HOST=\"localhost:5001\" FIREBASE_AUTH_EMULATOR_HOST=\"localhost:9099\" react-scripts test ./src/integrationTests/App.spec.js --watchAll=false",
"test:integration": "firebase emulators:exec 'npm run test:integration:runner'",
},
However, when I run npm run test:integration, the script returns after about 1 second, with no errors. Here is the only ouput:
PS C:\Users\{userame}\{project}> npm run test:integration
> {project_name} test:integration
> firebase emulators:exec 'npm run test:integration:runner'
PS C:\Users\{userame}\{project}>
The firebase emulator itself is working if I run it standalone, and I tested the integration test with the emulator already running, and that works as well. I tried running firebase emulators:exec with a different non-npm script (instead of npm run test:integration:runner) and it successfully spun up the emulator. Any idea what might be happening here?
Well, I figured this out soon after asking the question. It turns out you need to double quote the script.
So I changed
"test:integration": "firebase emulators:exec 'npm run test:integration:runner'",
to
"test:integration": "firebase emulators:exec \"npm run test:integration:runner\" ",
I'd like to understand why this works though. This is in Windows, and I'm not sure how single/double quote semantics in commands might differ from what I'm used to.

Unable to deploy firebase cloud functions to any firebase project from my machine (but it works perfectly fine on my colleague's machine)

This is my mac-mini M1 configuration and I'm trying to deploy firebase functions but it is not allowing me to deploy and every time shows me this error.
When I run this command it throws an error :
me#-Mac-mini demo % firebase deploy --only functions:helloWorld
=== Deploying to 'demo'...
i deploying functions
Running command: npm --prefix "$RESOURCE_DIR" run build
> build
> tsc
✔ functions: Finished running predeploy script.
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
✔ functions: required API cloudfunctions.googleapis.com is enabled
✔ functions: required API cloudbuild.googleapis.com is enabled
i functions: preparing codebase default for deployment
i functions: preparing functions directory for uploading...
i functions: packaged /Users/me/Documents/work/workspace/demo/functions (56.87 KB) for uploading
✔ functions: functions folder uploaded successfully
i functions: creating Node.js 16 function helloWorld(us-central1)...
⚠ functions: failed to create function projects/demo/locations/us-central1/functions/helloWorld
Failed to create function projects/demo/locations/us-central1/functions/helloWorld
Functions deploy had errors with the following functions:
helloWorld(us-central1)
i functions: cleaning up build files...
⚠ functions: Unhandled error cleaning up build images. This could result in a small monthly bill if not corrected. You can attempt to delete these images by redeploying or you can delete them manually at https://console.cloud.google.com/artifacts/docker/demo/us-central1/gcf-artifacts
Error: There was an error deploying functions
The actual log of the error :
{"#type":"type.googleapis.com/google.cloud.audit.AuditLog","status":{"code":7,"message":"Cloud Functions uses Artifact Registry to store function docker images. Artifact Registry API is not enabled in your project. To enable the API, use the gcloud command 'gcloud services enable artifactregistry.googleapis.com' then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry."}
Other versions info :
NPM version : 8.11.0
Firebase version : 11.2.0
Node version : 16.15.1
Firebase package.json
{
"name": "functions",
"scripts": {
"build": "tsc",
"build:watch": "tsc --watch",
"serve": "npm run build && firebase emulators:start --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "16"
},
"main": "lib/index.js",
"dependencies": {
"firebase-admin": "^10.2.0",
"firebase-functions": "^3.21.0"
},
"devDependencies": {
"typescript": "^4.6.4"
},
"private": true
}
Deploying from MacBook-pro-2014
Deploying from Mac-mini-m1
Why I am unable to deploy cloud functions from my machine and why is my colleague able to deploy the same cloud functions to same Firebase project from his machine even without enabling Artifacts Registry?
The Artifact Registry API is not enabled in your project.
The solution requires that billing is enabled for your project.
Provided that the CLI has permission to enable services, run this command:
gcloud services enable artifactregistry.googleapis.com
Or use the Google Cloud Console UI
More information is available in the Artifact Registry Documentation:
Enabling and disabling the service
Artifact Registry pricing

Firebase hosting doesn't let me deploy bc firebase-functions is outdated

functions: package.json indicates an outdated version of firebase-functions.
Please upgrade using npm install --save firebase-functions#latest in your functions directory.
=== Deploying to 'zootopia-mysite'...
i deploying functions, hosting
Running command: npm --prefix "$RESOURCE_DIR" run lint
> functions# lint /Users/zootopia/functions
> eslint .
✔ functions: Finished running predeploy script.
Error: There was an error reading functions/package.json:
Engines field is required but was not found in functions/package.json.
To fix this, add the following lines to your package.json:
"engines": {
"node": "10"
}
I've also tried to upgrade with npm install --save firebase-functions#latest and it still gives me the same error.
Your local project apparently works with both Firebase Hosting and Cloud Functions. The error message is telling you that the Cloud Functions deployment is failing, which doesn't have anything do with Firebase Hosting yet.
If you are trying to follow the advice of the output here, you're going to have to change to the "functions" folder and run the npm commands to upgrade the old modules and make any other changes to package.json.

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 functions fails to deploy with same error in all functions

I'm trying to deploy my firebase functions but all the functions return me error, I had already deployed before without any error.
I did not install anything new since the last time that a deploy was correct.
Every functions return almost the same error, the only thing that changes is the "errorId"
I have tried to logout from firebase-cli and login again, i have updated firebase-tools, firebase-admin, firebase-functions from npm.
I'm deploying with firebase deploy --only functions
Deployment error.
Build failed:
{
"error": {
"canonicalCode": "INVALID_ARGUMENT",
"errorMessage": "`npm_install` had stderr output:\nnpm WARN tar ENOENT: no such file or directory, open '/workspace/node_modules/.staging/#types/lodash-973f4ada/common/collection.d.ts'\nnpm WARN tar ENOENT: no such file or directory, open '/workspace/node_modules/.staging/#types/node-29231f2f/inspector.d.ts'\nnpm WARN tar ENOENT: no such file or directory, open '/workspace/node_modules/.staging/#types/node-f1c8db24/inspector.d.ts'\nnpm WARN tar ENOENT: no such file or directory, open '/workspace/node_modules/.staging/#firebase/auth-1b85ce5b/dist/auth.esm.js.map'\nnpm WARN tar ENOENT: no such file or directory, open '/workspace/node_modules/.staging/#firebase/webchannel-wrapper-e6854ec7/dist/index.js'\nnpm ERR! code E404\nnpm ERR! 404 Not Found: grpc#1.20.1\n\nnpm ERR! A complete log of this run can be found in:\nnpm ERR! /builder/home/.npm/_logs/2019-06-08T18_16_17_266Z-debug.log\n\nerror: `npm_install` returned code: 1",
"errorType": "InternalError",
"errorId": "FD2536C1"
}
}
Package.json :
{
"name": "functions",
"engines": {
"node": "8"
},
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"dependencies": {
"#firebase/storage": "^0.2.16",
"#google-cloud/vision": "^0.24.0",
"#sendgrid/mail": "^6.4.0",
"cors": "^2.8.5",
"dateformat": "^3.0.3",
"firebase": "^5.11.1",
"firebase-admin": "^7.4.0",
"firebase-functions": "^2.3.1",
"json2csv": "^4.5.1",
"mailchimp-api-v3": "^1.13.0",
"moment-timezone": "^0.5.25",
"openpay": "^1.0.3",
"paypal-rest-sdk": "^1.8.1",
"request": "^2.88.0"
},
"devDependencies": {
"eslint": "^4.12.0",
"eslint-plugin-promise": "^3.6.0",
"firebase-functions-test": "^0.1.6"
},
"private": true
}
Correct deploy of the functions.
Update***
I have tried to delete everything and uninstall every package except for the ones required for firebase-functions and start over with one test function in node 8 i'm having the same issue, with node 6 it was deployed, but i need to use node 8 because i need to use await/async
I had a similar deployment failure. I think it was caused by me running firebase deploy from the app directory rather the the app\functions directory. In any case, I ran the following commands from the terminal (using VSCode in my case) having changed into the app\functions directory. Deployment then worked perfectly.
npm install --save #google-cloud/storage
npm install --save firebase-admin#latest
npm install --save firebase-functions#latest
firebase deploy
Hope that helps.
Checking the log
You can examine the actual logs by using this command to open the log
firebase functions:log
Doing this is really helpful since specific issue will usually be visible there. I sometimes even had error as simple as a missing package name in package.json
It would have been much helpful if firebase could show better info on the errors directly. but at least we can find them here.
I hope it helps
I had similar issue and it ended up being a missing module in my package.json
You can view more detailed / useful logs here: https://console.cloud.google.com/logs
Firebase functions:log really helps! In my case I had not enabled signin method in the firebase project (:

Resources