Angular 11 Firebase 服务器端呈现无限加载/挂起

标签 angular firebase server-side-rendering angular-universal

我有一个 Angular 11 应用程序,它可以正常运行,即在非 SSR 模式下。 这是一个查询文档集合的示例,类型为 T(获取一次,不观察更改)。

在非 SSR 中工作的版本,查询一次集合的预期代码:

this.firestore.collection<T>('collection', ref => ref.limit(5))
    .get()
    .pipe(
      map((qs: firebase.firestore.QuerySnapshot) => qs.empty ? [] : qs.docs.map(d => d.data() as T)),
    );

当切换到 SSR 时,上面的代码会导致 express 服务器挂起,并且客户端会看到一个永远不会完成的“待处理”查询,或者超时并使页面部分呈现(即没有该查询的结果) .

我将 Angular 11 与 Ivy 结合使用。 我的 package.json 中的相关条目:

{
  "dependencies": {
    "@angular/cdk": "^11.0.3",
    "@angular/common": "~11.0.5",
    "@angular/compiler": "~11.0.5",
    "@angular/core": "~11.0.5",
    "@angular/fire": "6.1.4",
    "@angular/flex-layout": "^11.0.0-beta.33",
    "@angular/forms": "~11.0.5",
    "@angular/material": "^11.0.3",
    "@angular/platform-browser": "~11.0.5",
    "@angular/platform-browser-dynamic": "~11.0.5",
    "@angular/platform-server": "~11.0.5",
    "@angular/router": "~11.0.5",
    "@nguniversal/express-engine": "^11.0.1",
    "bootstrap": "^4.5.2",
    "express": "^4.17.1",
    "firebase": "^8.2.1",
    "rxjs": "~6.6.3",
    "tslib": "^2.0.0",
    "zone.js": "~0.10.3"
  },
  "devDependencies": {
    "@angular-builders/custom-webpack": "^11.0.0-beta.4",
    "@angular-devkit/architect": "~0.1100.5",
    "@angular-devkit/build-angular": "~0.1100.5",
    "@angular/cli": "~11.0.5",
    "@angular/compiler-cli": "~11.0.5",
    "@nguniversal/builders": "^11.0.1",
    "@ngx-builders/analyze": "^2.0.0",
    "@types/express": "^4.17.0",
    "@types/node": "^12.11.1",
    "bufferutil": "^4.0.2",
    "firebase-tools": "^9.0.1",
    "ts-node": "~9.1.1",
    "typescript": "~4.0.5",
    "utf-8-validate": "^5.0.3",
    "ws": "^7.4.1",
    "xhr2": "^0.2.0"
  }
}

在 angular.json 的 server.options 字段中,我必须添加以下内容以减轻以下错误 ENOENT: no such file or directory, open '.../dist/server/src/protos/google/firestore/v1/firestore.proto'

externalDependencies: [
              "@firebase/analytics",
              "@firebase/analytics-types",
              "@firebase/app",
              "@firebase/app-types",
              "@firebase/auth",
              "@firebase/auth-interop-types",
              "@firebase/auth-types",
              "@firebase/component",
              "@firebase/database",
              "@firebase/database-types",
              "@firebase/firestore",
              "@firebase/firestore-types",
              "@firebase/functions",
              "@firebase/functions-types",
              "@firebase/installations",
              "@firebase/installations-types",
              "@firebase/logger",
              "@firebase/messaging",
              "@firebase/messaging-types",
              "@firebase/performance",
              "@firebase/performance-types",
              "@firebase/polyfill",
              "@firebase/remote-config",
              "@firebase/remote-config-types",
              "@firebase/storage",
              "@firebase/storage-types",
              "@firebase/util",
              "@firebase/webchannel-wrapper"]

最佳答案

经过很长时间的调试 session 后,我将问题的根源缩小到问题中列出的 Firebase 查询。以下查询是一种解决方法,它可以在不挂起的情况下呈现页面。

this.firestore.collection<T>('collection', ref => ref.limit(5))
    .valueChanges()   <<<<
    .pipe(
      take(2),        <<<<
    );

使调试变得困难的一个方面是因为下面的更理智的版本关闭了可观察到的源导致服务器也挂起(记住,我不想观察变化,所以采取(1 ) 是有道理的)。 Take(2) 但是,不会挂起...这看起来像是堆栈中某处的错误,可能在 Firebase 中。

这将是更明智的解决方法...但会导致 express 服务器挂起,给客户端留下一个待处理请求:

this.firestore.collection<T>('collection', ref => ref.limit(5))
    .valueChanges()
    .pipe(
      take(1),      <<<<
    );

使用 promises 也会导致挂起,所以我目前只能使用 valueChanges()+take(2) 解决方法。

关于Angular 11 Firebase 服务器端呈现无限加载/挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65388261/

相关文章:

Angular 键值管道排序属性/按顺序迭代

angular - akka-http + angular2 路由

javascript - 如何在 Firebase 数据库 update() 方法上动态指定 'key' 名称?

android - 如何将多张图片上传到 Firebase

javascript - 使用 Next.js react onClick 事件处理程序不工作

node.js - 无法在 React 应用程序中导入图像 "Invalid or unexpected token"

python - Angular-cli 与任何其他服务器

angular - Angular 中 ViewContainerRef 类的 "detach"方法到底做了什么?

android - com.android.build.api.transform.TransformException : java. util.zip.ZipException : duplicate entry: com/google/android/gms/internal/zzbn. 类

javascript - NextJS 中的 EditorJS 无法加载插件