Could not load the default credentials? (Node.js Google Compute Engine tutorial)
Asked Answered
B

19

120

SITUATION:

I follow this tutorial: https://cloud.google.com/nodejs/tutorials/bookshelf-on-compute-engine

Everything works fine until I do npm start and go to:

http://localhost:8080

I am met with the following text on the blank page:

Could not load the default credentials. Browse to https://developers.google.com/accounts/docs/application-default-credentials for more information.

Which makes no sense since I am using OAuth. I followed the link and read the page, but I have no GOOGLE-APPLICATION-CREDENTIALS field anywhere, and nothing about it in the tutorial.


QUESTION:

Could you please reproduce the steps and tell me if you get the same result ?

(takes 5 minutes)

If not, what could I have done wrong ?

Bandung answered 4/2, 2017 at 17:56 Comment(1)
If you are here as a result of the same issue but with Firebase: See this QuestionBackscratcher
H
267

Yes, I had the same error. It's annoying cause Google Cloud Platform docs for their "getting started" bookshelf tutorial does not mention this anywhere. Which means that any new developer who tries this tutorial will see this error.

Read this: https://developers.google.com/identity/protocols/application-default-credentials

I fixed this issue by running: gcloud auth application-default login

In order to run thisgcloud auth application-default login Visit: https://cloud.google.com/sdk/install 1) You have to install sdk into your computer 2) That will enable you to run the code 3) Log in to your associated gmail account then you are good to go!

This will make you login, and after that you code locally will use that authentication.

Healion answered 6/2, 2017 at 2:41 Comment(12)
I did that, and the message is now: The project projectName does not exist or it does not contain an active App Engine application. Please visit http://console.developers.google.com to create a project or https://console.developers.google.com/appengine?project=projectName to add an App Engine application. Note that the app must not be disabled. THIS MAKES NO SENSE, I AM USING THE COMPUTE ENGINE AND THIS IS A TUTORIAL FOR THE COMPUTE ENGINE :(Bandung
To use the gloud CLI for these tutorials you need to configure your default app in the CLI level. You may have missed this step. I'm sure you have already created a "Project" in GCP, take that ProjectID and run this: gcloud config set project [YOUR_PROJECT_ID]. This will configure your gloud CLI to use the correct Project. Check out: cloud.google.com/nodejs/getting-started/tutorial-appHealion
Setting process.env.GOOGLE_APPLICATION_CREDENTIALS = "<PATH_TO_SERVICE_ACCOUNT_JSON_FILE>" worked for me.Macrophage
@Healion 'gcloud' is not recognized as an internal or external command, operable program or batch file.Selfsuggestion
@Bandung After installing the SDK and setting up GOOGLE_APPLICATION_CREDENTIALS it works for me. But how is this supposed to work in production? How do we retrieve the credentials in production?Improvement
@GabrielWamunyu Does it work for you w/o the SDK? in production?Improvement
@Healion how do we make this credentials work on production? I have tried giving IAM bucket access to my service account but still it is not working. Do you any idea?Christa
@Healion how to solve this issue if it's appearing in the bitbucket pipelines?Aggregation
@GabrielWamunyu don't use service account files in production, they are easy to download breaching your whole environment.Perplexed
installing SDK and authenticating, it does not help me. still my app could not load ADC file. how?Melesa
@OliverDixon how to use the credentials in production instead of using service account files?Stunk
This does not work, as "gcloud auth application-default login" won't be picked up by the code, but only by sdk commands.Incorrigible
M
39

There are 2 solutions for this problem. One option, as mentioned by others, is to use gcloud auth application-default login

Second option is to set the environment variable GOOGLE_APPLICATION_CREDENTIALS. It should point to a file that defines the credentials. To get this file you need to follow these steps:

Go to the API Console Credentials page.

From the project drop-down, select your project.

On the Credentials page, select the Create credentials drop-down, then select Service account key.

From the Service account drop-down, select an existing service account or create a new one.

For Key type, select the JSON key option, then select Create. The file automatically downloads to your computer.

Put the *.json file you just downloaded in a directory of your choosing.

This directory must be private (you can't let anyone get access to this), but accessible to your web server code.

Set the environment variable GOOGLE_APPLICATION_CREDENTIALS to the path of the JSON file downloaded.

See https://developers.google.com/identity/protocols/application-default-credentials for details

Mesosphere answered 18/12, 2017 at 11:35 Comment(3)
Just want to say thanks. This one works for me (using Node.js).Conny
the path should be like C:\Users\CheeWei.Choy\Desktop\OCR\Google-Vision-Api or just Google-Vision-Api.json @MesosphereSelfsuggestion
You can choose the service account rule to be "reCAPTCHA Enterprise Agent"Wivinah
O
22

I was facing the same issue. It got fixed with following command.

gcloud auth application-default login

It stores default gcloud cloud credentials on your system and uses the same.

Ole answered 21/10, 2021 at 5:48 Comment(0)
M
17
  1. Create a service account key using and download the json file. https://console.cloud.google.com/apis/credentials/serviceaccountkey

  2. Add this to your ENV file

    GOOGLE_APPLICATION_CREDENTIALS = "<PATH_TO_SERVICE_ACCOUNT_JSON_FILE>"

E.g:

GOOGLE_APPLICATION_CREDENTIALS=/Users/hello/Documents/ssh/my-10ebbbc8b3df.json
Maes answered 8/1, 2019 at 6:48 Comment(5)
how do we make this credentials work on production?Christa
To use this in production you would do the same thing. You have a .ENV file in your project's directory and you make sure that the file path is still accurate-- pointing to the location of the JSON file-- when deployed.Feria
@Feria that's bad practice. We shouldn't commit private keys in repoBeaston
How do you download the JSON file? There seem to be no buttons or links of any sorts (as of 2023)Ligon
dude, i just spent like 6 hours trying to fix this haha, thanks!!Andra
L
9

I got this error because of initially I did like below:

var admin = require("firebase-admin");
admin.initializeApp(); // I didnt add anything because firebaserc file include appName

It worked when I deployed the functions but not in serve. So this is how I solved it:

  • Go to the firebase Project settings(click on setting icon from side nav).
  • Click on the Service accounts.
  • Copy the admin sdk configuration snippet from selecting your pro. lang.

Ex (node.js):

var admin = require("firebase-admin");

var serviceAccount = require("path/to/serviceAccountKey.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://your-domain.firebaseio.com"
});
  • Now we need to add serviceAccountKey.json file.
  • Click on the Manage service account permissions in top right corner.
  • Now, you will see services accounts for your project, in the table find the row with column name name and value firebase-adminsdk, in that row click on Action dots and select Create key.
  • From the pop up dialog select Key type as json and press create button.
  • You will prompt to download the file, download it to your functions directory in project(You can customize this as you want and if you pushing to github, make sure to ignore that file).
  • Now, if you save it into the same directory where you are initializeApp(), access that file like: ./socialape-15456-68dfdc857c55.json(In my case, both files are located: functions/index.js and functions/services.son in functions directory and in index.js file, I initialed my firebase admin sdk).

Ex(node.js):

const functions = require('firebase-functions');

var admin = require("firebase-admin");

var serviceAccount = require("./myapp-15456-68dfdc857c55.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://myapp-15456.firebaseio.com"
});

It's a best and good idea to create .env file and include your file there and access it as others mentioned. I leave that part to you.

Hope this help someone on the planet. Regards!

Lavellelaven answered 8/12, 2019 at 17:45 Comment(3)
Don't do this. The environment exposes an API to access the the security of the platform.Perplexed
@OliverDixon can you please elaborate more on your comment and the right way to do this.Lavellelaven
#56598569Perplexed
M
7

If you're running the app locally, then the gcloud beta auth application-default login command should suffice for acquiring local credentials (I updated the tutorial to say so).

When running the app on Google Compute Engine, if the Compute Engine instance was created with the proper scopes (cloud-platform should be sufficient) then the app will authenticate with Google Cloud Platform APIs automatically without any extra work on your part.

Michi answered 7/2, 2017 at 18:50 Comment(3)
Thank you for your quick response. It's very nice to have such a quick official response from a Google engineer :) Sadly, I am faced with another issue in the tutorial, could you please have have a look at the following question: #42098508 ?Bandung
Also, you updated the wrong tutorial. That one is for the App Engine ?Bandung
Difference between gcloud beta auth application-default login and gcloud auth application-default login?Quake
C
5

Go here: https://firebase.google.com/docs/admin/setup#initialize_the_sdk and follow the instructions to create a private key. Then after you have downloaded your private key open command prompt in the project directory and do the following command:

 set GOOGLE_APPLICATION_CREDENTIALS=C:\YOUR-PATH\YOUR-KEY.json
Converge answered 5/9, 2019 at 13:15 Comment(1)
Really bad advice. Service account files are easy to download from production images over the internet; this will breach your whole GCP account.Perplexed
S
4

use this to solve your issue. this actually works:- just put credential parameter and give reference to your key to it.

const serviceAccount = require('../key.json');
admin.initializeApp({
    credential: admin.credential.cert(serviceAccount)
});
Sabaean answered 5/9, 2019 at 7:21 Comment(1)
perfect for unit/integration testing !Catbird
T
3

You have to create an object of your SessionsClient. Here I will provide some steps, so you can run your code like a charm.

  1. You have to go into your Dialogflow dashboard.
  2. Click on setting ( Left navbar top-right gear icon)
  3. in the General tab click Service Account link ( it will redirect you to another screen)
  4. If you have a service account then ignore step 5
  5. Create a service account ( Top-center +icon button)
    • Now you have a service account on a list click on
  6. From the action, field presses the 3 vertical dots and create a key.
  7. Download the JSON file on your local computer.
  8. Assign object to your sessionClient.
const sessionClient = new dialogflow.SessionsClient({
 keyFilename: "/var/www/html/moqatrips/dialog-flow.json"
});
Throwaway answered 9/9, 2020 at 11:17 Comment(1)
This is incorrect and introduces a security issue to the project; not to mention issues with deploying to multiple environments. Don't use service account files. Always use environmental apis.Perplexed
E
2

For all people using firebase, what it worked for me was passing the credentials to the KeyManagementServiceClient constructor

const serviceAccount = require('../keys/file.json'); //<- your firebase credentials
const client = new KeyManagementServiceClient({
      credentials: serviceAccount,
    });
Electromagnetism answered 3/7, 2020 at 20:33 Comment(0)
K
2

Another solution i found: in your package.json add an export command like this:

"scripts": {
    "start": "export GOOGLE_APPLICATION_CREDENTIALS='./gcloud.json' && node ./bin/www --exec babel-node --presets babel-preset-env",
  },
Kassie answered 7/8, 2020 at 14:5 Comment(0)
F
1

I also had this error problem, here I had not created the object of

keyFilename (stores the credentials of the api)

in the sessionClient object for nodejs app.

const sessionClient = new dialogflow.SessionsClient({
                keyFilename: "./keyCredentials.json"  
       });
        
           const sessionPath = sessionClient.sessionPath(projectId, sessionId);

To download 'keyCredentials.json' goto:

https://console.cloud.google.com/apis/credentials/serviceaccountkey

Also add the path of this file to the system variables

  1. In windows open powershell
  2. type GOOGLE_APPLICATION_CREDENTIALS = [PATH_TO_SERVICE_ACCOUNT_JSON_FILE]
Footmark answered 27/1, 2020 at 18:35 Comment(0)
U
1

you may find youself in another part of the world -- and land here. I'm adding to a three year old question because its keywords matched my issue and the preceding answers helped me although none describe my issue

firebase deploy --only functions --debug

produced

[2020-12-02T08:31:50.397Z] FirebaseError: HTTP Error: 429, Unknown Error
Error: Could not read source directory. Remove links and shortcuts and try again.

I could not find anything wrong with the source directory. But that was all so many tiny fish.

Examining the error in detail, from the top, lead to:

Our systems have detected unusual traffic from your computer network.  This page checks to see if it&#39;s really you sending the requests, and not a robot. 
The block will expire shortly after those requests stop.  

Out of curiosity and exhaustion, I waited first. The wait reset duration is > than 30 minutes. So i pursued the captcha to prove my enduring humanity which did register eventually after some oauth warnings.

Uni answered 2/12, 2020 at 19:55 Comment(0)
M
1
Mealymouthed answered 4/6, 2021 at 12:8 Comment(0)
C
0

Although this question has been answered multiple times, I found myself in a situation not explained here.

After I created the variable: $GOOGLE_APPLICATION_CREDENTIALS, I was getting the same error as Coder1000.

However, I was running both: nodemon and: npm run dev in two separate sessions in Terminal, neither of which were aware of the variable.

Once I: shut the tabs down; added new tabs; and ran the commands again, the application was able to access the variable.

Conservatism answered 19/5, 2020 at 9:19 Comment(0)
W
0

If anyone ran into the issue just like me and doesn't want to set the variable each time before running their code it's best to manually set the environment variable. Name it GOOGLE_APPLICATION_CREDENTIALS and browse the downloaded JSON file. If you don't know the steps follow this: https://docs.oracle.com/en/database/oracle/machine-learning/oml4r/1.5.1/oread/creating-and-modifying-environment-variables-on-windows.html#GUID-DD6F9982-60D5-48F6-8270-A27EC53807D0

Wildawildcat answered 14/10, 2021 at 15:10 Comment(0)
G
0

You may use 2 options to initialize Storage with the dynamic key:

new Storage({credentials: {%_json_content_%})


new Storage({keyFilename: {%_json_path_%})
Geter answered 3/8, 2023 at 8:2 Comment(0)
S
0

e.g: we can use the credentials object like below:

  new PubSub({
    projectId: process.env.PROJECT_ID,
    credentials: {
      client_email: process.env.CLIENT_EMAIL,
      private_key: process.env.PRIVATE_KEY,
    },
  }
Scoop answered 21/8, 2023 at 23:44 Comment(0)
F
0

I ended up just encoding the json file and saving it as a base64 env variable:

import {GoogleAuth} from 'google-auth-library';

function getGoogleCredentials() {
  const base64Data = process.env.BASE_64_CREDENTIALS!
  // Convert the base64 string back to a Buffer
  const bufferData = Buffer.from(base64Data, 'base64');

  // Convert the Buffer back to a JSON string
  const jsonData = bufferData.toString('utf-8');

  // Parse the JSON string to get the JavaScript object
  const jsonObject = JSON.parse(jsonData);
  return {
    private_key: jsonObject.private_key,
    client_email: jsonObject.client_email
  }
}

const auth = new GoogleAuth({
  scopes: "https://www.googleapis.com/auth/cloud-platform",
  credentials: getGoogleCredentials()
});
const token = await auth.getAccessToken()

I cannot for the life of me understand how google expects one to do this differently using any kind of automated deployment software.

Filum answered 4/11, 2023 at 23:23 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.