Call Google Cloud API from local Firebase Emulator - firebase

I've got a function which uses #google-cloud/language.
The function works when deployed live but when running in the local function emulator it complains
I've done firebase login with my Google account but get the following when running the function:
Error: 7 PERMISSION_DENIED: Cloud Natural Language API has not been used in project XXXXX before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/language.googleapis.com/overview?project=XXXXX then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
XXXXX is a project Id I don't recognise - where has this come from and how can I check if I'm mistaken?
The account I'm authed with firebase locally is already in the Owner role for the project, so either the project ID is wrong, or I need to grant permissions to the user?
What do I need to do?

The solution is to set the environment variable GOOGLE_APPLICATION_CREDENTIALS for authentication:
https://cloud.google.com/docs/authentication/getting-started#windows
And restart all the things due to my ENV variable not being updated.

Related

G-cloud sdk --> problems about firebase projects and permissions

I'm developing a backend microservice app with node.js along with #google-cloud/firestore and i'm trying to access my firebase project locally with gcloud-sdk. I've run gcloud init so i can log in and chose the project i need to connect to in order to access the db.
The problem is that, i keep getting 7 PERMISSION_DENIED: Missing or insufficient permissions when i try to make any type of interaction with the db even though i already have all permissions in the project. At the beginning i thought that maybe i was having that problem because i was using a different account that did not have permissions to access these projects, but that didn't make sense because i do not see that account in my list of accounts in the sdk
But, when i gave permissions to the other account that i thought maybe logged in in my sdk, i could access the db, so it was weird, it is like it's stuck with the other account that maybe i added when i first install the sdk.
So, i've tried everything to correct this, i've deleted all accounts from my gcloud sdk, i've deleted the list of configurations, i've uninstalled (twice) the sdk and installed it again (since people that i work with told me that they did this and worked for them, since they had same issue), i've run g cloud init to log in again and all that stuff, and still, when i try to connect to my firebase db, it still says that i still do not have permissions, it's like the account that i'm logging in is not the one that is being saved/used to access my project.
What can i do to make this work ?
EDIT #1 -> How i'm connecting to firebase and sdk commands to connect to the project
Connecting to my project on firestore
import 'reflect-metadata';
import { Firestore } from '#google-cloud/firestore';
import { GCP_PROJECT } from '#util';
export const firestore = new Firestore({ projectId: GCP_PROJECT });
Commands to connect to my project by sdk
-> gcloud init
Welcome! This command will take you through the configuration of gcloud.
Settings from your current configuration [coordinadora-work] are:
core:
account: diego.cifuentes#coordinadora.com
disable_usage_reporting: 'True'
project: cm-reparto-dev
Pick configuration to use:
[1] Re-initialize this configuration [coordinadora-work] with new settings
[2] Create a new configuration
Please enter your numeric choice: 1
Your current configuration has been set to: [coordinadora-work]
You can skip diagnostics next time by using the following flag:
gcloud init --skip-diagnostics
Network diagnostic detects and fixes local network connection issues.
Checking network connection...done.
Reachability Check passed.
Network diagnostic passed (1/1 checks passed).
Choose the account you would like to use to perform operations for this configuration:
[1] diego.cifuentes#coordinadora.com
[2] Log in with a new account
-> Please enter your numeric choice: 1
You are logged in as: [...my account that is having problems...].
Pick cloud project to use:
...
-> Please enter numeric choice or text value (must exactly match list item): 21
Your current project has been set to: [...project that i'm having problems with...].
-> Do you want to configure a default Compute Region and Zone? (Y/n)? n
Your Google Cloud SDK is configured and ready to use!
The Google Cloud Client libraries use the Application Default Credentials, not the current credentials setup using gcloud auth login.
To setup your Application Default Credentials for local development, simple execute gcloud auth application-default login. This will open a browser window and allow you to select the account to use as default credentials.
Another method is setting the environment variable GOOGLE_APPLICATION_CREDENTIALS to point to a service account key file.
Read more here : https://cloud.google.com/docs/authentication/application-default-credentials
When running in GCP, your credentials will get picked up from the environment, i.e. the service account your Cloud Function is running with.
https://cloud.google.com/docs/authentication/client-libraries

If I already have Cloud Functions Admin role, why do I need Cloud Functions Invoker role to run cloud functions?

I have been assigned Cloud Functions Admin role in the IAM permissions settings. I have created a cloud function callable by HTTP. When I make the request it throws
Error: Forbidden
Your client does not have permission to get URL /<function name> from this server.
Apparently I have to add the Cloud Functions Invoker role to be able to call cloud functions, but this seems unnecessary since I'm already a Cloud Functions Admin, whose permissions surely encompass any held within Cloud Functions Invoker.
Is this strange behavior correct or have I taken a wrong turn?
I have now added Owner role aswell as Cloud Functions Admin and it still throws the same 403.
I have updated my CLI using npm install -g firebase-tools - now on v11.8.0.
I have added allUsers principal to have Cloud Functions Invoker.
I have checked any errors logged in the console and gcf-artifacts has failed as the Artifact Registry API is not active. Please enable the API and try again. - however when I check if the Artifact Registry API is enabled, it is.
I am now attempting to enable unauthenticated HTTP function invocation using this article however I can't find the Configuration panel within the google cloud console.
If you are experiencing the same issue and have already completed all of my troubleshooting above, delete your cloud function and redeploy it.
It's that simple.

Previous GCP service account being used when deploying Firebase Functions despite passing updated service account info to admin.initializeApp

I am switching my Firebase functions from one Firebase account to another.
I have rerun firebase init.
I have added the new service account configs to the project and am passing it to admin.initializeApp. I have logged into GCP via my CLI and have run firebase login:ci as well.
Despite all this, whenever I try to run firebase deploy, I am met with the error:
Missing permissions required for functions deploy. You must have permission iam.serviceAccounts.ActAs on service account #appspot.gserviceaccount.com.
Any idea what's going on here?
This doesn't have anything to do with the service account you use to initialize the Firebase Admin SDK. The error has to do with the lack of permission of the Google Account that you used to sign in with the Firebase CLI. It doesn't have permission to deploy to Cloud Functions. You should either sign out then sign back in with an account that has permission (typically "editor" role), or add the appropriate permission to the account that you want to use.
If you're migrating to a new Firebase project / account, you must delete the project's existing .firebaserc and firebase.json files before running firebase init - this will ensure that you're using the updated project configs.

Firebase hosting deploy with serviceaccount fails with 403

I'm trying to deploy a Firebase hosted project with a Service Account (that I created myself, not one provided by Google/Firebase as default) via a pipeline (Gitlab, but that shouldn't matter for this issue).
When I run the following command locally (same happens in the pipeline):
GOOGLE_APPLICATION_CREDENTIALS="/path/to/serviceaccount.json" firebase deploy --only hosting
I'm getting the following error:
=== Deploying to 'my-firebase-project'...
i deploying hosting
Error: HTTP Error: 403, The caller does not have permission
The --debug does not provide any more details, other than the 403. I've set the following roles to the serviceaccount:
Firebase Hosting Admin
Firebase Rules Admin
API keys viewer
Deploying the rules (using --only firestore) works without issues. I've read the documentation about the roles of Firebase hosting, but assigning these don't work either.
Does anyone know which roles I'm missing?
Note: a service account is used here to do a deployment, so any firebase login / firebase logout actions won't have any effect. See Login to firebase using gcloud service account for details.
With the help of Firebase support, I was pointed to the Deploying to Firebase page, which provides an enumeration of all required roles. To sum it up here:
Cloud Build Service Account
Firebase Admin
API Keys Admin
I was missing the first one, which resulted in this error. Hope that this'll help others as well!
You have to add the role at the cluster level using oadm policy add-cluster-role-to-user cluster-reader system:serviceaccount:myproject:default

How to avoid "401 Unauthorized" when invoking Firebase callable HTTP Function under GCP organization?

I have a Firebase project under a GCP organization. I have NodeJS 10 callable functions which work fine with Firebase local emulator and in in GCP functions test page, but when attempting to call them in production using httpsCallable in a webapp, I get 401 Unauthorized - Your client does not have permission to the requested URL
There is practically nothing my test function - it just returns a hardcoded string. There is nothing in the logs after the call attempts.
The function call attempt is done after passing Firebase authentication in the webapp, and in development I see that the user is indeed passed to the context parameter.
I use Firebase Tools 8.0.2 to deploy.
In GCP console function details I see "Ingress settings - Allow all traffic", and as I wrote above, it runs successfully from the test tab there.
I tried to make the function public but I can't set permissions in the console or gcloud. When I try to run the following command with gcloud:
gcloud functions add-iam-policy-binding my-function-name \
--member="allUsers" \
--role="roles/cloudfunctions.invoker"
I get:
ERROR: (gcloud.functions.add-iam-policy-binding) ResponseError: status=[403], code=[Forbidden], message=[Permission 'cloudfunctions.functions.setIamPolicy' denied on resource 'projects/my-project-name/locations/us-central1/functions/my-function-name' (or resource may not exist).]
even though my account has the following roles: Project Owner, Cloud Functions Admin, Security Admin, IAP Policy Admin, Organization Administrator
Any guidance will be appreciated.
Per John's instructions, it turned out gcloud was set to an incorrect active account, so I set it to the correct account that had the required permissions using gcloud config set account my-email#my-domain.com and then I was able to make the function publicly invokable using
gcloud functions add-iam-policy-binding my-function-name \
--member="allUsers" \
--role="roles/cloudfunctions.invoker"

Resources