Emulator Storage running but ignored - firebase

I have a firebase function that is successfully uploading a file when run in the emulator, but the file ends up on production even though I'm running the Storage Emulator
I'm running with the following package.json snippets in the functions directory
"dependencies": {
"firebase-admin": "^8.13.0",
"firebase-functions": "^3.16.0",
...
}
"engines": {
"node": "14"
}
I'm initializing everything with defaults (which has worked fine in emulation and production until recently).
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const storage = admin.storage();
const bucket = storage.bucket();
...
const myFunction = async () => {
const savedFile = await bucket.file(`99999999.html`).save(fileContents);
}
The code above works, although the file ends up on production, not in the emulator storage. The logs show that a production google api is being accessed.
This would be fine (not ideal, but workable) if I could also read the file. But when I try to run the .exits() or .download() function for the same file with bucket.file('99999999.html').download();, I get the following log entries:
I need to either:
Get emulation for storage working to resolve this (ideal)
Figure out why downloading isn't working in this case
If anyone can help me with either, I'd greatly appreciate it.

I have updated firebase-admin and firebase-tools packages accordingly:
"dependencies": {
"firebase-admin": "^10.0.0",
"firebase-tools": "^9.23.1",
...
}
This resulted in a more clear error saying that the file downloaded did not match the file on the server (a hash mismatch from what I understand). I know that this is not the case, so I changed .download() to .download({validation: false}). This resolved my issue with accessing the file. It is still not storing on local emulation, but maybe that's not the intent.
UPDATE: I figured out you have to change the bucket to see your files in emulated storage.

Related

firebase emulator cannot refresh dynamic import Functions

Background
I use dynamic import for Firebase Functions to reduce cold start time based on this post: https://medium.com/firebase-developers/organize-cloud-functions-for-max-cold-start-performance-and-readability-with-typescript-and-9261ee8450f0
index.ts under functions folder has only one line
exports.consent = require("./myFunctionGroup");
index.ts under functions/myFunctionGroup
import * as functions from "firebase-functions";
export const helloWorld = functions.https.onCall(async (data, context) => {
return await (await import("./helloWorld")).default(data, context);
});
Content of helloWorld.ts under functions/myFunctionGroup
import * as functions from "firebase-functions";
export default async (
data: {},
context: functions.https.CallableContext
) => {
return "hello";
}
There is no problem when the emulator first launched as it return "hello" correctly. However, when I change to return to 'return "world";', even though the emulator seems to be aware of the change and prints ✔ functions: Loaded functions definitions from source:..., it still return the old value of hello. Maybe it has some kind of cache for the original imported module. When I restart process again, then it will then print "world".
Question:
Is there any setting to make the emulator aware my change and force to clear the Functions cache? I tried to use debugger and it realized my code has changed so that I can step through the new code. It's just not working for the Firebase emulator.
It was expected behavior,any changes/modification in the code after running the emulator will not be reflected. You can also refer to this documentation:
Note:Code changes you make during an active session are automatically
reloaded by the emulator. If your code needs to be transpiled
(TypeScript, React) make sure to do so before running the emulator.
You can run your transpiler in watch mode with commands like tsc -w to
transpile and reload code automatically as you save.
You can follow the below steps,As mentioned in this stackoverflow thread
After every change to the ts files, run "npm run build" to compile the code again.
Change "build": "tsc" to "build": "tsc -w" in package.json if you want to auto-compile after every change.
There is a bug raised for this at github which is still open you can track the updates there.

How to implement Firebase AppCheck inside firebase function to read Realtime database? [duplicate]

I recently enabled App Check for my firebase app and enforced it on both my cloud functions and database. The cloud function workflow is behaving correctly. However, I can no longer access the database from the function. A minimal version of my callable function looks something like this:
exports.myFunc = functions.https.onCall(async (data, context) => {
const adminApp = admin.initializeApp();
const ref = adminApp.database().ref('some-node');
if (context.app === undefined) {
throw new functions.https.HttpsError(
'failed-precondition',
'The function must be called from an App Check verified app.',
);
}
try {
return (await ref.orderByKey().equalTo('foo').get()).exists()
} catch(exc) {
console.error(exc);
}
});
This used to work before App Check, but now it fails and I see this in the logs:
#firebase/database: FIREBASE WARNING: Invalid appcheck token (https://my-project-default-rtdb.firebaseio.com/)
Error: Error: Client is offline.
Seems like I need to do something extra to get the admin app to pass App Check verification down to the database, but I haven't been able to find any documentation on this yet. I also tried using the app instance from functions.app.admin instead of initializing a new one, but this didn't help.
I have the latest version of the packages:
"firebase-admin": "^9.10.0"
"firebase-functions": "^3.14.1"
firebaser here
The behavior you're seeing is not how it's supposed to work, and we've been able to reproduce it. Thanks for the clear report, and sorry you encountered this.
If you (re)install the Firebase Admin SDK today, you won't be experiencing this same problem as we've fixed the problem in the #firebase/database dependency (in this PR).
If you're (still) experiencing the problem, you can check if you have the correct #firebase/database dependency by running:
npm ls #firebase/database
results look something like this:
temp-admin#1.0.0 /Users/you/repos/temp-admin
└─┬ firebase-admin#9.11.0
└── #firebase/database#0.10.8
If your #firebase/database version is lower than 0.10.8, you'll have to reinstall the Admin SDK, for example by deleting your node_modules directory and your package-lock.json file and running npm install again. This may also update other dependencies.

Firebase App Check not working with firebase functions - web project [duplicate]

I recently enabled App Check for my firebase app and enforced it on both my cloud functions and database. The cloud function workflow is behaving correctly. However, I can no longer access the database from the function. A minimal version of my callable function looks something like this:
exports.myFunc = functions.https.onCall(async (data, context) => {
const adminApp = admin.initializeApp();
const ref = adminApp.database().ref('some-node');
if (context.app === undefined) {
throw new functions.https.HttpsError(
'failed-precondition',
'The function must be called from an App Check verified app.',
);
}
try {
return (await ref.orderByKey().equalTo('foo').get()).exists()
} catch(exc) {
console.error(exc);
}
});
This used to work before App Check, but now it fails and I see this in the logs:
#firebase/database: FIREBASE WARNING: Invalid appcheck token (https://my-project-default-rtdb.firebaseio.com/)
Error: Error: Client is offline.
Seems like I need to do something extra to get the admin app to pass App Check verification down to the database, but I haven't been able to find any documentation on this yet. I also tried using the app instance from functions.app.admin instead of initializing a new one, but this didn't help.
I have the latest version of the packages:
"firebase-admin": "^9.10.0"
"firebase-functions": "^3.14.1"
firebaser here
The behavior you're seeing is not how it's supposed to work, and we've been able to reproduce it. Thanks for the clear report, and sorry you encountered this.
If you (re)install the Firebase Admin SDK today, you won't be experiencing this same problem as we've fixed the problem in the #firebase/database dependency (in this PR).
If you're (still) experiencing the problem, you can check if you have the correct #firebase/database dependency by running:
npm ls #firebase/database
results look something like this:
temp-admin#1.0.0 /Users/you/repos/temp-admin
└─┬ firebase-admin#9.11.0
└── #firebase/database#0.10.8
If your #firebase/database version is lower than 0.10.8, you'll have to reinstall the Admin SDK, for example by deleting your node_modules directory and your package-lock.json file and running npm install again. This may also update other dependencies.

Error parsing triggers Cannot find module when deploying firebase function

I am implementing a firebase function endpoint that requires I authenticate with two different projects. Information found on SO and other sources suggest this
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
const serviceAccountSource = require('./source.json');
const serviceAccountTarget = require('./target.json');
const sourceAdmin = admin.initializeApp({
credential: admin.credential.cert(serviceAccountSource)
})
const targetAdmin = admin.initializeApp({
credential: admin.credential.cert(serviceAccountTarget)
s}, "destination")
Where source.json and target.json are files storing the serviceAccount credentials (JSON) obtained from the Project Settings => Generate New Private Key.
My folder structure is as follows
functions/
index.ts
source.json
target.json
Running the following
npm run-script lint
produces no errors, however when I run
firebase deploy --only functions
I get
Error: Error parsing triggers: Cannot find module './source.json'
Firebase admin / functions versions as follows
"firebase-admin": "7.0.0",
"firebase-functions": "^2.2.0"
Typescript
"typescript": "^3.2.2"
Any ideas as what is causing the error.
If you are using Typescript try moving your source.json to the lib folder.
I found a solution to this. Although documentation on the firebase admin functions (parameters etc) seems to be very scarce I did notice that the credential.cert member takes a ServiceAccountPathOrObject.
I tried
const sourceAdmin = admin.initializeApp({
credential: admin.credential.cert('./source.json')
})
This failed with a path not found but this time it gave the path. From this I was able to see that there was a missing element in the Path
const sourceAdmin = admin.initializeApp({
credential: admin.credential.cert('./src/source.json')
})
The function deployed. I then tried to go back to the original code and added the 'src' folder to the path - however that resulted in the same error.
I prefer the above solution but I am still interested to know what caused the original error - given that much of the documentation out there seems to recommend this including this https://gist.github.com/brunobraga95/82bef0672ce451767107e62df1d8b28f - which is the code I am trying to implement.
The function has deployed and is working - so I can confirm the recommendation above works.

Error with Firebase on Electron app: Failed to load gRPC

I'm building an Electron app, and in the renderer.js file, I'm using Firebase Admin to get Firestore data. However, whenever I run it, it returns this error in the logs..
Error: Failed to load gRPC binary module because it was not installed for the current system
Expected directory: electron-v2.0-darwin-x64-unknown
Found: [node-v48-darwin-x64-unknown]
This problem can often be fixed by running "npm rebuild" on the current system
I tried to run "npm rebuild", but it still didn't fix it.
I also tried updating Firebase Admin and gRPC.
Here is the code from the renderer.js file...
// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// All of the Node.js APIs are available in this process.
const admin = require('firebase-admin');
var serviceAccount = require('./credentials.json');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://mytestapp.firebaseio.com"
});
var db = admin.firestore();
const settings = {
timestampsInSnapshots: true
};
db.settings(settings);
function LoadList() {
db.collection("Orders").get().then(function(Collection){
Collection.forEach(function(OrderDoc){
console.log(OrderDoc.id)
})
}).catch(function(err){
console.error(err);
});
}
document.querySelector('#ListSec').addEventListener('click', LoadOrderList)
Any ideas? I've been trying to solve this for hours, but can't seem to figure it out.
That error message indicates that gRPC was installed for Node, not for Electron. Electron has a different binary interface, so binary modules like gRPC need to be installed specifically for Electron. You can generally do this just by running npm rebuild --runtime=electron --target=2.0.0 (modified to match the version of Electron you want to use).
The original answer by #murgatroid99 was helpful at the time, and a postinstall command worked great up until electron v7, where the issue returned.
For anyone else who comes across this issue, I've found a better solution:
the electron-rebuild package
npm install electron-rebuild --save-dev
Run it using
npx electron-rebuild
Or, add it as a postinstall command
{
...
"scripts": {
"postinstall": "electron-rebuild"
},
...
}
Further information is in the official Electron Documentation

Resources