We are trying to create a development environment before publishing our firebase functions.
We have successfully installed and started a local emulator, can access our firestore database, can call the HTTPS endpoints and everything. Starting firebase emulators:start shows:
firebase emulators:start --import=./testdata
i emulators: Starting emulators: functions, firestore, hosting, pubsub
⚠ functions: The following emulators are not running, calls to these services from the Functions emulator will affect production: auth, database
⚠ Your requested "node" version "12" doesn't match your global version "14"
i firestore: Importing data from /home/forest/projects/icell/i_cell_parking_manager/firebase/testdata/firestore_export/firestore_export.overall_export_metadata
i firestore: Firestore Emulator logging to firestore-debug.log
i pubsub: Pub/Sub Emulator logging to pubsub-debug.log
i hosting: Serving hosting files from: webserver
✔ hosting: Local server: http://localhost:5000
i ui: Emulator UI logging to ui-debug.log
i functions: Watching "..../firebase/functions" for Cloud Functions...
✔ functions[createParkingReservationsForNextWeek]: pubsub function initialized.
✔ functions[reserveSpaceForUser]: http function initialized (http://localhost:5001/i-cell-parking-manager-backend/us-central1/reserveSpaceForUser).
┌────────────────────────────────────────────────────────────────┐
│ ✔ All emulators ready! View status and logs at localhost:4000 │
└────────────────────────────────────────────────────────────────┘
┌───────────┬────────────────┬──────────────────────────┐
│ Emulator │ Host:Port │ View in Emulator UI │
├───────────┼────────────────┼──────────────────────────┤
│ Functions │ localhost:5001 │ localhost:4000/functions │
├───────────┼────────────────┼──────────────────────────┤
│ Firestore │ localhost:8080 │ localhost:4000/firestore │
├───────────┼────────────────┼──────────────────────────┤
│ Hosting │ localhost:5000 │ n/a │
├───────────┼────────────────┼──────────────────────────┤
│ Pub/Sub │ localhost:8085 │ n/a │
└───────────┴────────────────┴──────────────────────────┘
Other reserved ports: 4400, 4500
We have a function called createParkingReservationsForNextWeek which is a timed single pubsub, we want to trigger it without needing to wait for the scheduler.
*/
exports.createParkingReservationsForNextWeek = functions.pubsub
.schedule(WEEKLY_NOTIFICATION_SCHEDULE)
.timeZone(TIMEZONE_EUROPE_BUDAPEST)
....
According to https://firebase.google.com/docs/functions/local-emulator#web we can do that by navigation to this URL in a browser: http://localhost:5001/i-cell-parking-manager-backend/us-central1/createParkingReservationsForNextWeek
But upon that we get this error (which can be seen in the emulator logs as well):
functions: TypeError: Cannot read property 'data' of undefined
at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:580:28
at Generator.next (<anonymous>)
at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:8:71
at new Promise (<anonymous>)
at __awaiter (/usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:4:12)
at processBackground (/usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:577:12)
at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:673:23
at Generator.next (<anonymous>)
at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:8:71
at new Promise (<anonymous>)
⚠ Your function was killed because it raised an unhandled error.
In the logs (http://localhost:4000/logs):
14:50:31
I
function[createParkingReservationsForNextWeek]
Beginning execution of "createParkingReservationsForNextWeek"
14:50:31
W
function[createParkingReservationsForNextWeek]
TypeError: Cannot read property 'data' of undefined
at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:580:28
at Generator.next (<anonymous>)
at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:8:71
at new Promise (<anonymous>)
at __awaiter (/usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:4:12)
at processBackground (/usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:577:12)
at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:673:23
at Generator.next (<anonymous>)
at /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:8:71
at new Promise (<anonymous>)
14:50:31
W
function[createParkingReservationsForNextWeek]
Your function was killed because it raised an unhandled error.
Cloud-firestore-emulator version is v1.11.9.
You can run a pub/sub function locally by calling it by name in the firebase shell:
Terminal 1: firebase emulators:start
Terminal 2: firebase functions:shell then createParkingReservationsForNextWeek()
If you need to include data on invocation (likely the cause of your error above), you can do so as well:
// invokes a function with the JSON message { hello: 'world' } and attributes { foo: 'bar' }
myPubsubFunction({data: new Buffer('{"hello":"world"}'), attributes: {foo: 'bar'}})
See the Firebase documentation for more details.
Related
I am trying to test my app with the firebase local emulator suite, which uses hosting, firestore and cloud functions.
I setup my app for the local emulator with the following code, referring to the instructions in https://firebase.google.com/docs/emulator-suite/connect_firestore#web-version-9.
import { getFirestore, connectFirestoreEmulator } from "firebase/firestore";
import { initializeApp } from "firebase/app";
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
connectFirestoreEmulator(db, 'localhost', 8080);
Then I was able to start up my local emulator with no errors using the following command
firebase emulators:start --project demo-<PROJECT_ID>
substituting <PROJECT_ID> and <LOCAL_DIR> with my actual project id and local directory.
Terminal output:
i emulators: Starting emulators: auth, functions, firestore, hosting, storage
i emulators: Detected demo project ID <PROJECT_ID>, emulated services will use a demo configuration and attempts to access non-emulated services for this project will fail.
+ functions: Using node#14 from host.
i firestore: Firestore Emulator logging to firestore-debug.log
i hosting: Serving hosting files from: build
+ hosting: Local server: http://localhost:5000
i ui: Emulator UI logging to ui-debug.log
i functions: Watching "<LOCAL_DIR>" for Cloud Functions...
+ functions[us-central1-makeUppercase]: firestore function initialized.
+ functions[us-central1-onCreateEntry]: firestore function initialized.
┌─────────────────────────────────────────────────────────────┐
│ ✔ All emulators ready! It is now safe to connect your app. │
│ i View Emulator UI at http://localhost:4000 │
└─────────────────────────────────────────────────────────────┘
┌────────────────┬────────────────┬─────────────────────────────────┐
│ Emulator │ Host:Port │ View in Emulator UI │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Authentication │ localhost:9099 │ http://localhost:4000/auth │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Functions │ localhost:5001 │ http://localhost:4000/functions │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Firestore │ localhost:8080 │ http://localhost:4000/firestore │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Hosting │ localhost:5000 │ n/a │
├────────────────┼────────────────┼─────────────────────────────────┤
│ Storage │ localhost:9199 │ http://localhost:4000/storage │
└────────────────┴────────────────┴─────────────────────────────────┘
Emulator Hub running at localhost:4400
Other reserved ports: 4500
But when I try to create a new Firestore document through my app hosted in local emulator, nothing is shown in my Firestore local emulator. Nor did I get any errors on my browser's console.
I was able to create new documents manually and communicate with my Cloud Functions local emulator in the Firestore local emulator. No problem. Only facing problems when I try to communicate with Firestore through my app.
What did I miss ? Thank you very much for your help!
I had similar issue, here is my firebase.js I am using in my react app.
import { initializeApp } from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
import 'firebase/storage';
import { getAuth, connectAuthEmulator } from 'firebase/auth';
import {
getFirestore,
connectFirestoreEmulator,
} from 'firebase/firestore';
const firebaseConfig = {
apiKey: process.env.REACT_APP_API_KEY,
authDomain: process.env.REACT_APP_AUTHDOMAIN,
databaseURL: process.env.REACT_APP_BASEURL,
projectId: process.env.REACT_APP_PROJECT_ID,
storageBucket: process.env.REACT_APP_STORAGEBUCKET,
messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_APP_ID,
measurementId: process.env.REACT_APP_MEASUREMENT_ID,
};
const app = initializeApp(firebaseConfig);
const auth = getAuth();
const db = getFirestore();
if (process.env.REACT_APP_TARGET.toUpperCase() === 'DEVELOPMENT') {
connectAuthEmulator(
auth,
process.env.REACT_APP_EMULATOR_HOST + '/',
);
connectFirestoreEmulator(db, 'localhost', '8080');
}
export { auth, db, firebaseConfig };
export default app;
I've a deployed a callable function, say foo, using
firebase deploy --only functions:foo
and I'm calling it in Flutter using:
var result = await FirebaseFunctions.instance.httpsCallable('foo')();
var data = result.data;
All good. But I'd like to run this function in the Firebase Emulator. When I run
firebase emulators:start --only functions
I can see the emulator up and running, and I'm connecting my Flutter app to the emulator using:
FirebaseFunctions.instance.useFunctionsEmulator('localhost', 4000);
However, I don't know how to invoke the callable foo in Flutter using the Firebase Emulator. I saw this related thread but it doesn't really answer my question.
EDIT:
Here's the console output:
✔ functions[us-central1-foo]: http function initialized (http://localhost:5001/my_project/us-central1/foo).
┌─────────────────────────────────────────────────────────────┐
│ ✔ All emulators ready! It is now safe to connect your app. │
│ i View Emulator UI at http://localhost:4000 │
└─────────────────────────────────────────────────────────────┘
┌───────────┬────────────────┬─────────────────────────────────┐
│ Emulator │ Host:Port │ View in Emulator UI │
├───────────┼────────────────┼─────────────────────────────────┤
│ Functions │ localhost:5001 │ http://localhost:4000/functions │
├───────────┼────────────────┼─────────────────────────────────┤
│ Firestore │ localhost:8080 │ http://localhost:4000/firestore │
└───────────┴────────────────┴─────────────────────────────────┘
Emulator Hub running at localhost:4400
Other reserved ports: 4500
I tried
useFunctionsEmulator('localhost', 4000);
useFunctionsEmulator('localhost', 5001);
but both of them throw the following error on calling httpsCallable('foo') but without the emulators, this function does work.
[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: [firebase_functions/unavailable] UNAVAILABLE
I suspect your host and port values might be incorrect.
When you start up your emulator, the logs will display all the ports that are being used for your various emulators. There's also the firebase.json file that has the port configurations for the emulators.
Also, localhost is not automatically identified by the clients. For Android you might have to configure networkSecurityConfig in your manifest by creating a network security config xml. For iOS, I think there should be something that needs to be added in the plist file - has to be checked confirmed.
Once your clients are able to access localhost (implicitly or explicitly), you can connect to your emulated functions. For example, I have explicitly state the host value in my code (this is not expected to change across restarts).
Here is the code that I use in Kotlin:
functions = FirebaseFunctions.getInstance()
/*
* Emulator
* */
if (emulatorMode) { //Local Testing
functions.useEmulator("10.0.2.2", 5001)
} else { //Live
functions = Firebase.functions
}
// Call the function and extract the operation from the result
return functions
.getHttpsCallable(function)
.call(inputData)
.continueWith { task ->...
It doesn't seem like a port or setup issue to me. Your console seems to show the expected output.
Try this:
Inside Flutter, where you want to call the function, add:
http.get(Uri.parse('http://localhost:5001/my_project/us-central1/foo'))
You're going to have to set an env variable, that asks your application to check what environment it is in. If dev, then it should use url above, if prod it can use the prod url
this._cloudFunctions = FirebaseFunctions.instance;
_cloudFunctions.useFunctionsEmulator(origin: "http://<System's IP>:5001");
Systems ip we can get by typing ipconfig in command prompt.
Make sure you connect your ip and run emulators start.
For Flutter
As per the Firebase Flutter Docs-
There is a useFunctionsEmulator module as part of your Firebase Functions instance.
You can initialize it as follows:
FirebaseFunctions.instance.useFunctionsEmulator('localhost', 5001);
For Web
If you cd into the functions directory you can run npm start which will, by default, build and run the emulators locally in the shell. I've found this to be the only solution for testing callable functions locally.
The firebase team has provided a connectFunctionsEmulator submodule in the V9 modular SDK which is designed specifically to interact with your app locally.
You can checkout the official docs for this Here.
Running npm run serve will serve the emulator that you are expecting but I have been running into issues testing callable functions via url.
I have a serverless REST API that uses NodeJS and Google Cloud Functions (Firebase). It works on production. But not locally for testing.
The app was created following the tutorial at: https://dev.to/levivm/creating-a-serverless-rest-api-using-google-cloud-functions-firebasefirestore-in-10-min-37km
When the firebase emulator is started locally the API endpoint seems not to work, and an error is returned:
URL http://my_local_server:8080/api/v1/my_api_route.
Output: Cannot GET /api/v1/my_api_route
The root url returns: http://my_local_server:8080/
{"status":"alive"}
Do you know what might cause the issue?
$ firebase emulators:start --only functions
i emulators: Starting emulators: functions
✔ functions: Using node#10 from host.
✔ functions: Emulator started at 0.0.0.0:8080
i functions: Watching "/home/ubuntu/environment/Crew-IQ/functions" for Cloud Functions...
⚠ functions: The Cloud Firestore emulator is not running, so calls to Firestore will affect production.
✔ functions[webApi]: http function initialized (0.0.0.0:8080/crew-iq/us-central1/w...).
✔ All emulators started, it is now safe to connect.
For that application, the endpoint would be
http://localhost:8080/crew-iq/us-central1/webApi/api/v1/my_api_route
└───┬───┘ └─┬┘ └──┬──┘ └────┬────┘ └──┬─┘└─────────┬────────┘
host │ │ │ │ │
port │ │ │ │
project ID │ │ │
function region │ │
function name │
your express app
I'm trying to debug firebase function on my local windows
as described in https://medium.com/#mwebler/debugging-firebase-functions-with-vs-code-3afab528bb36
I do
set FIREBASE_CONFIG={ databaseURL: 'https://invoice-manager-251609.firebaseio.com', storageBucket: 'invoice-manager-251609.appspot.com', projectId: 'invoice-manager-251609'}
functions start
and get
┌────────┬────────┬─────────┬─────────────────────────────────────────────────────────────────┐
│ Status │ Name │ Trigger │ Resource │
├────────┼────────┼─────────┼─────────────────────────────────────────────────────────────────┤
│ FAILED │ upload │ HTTP │ http://localhost:8010/invoice-manager-251609/us-central1/upload │
├────────┼────────┼─────────┼─────────────────────────────────────────────────────────────────┤
│ FAILED │ tst │ HTTP │ http://localhost:8010/invoice-manager-251609/us-central1/tst │
├────────┼────────┼─────────┼─────────────────────────────────────────────────────────────────┤
│ FAILED │ tst1 │ HTTP │ http://localhost:8010/invoice-manager-251609/us-central1/tst1 │
└────────┴────────┴─────────┴─────────────────────────────────────────────────────────────────┘
if I do
firebase emulators:start
I get
undefinedWarning, estimating Firebase Config based on GCLOUD_PROJECT.
Initializing firebase-admin may fail[2019-10-06T11:44:51.932Z]
#firebase/database: FIREBASE FATAL ERROR: Cannot parse Firebase url.
Please use https://.firebaseio.com
I also tried:
functions debug tst1
and get:
ERROR: Function worker crashed with exit code: 9
undefined(node:21096) [DEP0062] DeprecationWarning: `node --debug
and
node --debug-brkare invalid. Please usenode --inspectornode --inspect-brk` instead.
I tried with node-10 and node-8
I also tried this:
https://medium.com/#david_mccoy/build-and-debug-firebase-functions-in-vscode-73efb76166cf
and this
https://rominirani.com/google-cloud-functions-tutorial-debugging-local-functions-357c24829198
I get the same errors
whats going on?
how do I debugging firebase on local windows?
The guides in the question are correct, but
when running in Emulator, u have to set the db url manually
admin.initializeApp({
databaseURL: "https://<YOUR FIREBASE>.firebaseio.com"
});
here is the full cmd list:
functions start
functions deploy --trigger-http --timeout 600s funcName
functions inspect funcName
After that u can use chrome://inspect/ to connect to the process with the chrome debugger.
If you have issues, u can use:
functions logs read
NOTE: after functions start I still get the table with FAILED status - I ignore it
Goal
Use the firebase emulator and deploy firebase cloud functions locally for test and debug.
Issue
When firebase serve is run, it fails with - Error: Certificate object must be an object.
What's been tried
Following Google's documentation here, the instructions include
these steps:
To set up admin credentials for emulated functions (other than Cloud
Firestore and Realtime Database):
Open the Service Accounts pane of the Google Cloud Console.
Make sure that App Engine default service account is selected, and use the options menu at right to select Create key.
When prompted, select JSON
for the key type, and click Create. Set your Google default
credentials to point to the downloaded key:
$ export GOOGLE_APPLICATION_CREDENTIALS="path/to/key.json"
$ firebase functions:shell
OR
$ firebase serve --only functions
Completing these instructions and running firebase serve... fails. Here are the logs:
Silver-Sliver:functions dchaddportwine$ firebase serve --only functions
=== Serving from '/Users/dchaddportwine/Sites/people-is-cloud-functions/functions'...
i functions: Preparing to emulate functions.
Warning: You're using Node.js v8.11.1 but Google Cloud Functions only supports v6.11.5.
⚠ functions: Failed to load functions source code. Ensure that you have the latest SDK by running npm i --save firebase-functions inside the functions directory.
⚠ functions: Error from emulator. Error occurred while parsing your function triggers.
Error: Certificate object must be an object.
at FirebaseAppError.FirebaseError [as constructor] (/Users/dchaddportwine/Sites/people-is-cloud-functions/functions/node_modules/firebase-admin/lib/utils/error.js:39:28)
at FirebaseAppError.PrefixedFirebaseError [as constructor] (/Users/dchaddportwine/Sites/people-is-cloud-functions/functions/node_modules/firebase-admin/lib/utils/error.js:85:28)
at new FirebaseAppError (/Users/dchaddportwine/Sites/people-is-cloud-functions/functions/node_modules/firebase-admin/lib/utils/error.js:119:28)
at new Certificate (/Users/dchaddportwine/Sites/people-is-cloud-functions/functions/node_modules/firebase-admin/lib/auth/credential.js:106:19)
at new CertCredential (/Users/dchaddportwine/Sites/people-is-cloud-functions/functions/node_modules/firebase-admin/lib/auth/credential.js:189:64)
at Object.cert (/Users/dchaddportwine/Sites/people-is-cloud-functions/functions/node_modules/firebase-admin/lib/firebase-namespace.js:220:58)
at Object.<anonymous> (/Users/dchaddportwine/Sites/people-is-cloud-functions/functions/index.js:21:32)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
Question
How do I fix these two errors?
I have firebase-functions installed, and have tried npm i --save firebase-functions
⚠ functions: Failed to load functions source code. Ensure that you have the latest SDK by running npm i --save firebase-functions inside the functions directory.
Thinking this has to do with GOOGLE_APPLICATION_CREDENTIALS, but I'm not sure how to verify or check what's happening here.
⚠ functions: Error from emulator. Error occurred while parsing your function triggers.
Error: Certificate object must be an object.
UPDATE
Further along in the documentation, it reads:
If you're using custom functions configuration variables, run the
following command in the functions directory of your project before
running firebase serve.
firebase functions:config:get > .runtimeconfig.json
After running this command, I no longer get the certificate error. Woot! However, I am getting new failures and not many hints from the logs.
=== Serving from '/Users/dchaddportwine/Sites/people-is-cloud-functions/functions'...
i functions: Preparing to emulate functions.
i hosting[development-is]: Serving hosting files from: ./
✔ hosting[development-is]: Local server: http://localhost:5000
Warning: You're using Node.js v8.11.1 but Google Cloud Functions only supports v6.11.5.
⚠ functions: Failed to emulate app
⚠ functions: Failed to emulate helloSlack
⚠ functions: Failed to emulate helloIssy
⚠ functions: Failed to emulate interactiveIssy
i functions: No HTTPS functions found. Use firebase functions:shell if you would like to emulate other types of functions.
Code
Here is the firebase cloud functions for helloSlack
exports.helloSlack = functions.https.onRequest((req, res) => {
if (req) {
res.status(200).send(req.body);
} else {
console.log("req Error...");
throw res.status(500);
}
});
Answer
Further along in the documentation, it reads:
If you're using custom functions configuration variables, run the
following command in the functions directory of your project before
running firebase serve.
firebase functions:config:get > .runtimeconfig.json
This project is using custom functions configuration variables. So, after running the config command, I no longer get the certificate error. Woot!