How do I deploy Cloud Functions while ignoring existing functions? - firebase

Say I have the following four functions in my Firebase projects:
openDoor(europe-west1)
closeDoor(europe-west1)
openWindow(europe-west1)
closeWindow(europe-west1)
Now, these functions live in two separate Node packages, i.e. one that contains openDoor and closeDoor and another one that contains openWindow and closeWindow.
Error
If I try to run firebase deploy from the package with the door functions, the following error will be thrown (in non-interactive mode):
Error: The following functions are found in your project but do not exist in your local source code:
openWindow(europe-west1)
closeWindow(europe-west1)
This is a problem because it will cancel any CD workflow that tries to deploy these functions.
Force delete
There is an option to force-delete any existing functions:
-f, --force delete Cloud Functions missing from the current
working directory without confirmation
However, I want the opposite. I want to keep all existing functions.
Theoretical workaround
There is one workaround that I found would work in theory, which is:
yes N | firebase deploy --interactive
Piping N into the interactive deploy command, which will answer N to the deletion prompt:
The following functions are found in your project but do not exist in your local source code:
openWindow(europe-west1)
closeWindow(europe-west1)
If you are renaming a function or changing its region, it is recommended that you create the new function first before deleting the old one to prevent event loss. For more info, visit https://firebase.google.com/docs/functions/manage-functions#modify
? Would you like to proceed with deletion? Selecting no will continue the rest of the deployments. (y/N)
The problem now is that I am using https://github.com/w9jds/firebase-action to deploy the functions, which means that I need to have a built-in Firebase solution.

You can make use of the new codebases feature in Firebase.
By specifying a codebase in your firebase.json functions configuration, this problem is solved. The Firebase CLI will no longer prompt you to delete other functions as it only considers the functions of the same codebase.
If your firebase.json previously looked like this:
{
"functions": {
"source": "cloud_functions",
"ignore": [...],
"predeploy": [...],
"postdeploy": [...]
}
}
You only need to add "codebase": "<name>" to the config:
{
"functions": {
"source": "cloud_functions",
"codebase": "window",
"ignore": [...],
"predeploy": [...],
"postdeploy": [...]
}
}
The deploy will now look like this:
i functions: updating Node.js 16 function window:openWindow(europe-west1)...
i functions: updating Node.js 16 function window:closeWindow(europe-west1)...
Note that the actual function name does not change, i.e. the function will still only be called openWindow (without the prefix) in the Firebase / Google Cloud Console. So this is basically the perfect solution to the problem.

Alternatively, you can also specify the function names when performing deployment.
firebase deploy --only functions:openDoor,functions:closeDoor

Related

Firebase functions: RangeError [ERR_FS_FILE_TOO_LARGE]: File ... is greater than 2 GB

Been deploying a ton w/ no problems. Made a small change and now it bonks on deploy.
I rolled back a few commits and still get same error. Tried deploying only 1 function, same issue. Deleted a bunch of log files, etc. Same.
Quotas all look fine.
There's about 20 functions in the project.
i functions: Loaded environment variables from .env.
i functions: preparing functions directory for uploading...
[2023-01-17T07:51:09.242Z] RangeError [ERR_FS_FILE_TOO_LARGE]: File size (5067767843) is greater than 2 GB
at new NodeError (node:internal/errors:372:5)
at readFileHandle (node:internal/fs/promises:377:11)
at async getSourceHash (/Users/adrian/.nvm/versions/node/v16.16.0/lib/node_modules/firebase-tools/lib/deploy/functions/cache/hash.js:12:18)
at async packageSource (/Users/adrian/.nvm/versions/node/v16.16.0/lib/node_modules/firebase-tools/lib/deploy/functions/prepareFunctionsUpload.js:61:30)
at async prepare (/Users/adrian/.nvm/versions/node/v16.16.0/lib/node_modules/firebase-tools/lib/deploy/functions/prepare.js:131:36)
at async chain (/Users/adrian/.nvm/versions/node/v16.16.0/lib/node_modules/firebase-tools/lib/deploy/index.js:35:9)
at async deploy (/Users/adrian/.nvm/versions/node/v16.16.0/lib/node_modules/firebase-tools/lib/deploy/index.js:79:5)
Error: Could not read source directory. Remove links and shortcuts and try again.
What file is it referring to?
Appreciate any ideas.
A new type of log file had been generated which didn't match the current ignore pattern in firebase.json. So the log file was being processed during deploy.
Solution: update ignore pattern to cover any .log files
firebase.json
...
"functions": [
{
"source": "functions",
"codebase": "default",
"ignore": ["node_modules", ".git", "*.log"]
}
]
...

Firebase CLI suddenly ignoring environment variables on Functions deployment

I have a Firebase code project with Functions meant to be deployed to multiple Firebase projects over multiple regions.
I used to set the deployment region like this:
return functions
.region(process.env.REGION)
// ...
and used this command to deploy:
$ REGION=us-central1 firebase deploy --only functions
it worked like a charm until recently. Now it seems to completely ignore REGION=us-central1 even if I export it before I run firebase deploy.
EDIT 2022-06-13 - Possible solution
I changed the code to dump the contents of process.env to a file during deployment. This is what I got:
{
"FIREBASE_CONFIG": "{\"projectId\":\"REDACTED\",\"storageBucket\":\"REDACTED.appspot.com\",\"locationId\":\"us-central\"}",
"GCLOUD_PROJECT": "REDACTED",
"CLOUD_RUNTIME_CONFIG": "{REDACTED}",
"__CF_USER_TEXT_ENCODING": "REDACTED"
}
so definitely is not the same list of variables I have in my local environment.
I could use the locationId from FIREBASE_CONFIG to get the target location, or CLOUD_RUNTIME_CONFIG (it contains the dump of the functions .config() object, so I could set the target there).
I also believe that I could use the .env and .env.{project alias or ID} files and their contents would be available in process.env at deployment time.
As per Osvaldo López's suggestion, here are some other details:
Running on MacOS
No errors are reported
No recent changes to the CLI
Any input would be very welcome! Thanks.

Firebase CLI: the following filters were specified but do not match any functions in the project

I use Firebase Cloud Functions in my project, and I have a plenty of them so when I run the regular firebase deploy I exceed the quota, so one option is to deploy only the function that was modified by using firebase deploy --only functions:function1 as mentioned in this web page. This method works only with functions that start with: exports.funcName but when I try to use it with a function like this:
function doesNotStartWithExports() {
// Does something.
}
It doesn't work. I use firebase deploy --only functions:doesNotStartWithExports but I get this output:
⚠ functions: the following filters were specified but do not match any functions in the project: doesNotStartWithExports
The Question: How to deploy Firebase functions that does not start with exports?
I faced a very similar error while trying to delete some deprecated functions:
firebase functions:delete mymodule-helloWorld --region us-central1
Output:
Error: The specified filters do not match any existing functions in project my-firebase-project.
Turns out that if I replace the '-' in namespaced/grouped (module) functions with '.', the error goes away. Weird.
firebase functions:delete mymodule.helloWorld --region us-central1
Output:
? You are about to delete the following Cloud Functions:
mymodule-helloWorld(us-central1)
Are you sure? Yes
i functions: deleting function mymodule-helloWorld(us-central1)...
✔ functions[mymodule-helloWorld(us-central1)]: Successful delete operation.
The solution is adapted from this github thread
I actually found the solution, and it's by deploying one of the function that starts with exports and uses the function that doesn't start with exports, for example:
function doesNotStartWithExports() {
// I want to deploy only this function but I can't
}
exports.anotherFunction = functions.https.onRequest((request, response) => {
// This functions uses the one that I want to deploy.
doesNotStartWithExports()
})
To update doesNotStartWithExports I use this command:
firebase deploy --only functions:anotherFunction.
I also found that if you have a regular function exported somewhere with the same name as the Firestore function you will get this error:
export myFunction() {
// do somethig here
}
exports.myFunction = functions.https.onCall((data, context) => {
// function
})
renaming either of them to a unique name will solve the issue.
This works:
But this does not work (extra lines preceding function)

Firebase cannot understand what targets to deploy

When deploying the following hello-world equivalent code I get the error shown in the end:-
$ ls -lR
.:
total 8
-rw-r--r-- 1 hgarg hgarg 3 Aug 29 14:55 firebase.json
drwxr-xr-x 2 hgarg hgarg 4096 Aug 29 11:56 functions
./functions:
total 4
-rw-r--r-- 1 hgarg hgarg 1678 Aug 29 11:56 index.js
firebase.json looks like this:-
{}
and index.json like this:-
'use strict';
const functions = require('firebase-functions');
exports.search = functions.https.onRequest((req, res) => {
if (req.method === 'PUT') {
res.status(403).send('Forbidden!');
}
var category = 'Category';
console.log('Sending category', category);
res.status(200).send(category);
});
But deploying fails:-
$ firebase deploy
Error: Cannot understand what targets to deploy. Check that you specified valid targets if you used the --only or --except flag. Otherwise, check your firebase.json to ensure that your project is initialized for the desired features.
$ firebase deploy --only functions
Error: Cannot understand what targets to deploy. Check that you specified valid targets if you used the --only or --except flag. Otherwise, check your firebase.json to ensure that your project is initialized for the desired features.
it would be better to pre-populate the firebase with the default options. I choose that I wanted to use only hosting the firebase.json should have be created with the default hosting option.
{
"hosting": {
"public": "public"
}
}
or you try run firebase init again.
Faced similar issue. In firebase.json file (in hosting parameter), we have to give the name of directory that we want to deploy (in my case, I was already in the directory, which I wanted to deploy, hence I put "." in hosting specification). It solved the error for me.
{
"hosting": {
"public": ".",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}
I was facing this issue when running:
firebase emulators:exec --only firestore 'npm tst'
The problem was that on firebase.json must have a property for the emulator you want. So in my case I added a "firestore": {} on firebase.json and worked.
I faced this problem too because at the beginning of my Firebase project setup, I only initialized the hosting feature. Later on, when I wanted to deploy firestore security rules with the Firebase CLI, my initialization process was not complete for this command to work as expected.
I could not run firebase deploy --only firestore:rules
because my firebase.json file was not initialized with defaults.
Easiest and most adequate way to fix this problem is to run the firebase init command again to setup all features you want to use. You could do it manually but you could miss details that the command line interface can setup for you in the exact way it needs to be for defaults.
Solution:
Run the firebase init command again
...and make sure to initialize every feature you are currently using. Take care not to overwrite important configs if you already have some by carefully reading the Firebase CLI instructions that are asked by the init command.
Firebase reads package.json to read details of the functions target. This file was missing from my project directory, as I had moved files around after doing an init.
Creating a clean directory and doing a firebase init functions inside it created all the required files and folders to get started.
I think you are missing on one of the following things -
a) you should run firebase init outside of the main project where index.html is.
b) select hosting option after running firebase init by pressing SPACE
c) Please give folder name which contain index.html in it.
And your project will be up running.

Firebase cloud function deploy error

irregularly my firebase deployment get stuck at this log:
i functions: updating function [FUNCTION NAME]...
After canceling the deploy and retrying it throws the following error message:
⚠ functions: failed to update function resetBadgeCount
⚠ functions: HTTP Error: 400, An operation on function [FUNCTION NAME]
in region us-central1 in project [PROJECT NAME] is already in progress.
Please try again later.
So it seams like that the deploy got stuck and kept in the pipeline blocking further deploys. After a while it let me deploy the functions normally again.
But is there an explanation for this? Or maybe even a word around?
Go to Google cloud functions console and see if there is red exclamation mark against your function. Then select that particular function and try to delete. once it gets deleted from there, you can deploy again successfully. if it is showing spinner, then wait till it shows red mark.
Try this
You can fix the issue much easier by examining the actual logs using this command to open the log
firebase functions:log
The specific issue will be visible there. I sometimes even had errors as simple as a missing package in package.json
You can temporarily rename your function:
$ firebase deploy --only functions
...
i functions: deleting function onSameDataChanged...
i functions: creating function onSameDataChanged1...
...
✔ functions: all functions deployed successfully!
✔ Deploy complete!
Comment or cut your function
Deploy
Uncomment or paste back the function
Rename the function
Deploy
Rename the function back
Deploy
also you can wait a few minutes and you will get an error with {"code":10,"message":"ABORTED"}, then you can deploy again.
just copy your index.js to some where else and delete function form firebasa function console
firebase init -and overe write all file again
past index.js text again
deploy...
For me it was the node version. Turns out I had the 15.x on my machine and the 12.x on the server. Just updating it solved my upload issue
Make sure you've installed dependencies in the functions directory.
for more information about you function you can go to this page
Set your directory to your project directory \functions then run this command:
npm install -g firebase-tools

Resources