Cloud Functions for Firebase using es6 import statement
Firebase CLI now supports node.js 14, but it does not mean one can write Cloud Functions as ES modules.
Missing pieces are:
firebase-functions
(3.13.1) npm module does not offer ES exportsFirebase emulator (
firebase-tools
9.2.2) does not load Cloud Functions that are ES modules:[emul] require() of /Users/.../functions/index.js from /usr/local/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Meta: While the suggested ways (esm
package; converting to TypeScript) may work for some, I'm personally interested only in pure ES module functionality. This is also in line with the title of the question ("... using es6 import statement"), so I decided to write a summary of current (Jan 2021) situation.
There is no direct payback from being able to code Cloud Functions as ES modules. It's just a syntactical thing: if I write my web app in them, and node supports them, naturally I would prefer using them also for Cloud Functions.
If it's dear to you, here is the ticket to follow/ð.
The short answer is, no, you can't do this - yet. It doesn't have anything to do with Cloud Functions. It has to do with node. If you point node at your index.js with the command node index.js
, you'll see the exact same error.
The long answer about why this is a complicated problem has been discussed in some blogs, for example here and here.
EDIT: The firebase CLI now supports projects using TypeScript, which gives you access to ES7 syntax. It will automatically compile that down to ES6 for deployment to Cloud Functions.
Ahh figured it out. To use ES6 features like import
and const
, and even ES7 features like await
and async
, use Typescript by renaming index.js
to index.ts
.
Here's my index.ts
:
import * as functions from 'firebase-functions';
export const helloWorld = functions.https.onRequest((req, resp) => {
resp.send("Hello from Firebase!");
});
I was also prompted by Atom to generate a functions/tsconfig.json
file. I'm not sure this was necessary, but here's what was generated:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"isolatedModules": false,
"jsx": "react",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"declaration": false,
"noImplicitAny": false,
"noImplicitUseStrict": false,
"removeComments": true,
"noLib": false,
"preserveConstEnums": true,
"suppressImplicitAnyIndexErrors": true,
"lib": ["es2015", "es2015.promise"]
},
"exclude": [
"node_modules",
"typings/browser",
"typings/browser.d.ts"
],
"compileOnSave": true,
"buildOnSave": false,
"atom": {
"rewriteTsconfig": false
}
}
Here's the output generated by firebase deploy --only functions
:
=== Deploying to 'PROJECTNAME'...
i deploying functions
i functions: ensuring necessary APIs are enabled...
i runtimeconfig: ensuring necessary APIs are enabled...
✔ runtimeconfig: all necessary APIs are enabled
✔ functions: all necessary APIs are enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (1.53 KB) for uploading
✔ functions: functions folder uploaded successfully
i starting release process (may take several minutes)...
i functions: creating function helloWorld...
✔ functions[helloWorld]: Successful create operation.
✔ functions: all functions deployed successfully!
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/PROJECTNAME/overview
Function URL (helloWorld): https://us-central1-PROJECTNAME.cloudfunctions.net/helloWorld