0

Recently, I tried migrating my firebase cloud functions from javascript to typescript and split the functions into multiple files. However, I keep getting errors while trying to serve as well as deploy:

Errors while serving:

functions[functionName]: function ignored because the firestore emulator does not exist or is not running. functions[functionName]: function ignored because the firebase emulator does not exist or is not running.

Error while deploying:

functions[dataDownload(us-central1)]: Deployment error.
Function failed on loading user code. Error message: Code in file lib/index.js can't be loaded.
Is there a syntax error in your code?
Detailed stack trace: /srv/node_modules/fs-extra/lib/mkdirs/make-dir.js:86
      } catch {
              ^

SyntaxError: Unexpected token {
    at createScript (vm.js:80:10)
    at Object.runInThisContext (vm.js:139:10)
    at Module._compile (module.js:617:28)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/srv/node_modules/fs-extra/lib/mkdirs/index.js:3:44)

Tried:
Firestore/Firebase Emulator Not Running (installed the emulators, did firebase init emulators)
unable to split Firebase functions in multiple files
Firestore local http with real db: The Cloud Firestore emulator is not running so database operations will fail with a 'default credentials' error
https://github.com/firebase/functions-samples/issues/170#issuecomment-586019131
How do I structure Cloud Functions for Firebase to deploy multiple functions from multiple files?
https://javebratt.com/functions-multiple-files/
https://firebase.google.com/docs/functions/typescript#migrating_an_existing_javascript_project_to_typescript

My directory structure:

--functions
    -- lib
    -- node_modules
    -- src
        -- config
        -- admin.ts
        -- index.ts
        -- dataDownload.ts
    -- tsconfig.json
    -- tslint.json
    -- package.json
    -- package-lock.json

--.firebaserc
-firebase.json
--package.json
--package-lock.json

The files:
index.ts:

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);

import { dataDownloadHandler } from './dataDownload';
export const dataDownload = functions.firestore.document('user/{uid}/download/{downloadId}').onCreate((snapshot, context) => {
    dataDownloadHandler(snapshot, context);
});

dataDownload.ts:

/* 
imports
*/
export const dataDownloadHandler = (snapshot:any, context:any) => {
    // code
}

Nor did it work when I moved dataDownload function into the dataDownload.ts file and did export * from './dataDownload; in index.ts.

admin.ts:

import * as admin from 'firebase-admin';

const auth = admin.auth();
const rtDb = admin.database();
const fsDb = admin.firestore();
const firebaseTimestamp = admin.database.ServerValue.TIMESTAMP;
const firestoreTimestamp = admin.firestore.FieldValue.serverTimestamp();

export { admin, auth, rtDb, fsDb, firebaseTimestamp, firestoreTimestamp };

package.json:

{
  "name": "functions",
  "engines": {
    "node": "8"
  },
  "description": "Cloud Functions for Firebase",
  "scripts": {
    "lint": "tslint --project tsconfig.json",
    "build": "tsc",
    "watch": "tsc --watch",
    "serve": "npm run build && firebase serve --only functions -P staging",
    "shell": "npm run build && firebase functions:shell",
    "start": "npm run shell",
    "deploy": "npm run build && firebase deploy --only functions",
    "logs": "firebase functions:log -P staging"
  },
  "main": "lib/index.js",
  "dependencies": {
    "firebase-admin": "^8.10.0",
    "firebase-functions": "^3.5.0",
    ...other dependencies
  },
  "devDependencies": {
    "eslint": "^5.16.0",
    "eslint-plugin-promise": "^4.2.1",
    "tslint": "^6.1.0",
    "typescript": "^3.8.3"
  },
  "private": true
}

firebase.json:

{
  "database": {
    "rules": "database.rules.json"
   },
  "hosting": [
   ...],
  "storage": {
    "rules": "storage.rules"
  },
  "functions": {
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint",
      "npm --prefix \"$RESOURCE_DIR\" run build"
    ],
    "source": "functions"
  },
  "emulators": {
    "functions": {
      "port": 5001
    },
    "firestore": {
      "port": 8080
    },
    "database": {
      "port": 9000
    },
    "hosting": {
      "port": 5000
    }
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "allowJs": true,
    "module": "commonjs",
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "outDir": "lib",
    "sourceMap": true,
    "strict": true,
    "target": "es2017"
  },
  "compileOnSave": true,
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
      "node_modules"
  ]
}

EDIT: https cloud functions work; firestore and database cloud functions don't.

Srividya K
  • 755
  • 6
  • 24

2 Answers2

5

If you are using "fs-extra": "^9.0.0" try to downgrade to version 8.1.0.

This fixed the problem for me.

lazos
  • 1,035
  • 1
  • 7
  • 17
  • 1
    It worked! Thanks. v9.0.0 requires node version >= 10 it seems, whereas cloud functions are still stable only for node v8 – Srividya K Apr 08 '20 at 11:41
0

I tried to reproduce it from your code samples, but everything got deployed properly.

According to this doc ( you have mentioned it as well) lib/index.js is:

During firebase deploy, your project's index.ts is transpiled to index.js, meaning that the Cloud Functions log will output line numbers from the index.js file and not the code you wrote. To make it easier for you to find the corresponding paths and line numbers in index.ts

So I suppose you should check what is going on there, how those files look on your side. Maybe you will be able to figure it out.

Also I've found to SO questions that might be helpfull:

class imported but still firebase deploy fails with Cannot find module

Firebase deploy can't find serviceAccountKey

Check if your references are not to local files and maybe you can try recreate your project locally and than deploy. I hope this will be helpful!

Henrik Heimbuerger
  • 9,924
  • 6
  • 56
  • 69
vitooh
  • 4,132
  • 1
  • 5
  • 16
  • Thanks. I realized that the issue in deployment was that one of the dependencies has syntax error. Removing it worked fine. However, testing it using serve still doesn't work. – Srividya K Mar 25 '20 at 18:10
  • Are you sure you running the emulator properly? I wasnt able to reproduce this error ... is there any additional error in the info? – vitooh Mar 26 '20 at 10:32
  • I removed node_modules, reauthenticated firebase, did npm install, and it's working now. Thank you for your time – Srividya K Mar 26 '20 at 10:37