Difference between Firebase service account key files from Firebase and from GCloud? - firebase

I am running scripts to interact with Firestore (e.g. creating a doc). I've provided a service account key file to do so (tried with key files from Firebase and GCloud) - scripts run the same.
I am aware that Firebase is now built / closely linked to GCloud so I am expecting the key files to be similar.
However, the docs recommend initializing the sdk with a key from Firebase console when adding Firebase admin to your server and from GCloud Console for unit testing.
So here are my questions:
Why recommend 2 different ways to generate them? Is one more appropriate than the other?
Do service account key files generated in Firebase (1) and GCloud (2) consoles differ in terms of scope? Do they allow the same operations? Are they granted equivalent permissions?
Firebase Console > Project Settings > Service Accounts > Firebase Admin SDK > Create new private key
https://console.firebase.google.com/project/[my-project-id]/settings/serviceaccounts/adminsdk
Google Cloud Console > IAM & Admin > Service Accounts > App Engine default service account > Create key
https://console.cloud.google.com/iam-admin/serviceaccounts?project=[my-project-id]

The service account and credentials provided by the Firebase console are no different than one that you'd create in the Cloud console. Firebase is just making it easier to get started, so you don't have to learn the Cloud console. If you want to use the one provided by Firebase, fine. If you want to use one you create and configure in the Cloud console, fine. The Firebase service account should be visible in the Cloud console just like any other. When it comes to assigning permissions to individual products, you can still choose either one to work with. It's up to you.

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

Specify non-default bucket to enable Firebase Storage

I have a situation where I'm trying to enable Firebase Storage but also have an App Engine deployment which already created the buckets {project_name}.appspot.com and it give me the following error message:
I'm aware you can change the Firebase bucket after enabling Firebase Storage from the Firebase console, however I don't see a way to do it before/while enabling Firebase Storage.
I'm working with a few restrictions and want to see if I can enable Firebase storage with those. My first restriction is that I cannot create a separate GCP project for this. We have billing credits which are linked to the project. Another is that I cannot change the App Engine configuration, or rather doing so will only be done in the worst case since that's already being used for a production workload. Lastly, our parent organization is pretty strict in terms of their Org policies and is likely not willing to change it.
Is there a way specify a different bucket to enable Firebase Storage to avoid the conflict?
I created a GCP project with an App Engine app and a Firebase project with Firebase Storage enabled. According to the documentation these services require a default resource location in order to be initially provisioned. Firebase Storage makes use of the same default bucket as App Engine to initialize. It appears that your organization might have blocked access to this bucket, which makes Firebase Storage not to work initially. You should request the organizational policies to be temporarily allowed while Firebase Storage is provisioned, and then, as you mentioned, you can change the bucket used by Firebase Storage to a different one. Firebase makes use also of the following Storage service account:
You should make sure that this account has permissions to perform its operation at creation time of the bucket, from the FAQ it also explains this is needed:
Cloud Storage for Firebase creates a default bucket in the App Engine free tier.

How Can I Obtain GCP service account credentials on Google Cloud Run?

This page explains both:
Obtaining and providing service account credentials manually for developing local, deploying on-premises, or deploying to another public cloud.
Obtaining credentials on Compute Engine, Kubernetes Engine, App Engine flexible environment, and Cloud Functions
But there is no mention of obtaining credentials on Cloud Run. I'd appreciate it if you give instructions for obtaining credentials and setting firebase-admin initializeApp and firebase initializeApp for authentication on Cloud Run.
The documentation suggests that you can use the default service account just like other Google Cloud products as described here. The Firebase Admin SDK should use that account when initialized with no parameters.
There are also steps described if you want to use a non-default service account, which you can simply configure in the console or provide with gcloud.
If you must provide a file that's readable at runtime, you will have to deploy an image with that file added to the image. There is no short set of steps to add that file - you will have to make your docker build include it in a readable location, and your code will know where to look for it in order to load it.

Firebase Service Account for Firestore and Remote Config

I have created/forked a lil Google Apps Script Library to manage Firebase Firestore and Firebase Remote Config called FirebaseGoogleAppsScript. The goal is to simply manage the contents of your collections in an apps script as well as update your remote config.
My issue is I can't get the a service account to do both.
Firebase creates two service accounts upon creating a project:
The first is listed in the Firebase Console -> Project Settings -> Service Accounts. This one I use within my cloud functions to retrieve the Remote Config just fine. However in the Apps Script Project it is unable to retrieve any data from firestore. I tried adding all kinds of roles including Owner and Editor yet no firestore data, but I still can get the RemoteConfig.
The second is only visible in the GCP service accounts and has the title: Firebase Admin SDK Service Agent with the roles Firebase Admin SDK Administrator Service Agent and Service Account Token Creator. This one is able to retrieve all the data from firestore within an Apps Script Project. However in the apps script project I can't get it to retrieve the RemoteConfig even if I add the role Firebase Remote Config Admin.
I have also made my own service account which was able to get the Remote config and just about everything else from Firebase except the Firestore data. Seems only the one service account created by Firebase is able to get any data.
To recreate the issue simply deploy my lil FirebaseGoogleAppsScript project and associate it to the same GCP project Firebase is connected to. There is a test file in it which can recreate the issue assuming you have some data in RemoteConfig and a collection called posts with some docs.
What the heck is going on here? Why can't I make a service account who can access Firestore and RemoteConfig? Any ideas on what to do to create a proper role to do both? Do I really have to use two separate service accounts?

Can't run Firebase Test Lab tests using gcloud and service account: 403, does not have storage.objects.create

I am trying to run instrumented tests using the glcoud CLI as a service account in CircleCi. When I run:
gcloud config set project project-name-12345
gcloud auth activate-service-account firebase-testlab-serviceuser#project-name-12345.iam.gserviceaccount.com --key-file ${HOME}/client-secret.json
gcloud firebase test android run --type instrumentation --app debug-app.apk --test debug-test.apk --device model=Nexus6P,version=27,locale=en,orientation=portrait --environment-variables coverage=true,coverageFile=/sdcard/tmp/code-coverage/connected/coverage.ec --directories-to-pull=/sdcard/tmp --timeout 20m
I get:
ERROR: (gcloud.firebase.test.android.run) Could not copy [debug-app.apk] to [gs://test-lab-xxxxxxxx-yyyyyyyy/2018-01-18_17:14:09.964449_zPAw/] ResponseError 403: firebase-testlab-serviceuser#project-name-12345.iam.gserviceaccount.com does not have storage.objects.create access to bucket test-lab-xxxxxxxx-yyyyyyyy..
Using the API Console (https://console.cloud.google.com/iam-admin/iam/project) I've given my service user all the permission I can think would be relevant:
Firebase Crash Symbol Uploader
Firebase Test Lab Admin
Storage Admin
Storage Object Admin
Storage Object Creator
Storage Object Viewer
Firebase Rules System
Any help would be greatly appreciate. Thanks.
You should be able to use a service account created in the Google Cloud Console. Did your service account have the required project Editor role? (as noted in this doc: https://firebase.google.com/docs/test-lab/continuous)
After lots of clicking through the Firebase console and the Google Cloud Console, reading SO, asking for help on Slack, and more trial and error than I care to admit, I discovered that the Firebase console has a service account page:
https://console.firebase.google.com/u/0/project/project-name-12345/settings/serviceaccounts/adminsdk
That is different from the service accounts page in the Google Cloud Console
https://console.cloud.google.com/iam-admin/serviceaccounts/project?project-name-12345
It turns out you want the Firebase service account, you can not create one via the cloud console. Super, super annoying.
The steps I took to create the key is as follow:
1. Firebase Console https://console.firebase.google.com/
2. Project Settings
3. "Service Accounts" tab
4. Inside "Service Accounts" panel, Firebase Admin SDK
5. At the bottom of "Firebase Admin SDK" panel, "Generate new private key"
This is what Etherton answered
https://stackoverflow.com/a/48327579/2353939
Even after that, I still had some errors. So, I added a bunch of roles as follows.
Firebase Test Lab Admin
Firebase Service Management Service Agent
Firebase Admin SDK Administrator Service Agent
Service Account Token Creator
Storage Object Creator
That also didn't fix. So, finally, I applied P. Davis answer by adding Editor role to the service account.
https://stackoverflow.com/a/48331465/2353939
Steps to add Editor role is as follows
1. Go to google cloud console https://console.cloud.google.com/iam-admin/iam
2. Go into "IAM"
3. Use "client_email" from the json file downloaded from firebase console to find the service account you need to edit
4. Click the "Edit" icon on the right
5. Scroll down and "Add Another Role"
6. Click the input field and type in "Editor" to search
7. Choose the one with subtitle "Edit access to all resource"
8. Save
9. Now you should be able to use it
This is the list of the roles that I put in to my service account :
Firebase - Firebase admin ( I think this is overkill. I might update it later )
Project - Editor
Storage - Storage Object Creator
It does not matter whether you create the service account from Firebase or google cloud console. As long as you have these roles in your service account then you should be able run the Firebase test lab.
For people who stumble upon this and don't want to use the all powerful Project Editor role, here are the roles I'm using for my service account:
Firebase Test Lab Roles
I think the Firebase Analytics Viewer role is not necessary, because it mostly just execute the tests. To view the result we use the developer accounts instead but haven't tried removing it.
We ran into the same permissions issue with storage.objects.create. We have added all the roles that were mentioned here, except for the Editor role which we wanted to avoid, but it still failed. We were using a Service Account and it definitely had the proper permissions.
In the end our workaround was to setup a cloud storage bucket manually and then use it in the --results-bucket argument for gcloud. See the documentation here. That finally fixed it for us.

Resources