See continuous logging on command line - firebase

I am currently working on a Firebase function. As I am still in the development stage, I have a number of logs in my code to see what's going on.
async function getAddressByIdAsync(address) {
let addr = addressesRef.child(address);
console.log(addr);
return admin.database().ref('Addresses/' + address);
}
The only way I have found to be able to see these logs in real time is though the Firebase console, which is very slow and generally a bad UI experience IMO.
I'm looking for a command line solution that will let me see in real time the logs coming from the Firebase cloud function.
I have tried this command
firebase functions:log
Which appears to return the last twenty or so log entries into my Firebase Functions.
I know Google Cloud has a tail option on the end of that CLI but it doesn't work here.
firebase functions:log tail
Error: Too many arguments. Run firebase help functions:log for usage instructions
Is there a way to get a live running output of the logs from firebase cloud functions?

You can try the local emulator, that way you can first run your functions locally (and log in your terminal), before deploying.
https://firebase.google.com/docs/functions/local-emulator

Related

Environment variables are undefined when using Google Cloud Secret Manager in the Firebase Functions Emulator with --inspect-functions

I added Firebase Functions secrets via the CLI as described in the docs. The secrets are populated correctly in process.env both in deployed and emulated functions UNLESS the --inspect-functions flag is set. In that case, the secrets in process.env are undefined and no errors are displayed.
The issue only occurs when I run: firebase emulators:start --inspect-functions. Other notes:
I have the correct permissions set for the service account and there are no permissions errors.
I'm using .runWith correctly, since the same code works in the other environments. Here's how it's structured:
exports.functionName = functions
.runWith({secrets: ['SECRET_KEY', "SECRET_KEY_TEST"]})
.https.onCall(async (data, context) => {
// Code here.
});
There are no errors when the emulators start, which you'd expect if the configuration had a problem.
There is no mention of this being a limitation in the functions docs. The emulator docs mention the --inspect-functions flag causes a subtle behavior difference, but it doesn't seem relevant:
Note that when this flag is supplied, the Cloud Functions emulator
switches to a special serialized execution mode in which functions are
executed in a single process, in sequential (FIFO) order; this
simplifies function debugging, though the behavior differs from
multi-process, parallel execution of functions in the cloud.
I'm running firebase-tools version 10.7.0 on Windows 10. Thanks for any assistance figuring this one out!

Is it possible to auto-retry firebase cloud-function deploys when doing a full deploy?

I have a large amount of cloud functions (150+) that need to be deployed. When i run the following: firebase deploy --only functions to do a full deploy i get the following message:
⚠ functions: too many functions are being deployed, cannot poll status.
In a few minutes, you can check status at https://console.firebase.google.com/project/.../functions/logs
You can use the --only flag to deploy only a portion of your functions in the future.
✔ Deploy complete!
indicating that the deploy is in progress. The issue i have is that usually several functions fail to deploy due to quota limits or other non-code ralated issues, and these have to be retried/redeployed. When polling firebase will give the code to use to retry these, however, when not polling then no further console output is given. When i access the interface i am able to see which functions failed to deploy:
enter image description here
Is there an option either in the google interface to retry these, or some command option that can be added to the deploy command to auto-retry failed functions? Currently i have to manually gather all the failed function-names by manually looking trough the list and run a deploy specifying only those.
There is no such option to automatically retry. Maybe you could write code to scan the logs to figure out what failed and retry yourself. Alternatively, you could instead invoke the CLI once for each individual function at a controlled rate, and check the results individually.
What you have here sounds like a feature request, which you could post to the firebase-tools GitHub repo. You could also reach out to Firebase support to make your needs known.

Permission errors unit-testing Google Cloud Functions calling firestore db

I'm following the guide at https://firebase.google.com/docs/functions/unit-testing, but I always get " FirebaseError: Missing or insufficient permissions" when I run my test. I have the correct service-account.json file and I'm setting up firebase-functions-test with it (that part goes without error).
I've tried it with the emulator running (setting the FIRESTORE_EMULATOR_HOST var), and without it (which I assume uses live data) but I always get this error, as soon as my code under test does a db request such as:
data = await db().collection('/machines').get()
So my function under test is getting called, but it just can't do anything.
I also tried calling firebase.initializeApp() the same way I do in my front-end app, but that doesn't help, although without it I get the error telling me to call Firebase App.initializeApp().
firebase use is set to my current project.
I also tried running my test as firebase emulators:exec jest, no difference.
Any ideas?

Disable Cloud Functions for Firebase through Firebase dashboard (or cli)

Is there a way to disable a Cloud Function for Firebase through the Firebase dashboard?
I deployed a Cloud Function with a bug which caused an infinite loop of the function being triggered, updating the data, then the function triggering again. I discovered the error quickly, but I had to fix the code and redeploy the entire project to get the function to stop triggering.
Even though I deployed the new function, the deployment took some time and the function was triggered hundreds of times (which actually caused others to be triggered hundreds of times).
I'd like to be able to disable a function immediately when this happens, but I don't see any options in the dashboard or through the Firebase CLI.
If you view Cloud Functions in the Cloud Console, you can delete them individually from there: https://console.cloud.google.com/functions
Dont want to delete the function as I want to keep the usage history, logs, health ect?
This work around,long winded, but does the trick:
Disable function:
comment out the code in then function in your index.js
deploy just the firebase function:
firebase deploy --only functions:functionName
Enable function:
uncomment code
redeploy just the function with above line
Unfortunately Firebase has only a delete option and no disable option :(
A thing that I'm doing which isn't particularly neat but does the job. is just add a node in the database. for me I have a weekly script I run where I don't want my cloud functions to run when that's running. so at the top of my function I read that node and if the script is running, I just return early. not ideal but saves me having to comment out and redeploy every time
For me the fastest way is to edit function code directly in Google Cloud Console editor. In case of the HTTP function adding something like this at the beginning of a handler
res.status(500).send('The function is disabled');
return;
I use a solution similar to Red Baron. I have a Firestore Collection of booleans (one for each function) and I check that boolean at the beginning of my function to determine if it's allowed to run. The function will indeed be called, but it won't do anything if that boolean is set to false. It's not a perfect solution because it doesn't completely disable the function. But at least it will retain the log history.

Google Cloud Functions with ECONNRESET errors until I redeploy

I'm using Google Cloud Functions to:
Watch for a new Firebase entry
Download a file that's referenced in the Firebase entry
Generate a thumbnail based on that file.
Upload the thumbnail to the cloud bucket.
Unfortunately I'm getting ECONNRESET errors repeatedly on step 4, and the only way to fix it seems to be to redeploy the function. Any ideas how to further debug this?
Edit:
It seems like many times when this happens, when I try to deploy the function again, it errors, and I have to run the deploy twice. Is something hanging or something?
Update May 9 2017
According to this thread, the google cloud nodejs API developers have made some changes to the defaults that are used when initializing that should solve these ECONNRESET socket issues.
From #stephen++ on github GoogleCloudPlatform/google-cloud-node issue 2254:
We have disabled the forever agent by default in Cloud Function
environments. If you un- and re-install #google-cloud/storage, you
will pick up the new behavior automatically. Thanks for all of the
helpful debugging, everyone!
Older Post Follows:
The solution for me to similar ECONNRESET issues using storage on the cloud functions platform was to use npm:promise-retry, but set up your own retry strategy because the default of 10 retries is too many.
I reported an ECONNRESET issue with cloud functions to Google Support (which you might star if you are also getting ECONNRESET in this context but not in other contexts) and they replied with a "won't fix" that the behavior is expected. Google support said the socket that the API client library uses to connect times out after a few minutes, and then when your cloud function tries to use it again you get ECONNRESET. They recommended adding autoRetry:true when initializing the storage API, but that did not help.
The ECONNRESETs happen on the read side too. In both read and write cases promise-retry helps, and most of the time with only 1 retry needed to reset the bad socket.
So I wrote npm:pipe-to-storage to return a promise to do the retries, check md5, etc., but I haven't tested it with binary data, only text, so I don't know if you could use it with image files. The calls would look like this:
const fs = require('fs');
const storage = require('#google-cloud/storage')();
const pipeToStorage = require('pipe-to-storage')(storage);
const source = ()=>(fs.createReadStream("/path/to/your/file/to/upload"));
pipeToStorage(source, bucketName, fileNameInBucket).then(//do next step);
See also How do I read the contents of a new cloud storage file of type .json from within a cloud function?
You can directly report a bug to the Firebase Support team, or open a support ticket with Firebase to troubleshoot a specific issue.
You may also report a Cloud Functions specific issue in the Google Issue Tracker, which is similar to Stack Overflow in that it is accessible by the public (but specifically used for filing issue reports).

Resources