迁移到打字稿后,Firebase 云功能无法正常工作

Posted

技术标签:

【中文标题】迁移到打字稿后,Firebase 云功能无法正常工作【英文标题】:Firebase cloud functions not working after migration to typescript 【发布时间】:2020-07-04 14:38:24 【问题描述】:

最近,我尝试将我的 firebase 云函数从 javascript 迁移到 typescript,并将这些函数拆分为多个文件。但是,在尝试服务和部署时,我不断收到错误:

投放时出错:

functions[functionName]:函数被忽略,因为 firestore 模拟器不存在或没有运行。 functions[functionName]:函数被忽略,因为 firebase 模拟器不存在或没有运行。

部署时出错

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)

试过了: Firestore/Firebase Emulator Not Running (安装了模拟器,做了firebase init模拟器)unable to split Firebase functions in multiple filesFirestore 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-586019131How 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

我的目录结构:

--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

文件: 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

当我将dataDownload 函数移动到dataDownload.ts 文件中并在index.ts 中执行export * from './dataDownload; 时,它也不起作用。

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"
  ]

编辑https 云功能有效; firestoredatabase 云函数没有。

【问题讨论】:

【参考方案1】:

我试图从您的代码示例中重现它,但一切都已正确部署。

根据这个doc(你也提到过)lib/index.js 是:

在 firebase 部署期间,您的项目的 index.ts 被转换为 index.js,这意味着 Cloud Functions 日志将输出 index.js 文件中的行号,而不是您编写的代码。为了方便大家在index.ts中找到对应的路径和行号

所以我想你应该检查那里发生了什么,这些文件在你身边的样子。也许你能弄清楚。

我还发现了一些可能有帮助的问题:

class imported but still firebase deploy fails with Cannot find module

Firebase deploy can't find serviceAccountKey

检查您的引用是否不是本地文件,也许您可​​以尝试在本地重新创建项目而不是部署。我希望这会有所帮助!

【讨论】:

谢谢。我意识到部署中的问题是其中一个依赖项有语法错误。删除它工作正常。但是,使用 serve 对其进行测试仍然不起作用。 你确定你的模拟器运行正常吗?我无法重现此错误...信息中是否还有其他错误? 我删除了 node_modules,重新验证了 firebase,安装了 npm,它现在可以工作了。感谢您的宝贵时间【参考方案2】:

如果您使用的是"fs-extra": "^9.0.0",请尝试降级到版本8.1.0

这解决了我的问题。

【讨论】:

成功了!谢谢。 v9.0.0 似乎需要节点版本 >= 10,而云功能仅对节点 v8 仍然稳定

以上是关于迁移到打字稿后,Firebase 云功能无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Firebase云函数打字稿

Firebase 或 APNS 无法正常工作

Firebase 云功能无法正确记录

无法部署“pubsub”云功能

迁移 Angular Universal firebase 后,云函数抛出错误

IOS 应用程序中的 Firebase 云消息传递 (FCM) 无法正常工作