Permission errors unit-testing Google Cloud Functions calling firestore db - firebase

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?

Related

DialogFlow "Webhook call failed. Error: UNKNOWN."

I have a DialogFlow setup using a firebase function for fulfillments.
I attempted to add two regions to .region() in my index.js file. This led to me deleting my existing firebase function (which had been running on "us-central-1") and adding two new ones for the newly added regions.
After doing so, my dialogflow setup completely fails to do fulfillments. Instead, i get "Webhook call failed. Error: UNKNOWN" with no other details. I tried removing .region() in my index.js, thereby creating a new firebase function similar to the original, but without luck.
I have also tried to add my fulfillment code directly in the inline editor, but this does not work either.
I am at a loss for what to do here. Has anyone experienced similar issues or perhaps know a fix? Please note that the setup worked completely fine prior to adding .region() and deleting the existing firebase function.
NOTE: I am getting a weird error when deploying through the inline editor: "Permission 'cloudfunctions.functions.SetIamPolicy' denied on resource '(my resource)' (or resource may not exist)."
Regarding the following error:
Permission 'cloudfunctions.functions.SetIamPolicy' denied on resource '(my resource)' (or resource may not exist).
I also encountered this when I deleted the function and tried to redeploy it.
I discovered that this occurs when the user (i.e. you) deploying the function does not have sufficient permissions to set IAM policies. In my case, the project was owned by another user whilst I had limited access. After being given owner access, although you likely only need permissions to manage IAM, the function deploys without any errors.
Although you moved the location of the function, you don't mention that you changed the URL for the webhook in Dialogflow to reflect this new location. The URL for Firebase Cloud Functions include the region where the function runs, so if you change the region, you also need to change the fulfillment URL.

Why do I get "Client is not yet ready to issue requests" - Firestore get() fails when called by Schedule function

In my Firebase project I have a functions.pubsub.schedule().onRun() that runs every 5 minutes to perform some calendar related tasks. It needs to look up in my Firestore collections and does so with a .get() query.
This has been working fine until sometime 2020-03-13 in the morning where the function started to throw
2020-03-13 09:36:02.326 CET scheduledHooks 1042277797598294
Error: INTERNAL ERROR: Client is not yet ready to issue requests.
at Firestore.get projectId [as projectId] (/srv/functions/node_modules/#google-cloud/firestore/build/src/index.js:401:19)
at Query.toProto (/srv/functions/node_modules/#google-cloud/firestore/build/src/reference.js:1556:42) at Query._get (/srv/functions/node_modules/#google-cloud/firestore/build/src/reference.js:1466:30)
at Query.get (/srv/functions/node_modules/#google-cloud/firestore/build/src/reference.js:1457:21)
at FirebaseActivitiesCollection.<anonymous> (/srv/functions/lib/collections/activities/FirebaseActivitiesCollection.js:32:40)
at Generator.next (<anonymous>) at /srv/functions/lib/collections/activities/FirebaseActivitiesCollection.js:8:71
at new Promise (<anonymous>) at __awaiter (/srv/functions/lib/collections/activities/FirebaseActivitiesCollection.js:4:12)
at FirebaseActivitiesCollection.getActivitiesByInterval (/srv/functions/lib/collections/activities/FirebaseActivitiesCollection.js:27:16)
I can't track that I have changed anything, could it be that Firebase made some changes that I should be aware of or am I missing an obvious clue in this error message?
My other Cloud Functions and the Firebase JavaScript SDK still work fine.
Extra info: The same code works on my other environment where I have not deployed. This of course led me to search for changes in the deployed code, but I can't find any!?
It seems by the error, that the project was not connected and initialized correctly. As per the official API here, this error occurs when:
Returns the Project ID for this Firestore instance. Validates that
initializeIfNeeded() was called before.
I would recommend you to check that. In case you are still facing, I would say for you to contact the Firebase Free Support. Since you mentioned that it was working until yesterday morning, it might be some change on their side.
Hope this helps!
This turned out to be a very simple matter of initialization of Firebase:
Before I had:
// Initialize firebase
admin.initializeApp(functions.config().firebase)
..And it worked fine until it didn't anymore.
Now I have:
// Initialize firebase
admin.initializeApp()
... And it works again
Got the same error while running some jest tests involving firebase. Problem was that I didn't have GOOGLE_APPLICATION_CREDENTIALS environment variable set.
Since I was running them locally on my machine, exporting this variable in terminal before running the tests was sufficient for my case:
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials/file.json

See continuous logging on command line

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

Firebase Functions: Could not load default credentials

I have a Firebase Function that subscribes to a Cloud PubSub topic. App is initialized very simply like this:
import * as admin from 'firebase-admin';
admin.initializeApp();
I'm getting this error:
"Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
at GoogleAuth.getApplicationDefaultAsync (/srv/functions/node_modules/google-auth-library/build/src/auth/googleauth.js:161:19)
at process._tickCallback (internal/process/next_tick.js:68:7)"
Here's the weird thing. It typically works. In other words, if I trigger it a second time it works. And a third time. Most often it seems to fail the first time it runs after a new firebase deploy and possibly on a "cold start."
Not sure what I'm doing wrong and why it would fail only on the first run.
SOLVED! This answer helped:
Error: Could not load the default credentials (Firebase function to firestore)
From within a Firebase Function for an API call, I was publishing to a Cloud PubSub topic like this:
pubsub.topic(topicName).publish(dataBuffer, customAttributes)
I was not awaiting the response and was immediately sending the 2XX HTTP response back to the client. The execution seemed to continue fine, but obviously it did not behave as intended.
Sometimes the API response call itself would fail (and never publish the message), but sometimes not. In other cases, the publish would succeed but the Firebase Function subscribing to the topic would fail!
In all cases, this seemed to resolve itself after running the script a second time. For this reason, I still believe it had something to do with a cold start.
But since I changed it to await like this:
await pubsub.topic(topicName).publish(dataBuffer, customAttributes)
I have not seen this problem happen again.

Cloud Functions for Firebase sometimes have Invalid credential error

Not appear every time, but sometimes this error appears in the log:
FIREBASE WARNING: {"code":"app/invalid-credential","message":"Credential implementation provided to initializeApp() via the \"credential\" property failed to fetch a valid Google OAuth2 access token with the following error: \"read ECONNRESET\"."}
Is there any way to handle this kind of error like retry?
Or is it okay to ignore it?
Just ensure that your machine time auto sync. and not manualy,
And your XXX......json from firebase is the latest downloaded. (if you dont sure, download it again - and this file will be the newer one)
that what helped me.
I am also facing this issue. Looks like it retries and get the job done but cloud functions are taking time to process data.

Resources