Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

13.x has broken auto finding service account for auth.createCustomToken #2800

Open
seaders opened this issue Dec 4, 2024 · 2 comments
Open
Assignees

Comments

@seaders
Copy link

seaders commented Dec 4, 2024

[REQUIRED] Step 2: Describe your environment

  • Operating System version: OSX 15.1.1
  • Firebase SDK version: 13.0.1
  • Firebase Product: auth (auth, database, storage, etc)
  • Node.js version: 20.11.1
  • NPM version: 10.9.1

[REQUIRED] Step 3: Describe the problem

Steps to reproduce:

What happened? How can we make the problem occur?

Prior to 13.x and the switch to google auth, you were able to run code like this

import { initializeApp } from "firebase-admin/app"
import { getAuth } from "firebase-admin/auth"

initializeApp()
getAuth().createCustomToken("test")

and create a custom token fine. I was able to do it locally, without error.

Now, we get errors locally like

Failed to determine service account. Make sure to initialize the SDK with a service account credential. Alternatively specify a service account with iam.serviceAccounts.signBlob permission. Original error: Error: Error while making request: getaddrinfo ENOTFOUND metadata. Error code: ENOTFOUND

This is very similar to the hoops introduced in 13.x to get the projectId.

To get everything properly working with each other, you need to do something like unnecessarily create the google auth, wait for the projectId/for it to be "filled", and then set the service account that that had auto set in the initializeApp function,

import { initializeApp } from "firebase-admin/app"
import { GoogleAuth } from "google-auth-library"

const gAuth = new GoogleAuth()
const projectId = await gAuth.getProjectId()
const jsonContent = gAuth.jsonContent as { client_email: string }
const app = initializeApp({ serviceAccountId: jsonContent.client_email })

All of the above seems like a big regression to many working features which needs to be fixed, or much of the documentation needs updating as running just initializeApp now does not set up your app fully like it did prior to 13.x, or plainly just a bug.

--- edit ---

My creds are loaded from my .env file, via

GOOGLE_APPLICATION_CREDENTIALS=/Users/Shared/PATH_TO_SERVICE_FILE.json

The exact same service account and env vars are set, when testing against pre 13 and 13.x, and works fine with the appropriate code above, no issue with env vars, nor service account perms.

@lahirumaramba
Copy link
Member

Hey @seaders ,

When you call initializeApp() with no parameters the SDK will try to fetch the credentials from your environment.
How are you setting the service account credentials in your local environment? Do you use the GOOGLE_APPLICATION_CREDENTIALS env variable?

Does your service account have required permissions? See: https://firebase.google.com/docs/auth/admin/create-custom-tokens#service_account_does_not_have_required_permissions

Re: the project id, could you try the accessing the credentials in your app instance without using GoogleAuth?

const app = initializeApp()
const projectId = app.options.credential.projectId

@lahirumaramba lahirumaramba self-assigned this Dec 4, 2024
@seaders
Copy link
Author

seaders commented Dec 4, 2024

Hi @lahirumaramba I should have mentioned that in the OP, but yeah,

.env file,

GOOGLE_APPLICATION_CREDENTIALS=/Users/Shared/.json

In regards the perms, as I mentioned in the post, this works perfectly, with the same service account, service account json file, and .env vars and the above code, on pre 13.x, and with the altered code on 13, so it's 100% nothing to do with the perms. I think it's to do with how the app is initialising now, and due to the "promise-y" nature of loading GoogleAuth, things aren't setting up right.

In regards projectId... my dude
image

As per the docs,

export interface Credential {

projectId doesn't exist on the Credential type. Even if I DID force cast it as having a projectId, it's still empty. It's empty until the getProjectId is awaited upon, in the private (inaccessible to even cast as) ApplicationDefaultCredential

public async getProjectId(): Promise<string> {

I truly don't understand the strategy that's gone on with some of this stuff and the change to GoogleAuth. Either expose the googleAuth object on the credential, or expose the internals of the default credential, or at least let us check, and cast the credential as the internal class. I'm really surprised that more things hasn't broken for more people, we've had a nightmare with the change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants