I am currently trying to deploy my Cloud Functions to Firebase with firebase deploy --only functions but this does not seem to work, it never finishes the deploy. I tried debugging the deploy with the command firebase deploy --only functions --debug, this prints out all the requests with the url's that lead to the error messages. Whenever i click one of the url's of the requests it gives me this error:
{
"error": {
"code": 403,
"message": "The request is missing a valid API key.",
"status": "PERMISSION_DENIED"
}
}
Some of the other url's give me this error:
{
"error": {
"code": 401,
"message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"status": "UNAUTHENTICATED"
}
}
I can't really find anything useful online on how to fix this either. The articles that i did find did not help me though.
This is my index.js file where my Cloud Functions are:
const functions = require('firebase-functions');
const {firestore, auth} = require('./src/admin');
// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
exports.helloWorld = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
This is my admin.js file where i define the serviceAccountKey and such:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const serviceAccount = require('../serviceAccountKey.json');
const app = admin.apps.length
? admin.app()
: admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: functions.config().database.url || process.env.FIREBASE_CONFIG.databaseURL, // default firebase var
storageBucket: functions.config().storage.bucket || process.env.FIREBASE_CONFIG.storageBucket // default firebase var
});
module.exports = {
app,
firestore: app.firestore(),
db: app.database(),
storage: app.storage(),
auth: app.auth()
};
I have used this exact code before on another project so i assume its a Firebase problem and not my code. In the end i expect my Cloud Functions to be deployed by calling the firebase deploy --only functions command without any authentication errors.
Can someone please tell me what i am doing wrong here?
UPDATE 22-2-2020 12:44 PM: I tried reinstalling and reconfiguring the firebase-tools. After doing that and running the command again it gave me this error:
There was an issue deploying your functions. Verify that your project has a Google App Engine instance setup at https://console.cloud.google.com/appengine and try again. If this
issue persists, please contact support.
! functions: Upload Error: HTTP Error: 503, The service is currently unavailable.
Error: HTTP Error: 503, The service is currently unavailable.
The URL leads me to the page where you can setup your App Engine. Because i already set that up it says 'Your App Engine application has been created'. However whenever i click Get Started button again, i have to create a billing account to proceed. This is keeping me from deploying my Cloud Functions. Is there a way to use Cloud Functions with a billing account?
Related
I am struggling to connect to the emulated Firebase Auth service via the Firebase Admin SDK. I cut down the code to really make the problem stand out, and hope someone can help.
This is the code of the test.js I run (in NodeJS):
// Someone said these two lines should allow the firebase-admin
// SDK to connect to the emulators, but... no.
process.env['GCLOUD_PROJECT'] = 'my-firebase-project-id'
process.env['FIRESTORE_EMULATOR_HOST'] = 'localhost:8080'
const admin = require('firebase-admin')
const app = admin.initializeApp()
const auth = app.auth()
console.log('I have an auth service object')
auth.listUsers().then(users => console.log(users))
I run the emulators like this:
firebase emulators:start --only auth
When I run the test.js file, I get this:
PS C:\...\functions> node .\test.js
I have an auth service object
(node:18232) UnhandledPromiseRejectionWarning: Error: Credential implementation provided to initializeApp() via the "credential" property failed to fetch a valid Google OAuth2 access token with the following error: "Error fetching access token: Error while making request: getaddrinfo EAI_AGAIN metadata.google.internal. Error code: EAI_AGAIN".
at FirebaseAppError.FirebaseError [as constructor] (C:\...\functions\node_modules\firebase-admin\lib\utils\error.js:44:28)
at FirebaseAppError.PrefixedFirebaseError [as constructor] (C:\...\functions\node_modules\firebase-admin\lib\utils\error.js:90:28)
at new FirebaseAppError (C:\...\functions\node_modules\firebase-admin\lib\utils\error.js:125:28)
at C:\...\functions\node_modules\firebase-admin\lib\app\firebase-app.js:87:19
at processTicksAndRejections (internal/process/task_queues.js:97:5)
I run this on Windows with the following versions of firebase:
"firebase-admin": "^10.0.2",
"firebase-functions": "^3.18.1",
I read about getting a secret credentials key and adding its path like this:
process.env['GOOGLE_APPLICATION_CREDENTIALS'] = 'C:\\...\\functions\\.runtimekey.json'
And that 'works' in as much as I then can access the real cloud auth instance (as long as the emulators is off) but that isn't what I want. I want to connect firebase-admin and get a list of users in the emulated Auth instance.
Many thanks for any help you can offer!
Set the environment variable FIREBASE_AUTH_EMULATOR_HOST
export FIREBASE_AUTH_EMULATOR_HOST=localhost:9099
Do not include the protocol scheme (i.e http/https)
Or in your case:
process.env['FIREBASE_AUTH_EMULATOR_HOST'] = 'localhost:9099'
Then you can initialise the app as per normal
admin.initializeApp()
Worked for me (after I finally figured out not to include the protocol scheme)
source: https://firebase.google.com/docs/emulator-suite/connect_auth#admin_sdks
Without having changed anything in my Firebase callable functions code, but having re-deployed them, now they suddenly start rejecting all function invocations from my app with the error shown below. I would like NOT to use App Check until I am ready to make the changes needed. How do I stop my callable (https.onCall) Firebase functions from rejecting invalid App Checks, and instead only reject invalid Authentication?
Failed to validate AppCheck token. FirebaseAppCheckError: Decoding App Check token failed. Make sure you passed the entire string JWT which represents the Firebase App Check token.
at FirebaseAppCheckError.FirebaseError [as constructor] (/workspace/node_modules/firebase-admin/lib/utils/error.js:44:28)
at FirebaseAppCheckError.PrefixedFirebaseError [as constructor] (/workspace/node_modules/firebase-admin/lib/utils/error.js:90:28)
at new FirebaseAppCheckError (/workspace/node_modules/firebase-admin/lib/app-check/app-check-api-client-internal.js:187:28)
at /workspace/node_modules/firebase-admin/lib/app-check/token-verifier.js:82:19
at processTicksAndRejections (internal/process/task_queues.js:97:5) {
errorInfo: {
code: 'app-check/invalid-argument',
message: 'Decoding App Check token failed. Make sure you passed the entire string JWT which represents the Firebase App Check token.'
},
codePrefix: 'app-check'
}
Callable request verification failed: AppCheck token was rejected. {"verifications":{"app":"INVALID","auth":"VALID"}}
The code rejecting all requests due to invalid App Check is super simple:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.example = functions.https.onCall((data, context) => {
return "test";
}
Package.json:
"engines": {
"node": "12"
},
"main": "index.js",
"dependencies": {
"firebase-admin": "^9.10.0",
"firebase-functions": "^3.14.1"
},
I had the same experience. The docs say that you are supposed to check like this[1]:
if (context.app == undefined) {
throw new functions.https.HttpsError(
'failed-precondition',
'The function must be called from an App Check verified app.')
}
But, this is not the case in my experience, the App Check starts to be enforced immediately the moment you add App Check to your app.
EDIT:
moreover, even without doing any check in my code, I can see this in the logs whenever I call one of my functions:
Callable request verification passed {"verifications":{"auth":"VALID","app":"VALID"}}
So it seems App Check happens automatically, at least in Callable Functions. If you want to bypass AppCheck in one of your functions, you might want to try an HTTP function instead (not Callable).
[1] Source https://firebase.google.com/docs/app-check/cloud-functions
From protocol specification for https.onCall:
Optional [Header]: X-Firebase-AppCheck: The Firebase App Check token provided by the client app making the request. The backend automatically verifies this token and decodes it, injecting the appId in the handler's context. If the token cannot be verified, the request is rejected. (Available for SDK >=3.14.0)
My guess is that calls to your callable function contains an invalid App Check token.
If you haven't configured DeviceCheck or/and App Attest attestation providers on your project but have included the App Check library on your client, your client code may be including a dummy App Check token when calling your function (full details on this github issue).
Firebase team is working through changes to make the experience less confusing. Please follow along in http://github.com/firebase/firebase-functions/issues/967 and https://github.com/FirebaseExtended/flutterfire/issues/6794 for status.
My problem is the same when I run the app on an emulator, after running on a real device is running without any problems. That's what happens to me.
Does anyone know why Firebase admin auth in node.js doesn't use ADC (Application Default Credentials)? I always have to set GOOGLE_APPLICATION_CREDENTIALS to a credentials file to get auth to work. Everything else (firestore, compute, storage etc.) works fine with ADC.
For instance, this code works only when GOOGLE_APPLICATION_CREDENTIALS is set to a valid credentials file, even though I'm logged into my Firebase project and my gcloud project:
import * as admin from 'firebase-admin'
admin.initializeApp()
async function listAllUsers(users: any[], matchRegex: RegExp, nextPageToken?: string) {
// List batch of users, 1000 at a time.
const listUsersResult = await admin.auth().listUsers(1000, nextPageToken)
.catch(function (error) {
console.log('Error listing users:', error);
});
if (listUsersResult) {
listUsersResult.users.forEach(function (userRecord) {
if (matchRegex.test(userRecord.email || '<none>') ||
matchRegex.test(userRecord.displayName || '<none>') ||
matchRegex.test(userRecord.uid))
users.push(userRecord.toJSON())
});
if (listUsersResult.pageToken) {
// List next batch of users.
console.log(`next batch...`)
listAllUsers(users, matchRegex, listUsersResult.pageToken);
}
}
}
If that env var is not set, I get this error:
Error listing users: FirebaseAuthError: Failed to determine project ID for Auth.
Initialize the SDK with service account credentials or set project ID as an app option.
Alternatively set the GOOGLE_CLOUD_PROJECT environment variable.
But setting GOOGLE_CLOUD_PROJECT is not enough either. When I do that, I get:
Error listing users: FirebaseAuthError: //cloud.google.com/docs/authentication/. Raw server response: "{"error":{"code":403,"message":"Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the identitytoolkit.googleapis.com. We recommend configuring the billing/quota_project setting in gcloud or using a service account through the auth/impersonate_service_account setting. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/.","errors":[{"message":"Your application has authenticated using end user credentials from the Google Cloud SDK or Google Cloud Shell which are not supported by the identitytoolkit.googleapis.com. We recommend configuring the billing/quota_project setting in gcloud or using a service account through the auth/impersonate_service_account setting. For more information about service accounts and how to use them in your application, see https://cloud.google.com/docs/authentication/.","domain":"usageLimits","reason":"accessNotConfigured","extendedHelp":"https://console.developers.google.com"}],"status":"PERMISSION_DENIED"}}"
at FirebaseAuthError.FirebaseError [as constructor] (/c/dss/Product/Horizon/horizon/packages/renderer/node_modules/firebase-admin/lib/utils/error.js:43:28)
at FirebaseAuthError.PrefixedFirebaseError [as constructor] (/c/dss/Product/Horizon/horizon/packages/renderer/node_modules/firebase-admin/lib/utils/error.js:89:28)
at new FirebaseAuthError (/c/dss/Product/Horizon/horizon/packages/renderer/node_modules/firebase-admin/lib/utils/error.js:148:16)
at Function.FirebaseAuthError.fromServerError (/c/dss/Product/Horizon/horizon/packages/renderer/node_modules/firebase-admin/lib/utils/error.js:187:16)
at /c/dss/Product/Horizon/horizon/packages/renderer/node_modules/firebase-admin/lib/auth/auth-api-request.js:1490:49
As I said though, all other Firebase admin features seem to work fine with ADC; they automatically pick up the current project and my logged in account.
This question already has answers here:
How to resolve 'preflight is invalid (redirect)' or 'redirect is not allowed for a preflight request'
(6 answers)
Closed 2 years ago.
server code
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.hello = functions.https.onCall((data, context) => {
console.log(data.text);
return 123;
});
client code
const myFunc = firebase.functions().httpsCallable('hello');
myFunc({text: 'world'}).then((rslt)=>{
console.log('rslt:', rslt);
});
But it is not work.
I got error message at client browser console.
Access to fetch at 'https:// ==skip== /hello' from origin
'http://localhost:5000' has been blocked by CORS policy: Response to
preflight request doesn't pass access control check: Redirect is not
allowed for a preflight request.
How can I solve this problem?
I did not find a solution in the google guide documentation.
I see comments and add content.
The query does not arrive at the server.
If I try after functions deploy it works fine.
But it doesn't show up on the local console, but on the firebase console.
How can I make a local server call?
It's crazy to deploy every time you test a function.
Hard to tell from the given code why your request violates Cross-Origin Resource Sharing. Take a read on this matter and figure out what is it that you include (whether by intention or not) in your HTTP request that causes it. Headers maybe?
In the meantime, you can enable CORS in Firebase Functions with require("cors"):
const cors = require("cors")({origin: true});
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.hello = functions.https.onCall((data, context) => {
cors(data, context, () => {
console.log(data.text);
res.send("123");
}
});
Regarding local testing of Firebase Functions, you can do so by using this command:
firebase serve --only functions
Local testing of Firebase Hosting / Functions
Enabling CORS in Firebase Functions.
After running the following line in node-js:
import * as admin from "firebase-admin";
import * as serviceAccount from "../../firebase_service_account_key.json";
const app = admin.initializeApp({
credential: admin.credential.cert(serviceAccount as any),
databaseURL: "https://my-app-path.firebaseio.com"
});
admin.messaging().send({
token: "known-good-token",
notification: {
title: "Test Push Note",
body: "Here is some text"
}
});
I'm getting the error:
Error: Auth error from APNS or Web Push Service
Raw server response:
"{
"error":{
"code":401,
"message":"Auth error from APNS or Web Push Service",
"status":"UNAUTHENTICATED",
"details"[
{
"#type":"type.googleapis.com/google.firebase.fcm.v1.FcmError",
"errorCode":"THIRD_PARTY_AUTH_ERROR"
},
{
"#type":"type.googleapis.com/google.firebase.fcm.v1.ApnsError",
"statusCode":403,
"reason":"InvalidProviderToken"
}
]
}
}"
I've added an "APNs Authentication Key" to my ios project under the Settings > Cloud Messaging section of Firebase. I've also properly downloaded and imported my service account json file.
In terms of research, I've tried looking up the errors.
For the InvalidProviderToken error, this answer seems to indicate I'm using an old token. This is totally possible, but the logs on my app and database appear to match, so it seems off.
As for the THIRD_PARTY_AUTH_ERROR, google gave me no hits. The closest thing I found was this, and the following text might be the culprit (EDIT: it's not the issue):
auth/unauthorized-domain
Thrown if the app domain is not authorized for OAuth operations for your Firebase project. Edit the list of authorized domains from the Firebase console.
Does anyone have anymore details on this error which might help me get to the bottom of it?
This error arises if your app setup for iOS has an error in any one of the following:
Found in Settings > General > Your Apps > iOS Apps:
App Store ID
Bundle ID
Team ID
When adding an APNs key (Uploading to Cloud Messaging > APNs Authentication Key):
Team ID (should auto set based off ios app info above)
Key Id (often is in the name of the key, best to grab when creating it)
Everything worked for me the other day, so all setup was fine. But today I got this error.
Here's what solved it for me:
Revoked APNs Key
Created new one and downloaded it
Deleted old one and Uploaded it to Firebase Dashboard / Settings /
Cloud Messaging
Gone to Settings / Service Accounts and generated new private key
Added it to my Cloud Functions project (renamed it to
service-account.json in my case)
Saved the files and deployed the functions: firebase deploy --only
functions
Did you call admin.initializeApp()?
There are many official samples.
See:
https://github.com/firebase/functions-samples/blob/master/fcm-notifications/functions/index.js#L20
https://github.com/firebase/functions-samples/tree/master/fcm-notifications
https://github.com/firebase/functions-samples
https://github.com/firebase/quickstart-js/tree/master/messaging
I had the same issue. The culprit was lowercase APNs teamId. Changing it to capital solved it.
Double check if you have uploaded your apns key on firebase console. That was my case.