firebase-functions: 0.8.2
firebase-tools: 3.17.6
firebase-admin: 5.8.2
node -v: 6.9.5
npm -v: 5.0.3
I've tried to use simple import-statements, compile the file using babel-cli and deploy the compiled code to firebase.
For readability, I'll provide you with the uncompiled and compiled source code. I am very certain that this is not an issue with babel-cli, as e.g. the import statement from firebase-admin works and I also did not encounter any issues with other projects and a similar setup of babel.
Nevertheless, I am new to firebase and it could be an issue on my side. If there are any more information you need/would like to have, please let me know.
index.src.js
import admin from 'firebase-admin';
import functions from 'firebase-functions';
admin.initializeApp(functions.config().firebase);
.babelrc
{
"presets": ["env"]
}
index.js
'use strict';
var _firebaseAdmin = require('firebase-admin');
var _firebaseAdmin2 = _interopRequireDefault(_firebaseAdmin);
var _firebaseFunctions = require('firebase-functions');
var _firebaseFunctions2 = _interopRequireDefault(_firebaseFunctions);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_firebaseAdmin2.default.initializeApp(_firebaseFunctions2.default.config().firebase);
Result:
"TypeError: Cannot read property 'config' of undefined"
Either:
a) Use the above index.js for your functions and deploy it, or
b) Use the above .babelrc and the index.src.js to generate index.js and deploy it.
I received the error message:
TypeError: Cannot read property 'config' of undefined
at Object.<anonymous> (index.js:13:66)
I would expect that the deployment succeeds without any error message. The deployed service would have 0 functions, but the deploy itself should succeed.
Instead of suceeding, the deployment fails because functions is undefined instead of
containing the exports from the firebase-functions module. On the other hand, the same import-statement works fine with the firebase-admin module - and i did not encounter similar issues so far with other modules.
The firebase-debug.log:
[debug] [2018-03-14T17:44:17.451Z] ----------------------------------------------------------------------
[debug] [2018-03-14T17:44:17.467Z] Command: C:\Program Files\nodejs\node.exe C:\Users\Username\AppData\Roaming\npm\node_modules\firebase-tools\bin\firebase deploy --only functions
[debug] [2018-03-14T17:44:17.467Z] CLI Version: 3.17.6
[debug] [2018-03-14T17:44:17.467Z] Platform: win32
[debug] [2018-03-14T17:44:17.467Z] Node Version: v6.9.5
[debug] [2018-03-14T17:44:17.467Z] Time: Wed Mar 14 2018
[debug] [2018-03-14T17:44:17.467Z] ----------------------------------------------------------------------
[debug]
[debug] [2018-03-14T17:44:17.513Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
[debug] [2018-03-14T17:44:17.529Z] > authorizing via signed-in user
[debug] [2018-03-14T17:44:17.529Z] >>> HTTP REQUEST GET https://admin.firebase.com/v1/projects/my-project
Wed Mar 14 2018
[debug] [2018-03-14T17:44:18.092Z] <<< HTTP RESPONSE 200
[debug] [2018-03-14T17:44:18.092Z] >>> HTTP REQUEST GET https://admin.firebase.com/v1/database/my-project/tokens
Wed Mar 14 2018
[debug] [2018-03-14T17:44:18.467Z] <<< HTTP RESPONSE 200
[info]
[info] === Deploying to 'my-project'...
[info]
[info] i deploying functions
[info] Running command: npm --prefix "$RESOURCE_DIR" run lint
[info] + functions: Finished running predeploy script.
[debug] [2018-03-14T17:44:27.123Z] > [functions] package.json contents: {
"name": "functions",
"description": "Cloud Functions for my-project",
"scripts": {
"lint": "eslint .",
"serve": "firebase serve --only functions",
"shell": "firebase experimental:functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log",
"build": "node node_modules/babel-cli/bin/babel.js src/ --out-dir ./"
},
"dependencies": {
"firebase-admin": "^5.8.2",
"firebase-functions": "^0.8.1"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-preset-env": "^1.6.1",
"eslint": "^4.12.0",
"eslint-plugin-promise": "^3.6.0"
},
"private": true
}
[info] i functions: ensuring necessary APIs are enabled...
[debug] [2018-03-14T17:44:27.123Z] >>> HTTP REQUEST GET https://servicemanagement.googleapis.com/v1/services/cloudfunctions.googleapis.com/projectSettings/my-project?view=CONSUMER_VIEW
Wed Mar 14 2018
[debug] [2018-03-14T17:44:27.123Z] >>> HTTP REQUEST GET https://servicemanagement.googleapis.com/v1/services/runtimeconfig.googleapis.com/projectSettings/my-project?view=CONSUMER_VIEW
Wed Mar 14 2018
[debug] [2018-03-14T17:44:27.920Z] <<< HTTP RESPONSE 200
[debug] [2018-03-14T17:44:27.936Z] <<< HTTP RESPONSE 200
[info] + functions: all necessary APIs are enabled
[debug] [2018-03-14T17:44:27.936Z] >>> HTTP REQUEST GET https://cloudresourcemanager.googleapis.com/v1/projects/my-project
Wed Mar 14 2018
[debug] [2018-03-14T17:44:28.422Z] <<< HTTP RESPONSE 200
[debug] [2018-03-14T17:44:28.422Z] >>> HTTP REQUEST GET https://mobilesdk-pa.googleapis.com/v1/projects/some-numeric-id:getServerAppConfig
Wed Mar 14 2018
[debug] [2018-03-14T17:44:28.912Z] <<< HTTP RESPONSE 200
[info] i functions: preparing functions directory for uploading...
[debug] [2018-03-14T17:44:28.927Z] >>> HTTP REQUEST GET https://runtimeconfig.googleapis.com/v1beta1/projects/my-project/configs
Wed Mar 14 2018
[debug] [2018-03-14T17:44:29.406Z] <<< HTTP RESPONSE 200
Okay, I've debugged a little bit further. The following source code also compiles and deploys successfully:
import admin from 'firebase-admin';
const functions = require('firebase-functions');
admin.initializeApp(functions.config().firebase);
I was capable to pinpoint the problem down to the ".default"-usage: If, in the compiled source code, the erroneous line (13) gets changed to the following:
_firebaseAdmin2.default.initializeApp(_firebaseFunctions2.config().firebase);
it seems to work. Therefore, the problem is that _firebaseFunctions2.default is undefined. Unfortunately, I have to stop at this point as I do not understand enough about how ES6-modules work internally, and what exactly the function _interopRequireDefault() is required for - and why it checks for obj.__esModule. Maybe someone with more knowledge to that could help me out?
At this point, I am unsure if this is a bug or a feature request - as most other modules seem to work with that kind of import structure, but firebase-functions doesnt. I never noticed that I had to do anything special on my own modules so that they work, so I am a little bit confused right now :D
@SargTeX
Hey, I ran into this problem while converting require to import/export.
In es6, there are different ways of importing. There are also different methods of exporting. When you export like this export { name1, name2, …, nameN };, it exports an object of key/value pairs. When you export like this export default expression;, I think it sets the key 'default' to the expression.
When you import like this import defaultExport from "module-name";, it reads the value at the default key. When you import like this import * as name from "module-name"; it'll read in all the key/value pairs.
config must not be the default export, that's why it didn't work. require must be catching both scenarios, that's why using require works.
My solution is:
import * as functions from 'firebase-functions'; // <-- solution
/* eslint-disable-next-line import/no-mutable-exports */
let config;
if (!functions || process.env.NODE_ENV === ('silent' || 'test')) {
// handle local unit testing
config = {};
} else {
config = functions.config();
}
export default config;
update:
If you checkout the source code, you'll see that there is no default export.
Thanks for stepping in @jhu7235 !
You can also do import { config } from 'firebase-functions'
You can add other imports to that list, for example:
import {config, database, firestore} from 'firebase-functions'
Most helpful comment
@SargTeX
Hey, I ran into this problem while converting require to import/export.
In es6, there are different ways of importing. There are also different methods of exporting. When you export like this
export { name1, name2, …, nameN };, it exports an object of key/value pairs. When you export like thisexport default expression;, I think it sets the key 'default' to the expression.When you import like this
import defaultExport from "module-name";, it reads the value at the default key. When you import like thisimport * as name from "module-name";it'll read in all the key/value pairs.config must not be the default export, that's why it didn't work. require must be catching both scenarios, that's why using require works.
My solution is:
update:
If you checkout the source code, you'll see that there is no default export.