35

Is there any way to use es6 syntax in Cloud Functions for Firebase?

import functions from 'firebase-functions';

export const helloWorld = functions.https.onRequest((request, response) => {
 response.send("Hello from Firebase!");
})

fails on:

SyntaxError: Unexpected token import

9 Answers 9

19

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.

Sign up to request clarification or add additional context in comments.

6 Comments

But they do it in the Google Cloud Next '17 presentation on firebase functions, I think by using Typescript. I'm just not sure how to use Typescript...
TypeScript just transpiles down to JavaScript. There is a compiler program tsc that takes your .ts files and converts them into .js files. Those JS files are what actually get deployed to Cloud Functions.
See my answer below - it was as simple as renaming the file (firebase-cli is apparently aware of typescript).
The firebase CLI is not aware of TypeScript. What you did was configure your editor to automatically generate JavaScript files from your TypeScript. These generated files are what makes your function actually operate as a Cloud Function.
Ooo, you're right. Atom automatically compiles Typescript to Javascript on save.
|
12

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

5 Comments

Bear in mind that if you do this, you are no longer writing JavaScript. You're writing TypeScript, and you're bound to the rules of that language, which is a superset of JS, and may evolve independently of JS. If you're writing TS, you cannot simply switch back to JS and expect everything to work. When TS transpiles to JS, you'll see that ultimately it uses regular old JS require statements to get imports to work.
Small note: Cloud Functions environment runs Node 6.9.1, which has full support for const. You can view other supported features at node.green
@DougStevenson true. waiting for cloud function in kotlin though. It's already the official android language (and better than java), so it's make sense to make cloud function also in kotlin for more seamless experience developing in google environment :) not to mention that being a js developer requires us to act like a psychic.
I get this error when i rename index "Error: functions/index.js does not exist, can't deploy Firebase Functions"
@AlxVallejo run tsc in cmd in your functions folder first to generate your index.js
8

Using ES modules is now experimental, to use ESM within a Cloud Function, you must declare "type": "module" within your package.json.

  ...
  "type": "module",
  ...
}

Then you can use import and export statements.
Reference: https://cloud.google.com/functions/docs/concepts/nodejs-runtime#using_es_modules_experimental
Code example: https://github.com/GoogleCloudPlatform/functions-framework-nodejs/blob/master/docs/esm/README.md

2 Comments

I can confirm this works, no need to use Typescript, we can use ES Modules and deploy Firebase functions without changing anything, except of course setting the type to module as @Roberto explained
I was able to deploy the functions with firebase deploy --only functions and it worked
7

Firebase CLI now supports node.js 14, but it does not mean one can write Cloud Functions as ES modules.

Missing pieces are:

  1. firebase-functions (3.13.1) npm module does not offer ES exports

  2. Firebase 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/👍.

3 Comments

thanks! this was exactly the information I was looking for!
Since Jan, some update(s) have made Firebase Functions as ESM to work.
might want to update the answer to reflect it now aorks
6

It is possible check this Link with full steps :

I. Deprecated : https://codeburst.io/es6-in-cloud-functions-for-firebase-959b35e31cb0

  1. Create ./functionsES6 and copy the package.json, yarn.lock and index.js into it from ./functions.

  2. Add the presets in ./functionsES6/package.json

enter image description here

  1. While you are in root path ./functionsES6 - Yarn Deploy

enter image description here

II. Updated : https://codeburst.io/es6-in-cloud-functions-for-firebase-2-415d15205468

You can use these in package.json

enter image description here

Comments

1

Simple method is use esm packahe https://www.npmjs.com/package/esm

require = require("esm")(module /*, options*/ )

Comments

1

Has been working for a while, now (firebase-functions 3.22.0; firebase-tools 11.2.1).

Comments

0

File: component.ts

exports.methodName = fn() => {}


File: index.ts (used to call all exportable functions)

... export * from './component.ts'; ...

This must solve part of using es6 for export functions.

Comments

-2

Using pure JS to import a library will fix it too.

Example:

var _ = require('lodash');

instead of:

import _ from 'lodash';

2 Comments

The question is not about how to fix the error. it's whether we can use es6 in google cloud functions
This answer is better than simply saying No. Upvote.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.