迁移Angular Universal firebase后云函数引发错误

问题描述 投票:0回答:3

我有一个SPA托管在Firebase中,并且我一直在使用Firestore来存储数据。我还在一些https操作和某些其他数据库读写操作中使用了云功能。

最近,我使用angular Universal从客户端到服务器端更新了渲染逻辑,这非常成功。这是我关注的链接:https://fireship.io/lessons/angular-universal-firebase/

基本上,我已经创建了一个https函数来在云函数中呈现ssr。

const universal = require(`${process.cwd()}/dist/server`).app;
exports.api = functions.https.onRequest(app); //Application related endpoint line makepayment, createorder etc.,
exports.ssr = functions.https.onRequest(universal);

现在,一旦我部署了此功能,就可以使用我以前用来访问api https的所有db.collection功能或db.doc开始抛出错误。以下是对db.doc的相同调用。

db.doc("samplecollection/docid")
.get()
.then(function (doc) {
   console.log('doc.data', doc.data());
})
.catch(function (error) {
   console.log('Error in fetching samplecollection doc', error);
});

现在,当我尝试执行上述操作时,出现以下错误。

Error in autogenerated TypeError [ERR_INVALID_ARG_TYPE]: The "path"
 argument must be of type string. Received type object
      at validateString (internal/validators.js:125:11)
      at Object.basename (path.js:744:5)
      at GrpcClient.loadProto (sampleproject\functions\node_modules\google-gax\build\src\grpc.js:133:29)
      at new FirestoreClient (sampleproject\functions\node_modules\@google-cloud\firestore\build\src\v1\firestore_client.js:121:32)
      at ClientPool.Firestore._clientPool.pool_1.ClientPool [as clientFactory]
 (sampleproject\functions\node_modules\@google-cloud\firestore\build\src\index.js:302:26)
      at ClientPool.acquire (sampleproject\functions\node_modules\@google-cloud\firestore\build\src\pool.js:67:35)
      at ClientPool.run (sampleproject\functions\node_modules\@google-cloud\firestore\build\src\pool.js:124:29)
      at Firestore.readStream (sampleproject\functions\node_modules\@google-cloud\firestore\build\src\index.js:947:26)
      at Firestore.getAll_ (sampleproject\functions\node_modules\@google-cloud\firestore\build\src\index.js:680:14)
      at initializeIfNeeded.then (sampleproject\functions\node_modules\@google-cloud\firestore\build\src\index.js:650:61)
      at ZoneDelegate.invoke (sampleproject\functions\dist\server.js:5715:30)
      at Zone.run (sampleproject\functions\dist\server.js:5472:47)
      at sampleproject\functions\dist\server.js:6213:38
      at ZoneDelegate.invokeTask (sampleproject\functions\dist\server.js:5750:35)
      at Zone.runTask (sampleproject\functions\dist\server.js:5517:51)
      at drainMicroTaskQueue (sampleproject\functions\dist\server.js:5930:39)
      at process._tickCallback (internal/process/next_tick.js:68:7)

我不确定错误为什么说“ path”参数必须为字符串类型。收到类型对象。我试图将文档的路径分配给变量,并使用typeof检查其类型,它仍然显示为string

要注意的关键点是-如果我删除复制到ssr目录中的dist,函数和functions文件夹,则具有相同代码行的所有内容都可以正常工作。因此,我强烈怀疑这与SSR有关。

我在Google上进行了很多搜索,但是没有一个这样的SSR设置。有人可以为我指出正确的方向,还是让我知道是否有人面对过Angular Universal SSR的问题并找到了解决方案?


更新-1

我在webpack.server.config.js文件中设置了以下选项。那会是个问题吗?

node: {
    __dirname: false
},

更新-2

这是为开发和生产环境配置的firebase.json。

{
  "hosting": [
    {
      "public": "dist/browser",
      "target": "staging",
      "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
      "rewrites": [
        {
          "source": "**",
          "function": "ssr"
        }
      ],
      "headers": [
        {
          "source": "**/*.@(jpg|jpeg|gif|png|svg|js|css|css?*|eot|otf|ttf|ttc|woff|woff2)",
          "headers": [
            {
              "key": "Access-Control-Allow-Origin",
              "value": "*"
            },
            {
              "key": "Cache-Control",
              "value": "max-age=31536000"
            }
          ]
        },
        {
          "source": "404",
          "headers": [
            {
              "key": "Cache-Control",
              "value": "max-age=7200"
            }
          ]
        }
      ]
    },
    {
      "public": "dist",
      "target": "production",
      "ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
      "rewrites": [
        {
          "source": "**",
          "destination": "/index.html"
        }
      ]
    }
  ],
  "functions": {
    "include": ["**/views/**"]
  }
}

现在,我刚刚在staging中配置了此功能,即在[开发环境]中进行了测试,但是此问题甚至影响了生产环境,因为两者的云功能都将保持不变。

更新-3

[进一步调查后,我发现node_modules依赖项的functions中的firestore_client.js在路径node_modules/@google-cloud/firestore/build/src/v1下具有下面的代码段,以标识其是否是浏览器。

const isBrowser = typeof window !== 'undefined';
if (isBrowser) {
    opts.fallback = true;
}
.....
.....
.....
// Load the applicable protos.
// For Node.js, pass the path to JSON proto file.
// For browsers, pass the JSON content.
const nodejsProtoPath = path.join(__dirname, '..', '..', 'protos', 'protos.json');
const protos = gaxGrpc.loadProto(opts.fallback ? require('../../protos/protos.json') : nodejsProtoPath);

因此firestore_client.js通过检查typeof window !== undefined来确定这是否是浏览器。但是,在我的SPA的server.ts中,我已经从global['window'] = win库中定义了domino。添加它是因为它将抛出[window is not defined ReferenceError。

[基本上,这意味着firestore_client.js可以通过window确定并生成server.js文件夹中的对象,并因此将functions文件内容作为对象,而不是通过protos.json确定对象。路径。阅读上述文件中的注释,我觉得应该在此处传递文件的路径,而不是在nodejs环境中使用的对象。

任何想法,现在我该如何克服?

node.js angular firebase google-cloud-firestore angular-universal
3个回答
1
投票

所以我有2个要丢在那里的选项,希望其中一个可以使用。

  1. 尝试旧版本:卸载当前安装:
npm uninstall @angular/fire firebase --save

然后安装旧版本,我在下面做了:

npm install @angular/[email protected] [email protected] --save
  1. 不确定您的webpack.server.config中是否包含此内容:
module.exports = {
...
 resolve: {
    alias: {
      ['firebase/app']: path.resolve(__dirname, 'node_modules/firebase/app/dist/index.cjs.js')
    }
  }
...
}

0
投票

[[因此,经过几天的研究,我不得不遵循一种肮脏的方法使SPA才能在SSR应用程序的云功能中工作。

正如我在最新的帖子中提到的那样,在所有情况下,我都必须将opts.fallback设置为假。我这样做是为了确保@google-cloud仅存在于我的应用程序中的functions中。现在看起来像下面:

const isBrowser = typeof window !== 'undefined'; if (isBrowser) { opts.fallback = true; } opts.fallback = false; //Added this line.

现在,一切正常。但是,最终,这是最肮脏的方法。

我仍然对@google/cloud下的某些内容感到困惑,因为我注意到也有

firestore_admin_client.js文件,并且不确定何时调用该文件。另外,我担心这种方法将来是否会引起任何安全漏洞。

无论如何,如果将来在调试时发现任何问题,我会及时发布。

嗯,当我将该功能部署到云时,上述方法似乎失败了。只有在firebase serve

下才能在本地使用

0
投票
不是您想要的答案,而是将其发布。

前一段时间,我尝试了基本相同的方法。我使用Firebase身份验证和实时数据库而不是Firestore。另外,我使用了AngularFire2。我不确定您是否也在使用此功能。构建很好,但是我总是会遇到运行时异常。

我发现有多个声明声称Firebase身份验证和实时日期库不能用于ssr的语句,因为它取决于某些浏览器功能。不幸的是我现在找不到它们。不知道这是与Firebase相关还是与AngularFire相关。

我搜索有关ssr与实时数据库结合的多个教程/帖子。除了一个,我什么也找不到。 This指南介绍了如何将Firestore与SSR结合使用。区别在于他们使用的是AngularFireLite而不是AngularFire。

© www.soinside.com 2019 - 2024. All rights reserved.