AngularFire2 firestore take(1) on doc valueChanges

Posted

技术标签:

【中文标题】AngularFire2 firestore take(1) on doc valueChanges【英文标题】: 【发布时间】:2018-03-21 03:33:45 【问题描述】:

使用 AngularFire2 我尝试从单个 Firestore 文档中获取数据。 有效的是

this.addressRef = afs.doc<Address>('addresses/key')
this.addressRef.valueChanges().subscribe(val => ......

我只想运行一次订阅代码。通常我使用 take(1) 来实现这一点(与 Firebase DB 一起使用)。 但是这段代码

this.addressRef.valueChanges().take(1).subscribe(val => ......

给出错误:TypeError:this.addressRef.valueChanges(...).take 不是函数。

VS Code 正在列出执行操作。这是 AngularFire2 中的错误,我做错了还是有其他(更好的)方法可以在获取数据后停止订阅?我也尝试过 topromise,但这也失败了。

【问题讨论】:

【参考方案1】:

更新

因为这个答案受到了很多关注,所以我提供了一个更新的答案。通常,在使用可观察对象进行编程时,您应该尝试进行反应式思考。有一些很棒的教程,但是this one is 很好。

新解决方案

user$ = this.afDs.doc<User>('users/NaGjauNy3vYOzp759xsc')
  .valueChanges().pipe(
    take(1) // Here you can limit to only emit once, using the take operator
  )

在你的模板中,你订阅了你的 observable。

(user$ | async).name

上下文

这种解决问题的方法有很多好处:

如果您不想转换数据,则只需输入地图运算符 您可以使用 rxjs 过滤器操作符过滤事件 根据 user$ 流创建其他流 易于调试,因为其他开发人员可以以更透明的方式查看您应用中的数据流

例如(创建另一个流,仅在用户是管理员时发出,并创建一个新标题):

adminTitle$ = this.user$.pipe(
  filter(user => user.title === 'admin'),
  map(user => `$user.name (admin)`)
)

旧答案

您可以通过执行以下操作来实现此目的:

this.userDoc = afDs.doc<User>('users/NaGjauNy3vYOzp759xsc');
this.userDoc.valueChanges()
  .pipe(take(1))
  .subscribe(v => 
    this.user = v;
  );

【讨论】:

好的,起初我在您的答案中没有看到太多新内容,因为我已经使用了相同的代码,但是 take() 在我的设置中不起作用。但是在研究了你的 stackblitz 之后,我发现我的导入是不同的。我猜它们是由 VC 自动生成的。我将“rxjs/operator/take”作为导入路径。如您的示例中所示,将其更改为“rxjs/add/operator/take”,现在 take() 可以工作了。所以感谢您提供完整的代码。我会进一步研究这些不同的路径。 现在每次您需要例如 user.uid 来编写其他代码时,您需要在订阅中执行此操作吗?这使得代码看起来很奇怪和嵌套。你不能从数据库中获取当前用户 uid 并在你的组件中使用它(所以不是 html)而不订阅? @Ruben 你还需要这方面的帮助吗?简短的回答是肯定的——你必须订阅。但是你不需要多次调用它:) @DauleDK 谢谢,我明白了,但我的代码看起来很奇怪,我的应用程序中几乎每个页面都需要当前登录的用户 UID,但我每次都需要订阅(一次),如果 UID 是一个全局变量,我可以在不使用订阅的情况下在任何地方访问它会更容易。我的大部分其他代码都应该在我获得 UID 后运行,所以这有点烦人 嗨@Ruben - 如果你问我,为了避免这种情况,你有两个选择。您可以将 UID 存储在浏览器存储中。在 Angular 中,您可以简单地执行 localStorage.setItem('uid', &lt;uid&gt;),然后在需要时执行 localStorage.getItem(uid)。您还可以创建一个服务,注入您的应用程序模块。请记住在用户注销时清除 uid :)

以上是关于AngularFire2 firestore take(1) on doc valueChanges的主要内容,如果未能解决你的问题,请参考以下文章

使用 Firestore/Angularfire2 或 Firestore SDK 查询集合中的内部对象 ID

AngularFire2 firestore take(1) on doc valueChanges

Firestore:将 angularfire2 异步数据传递为 Ionic 3 navParams 不起作用

使用 ionic 3 中的 Angularfire2 从 Firestore 获取集合文档的 ID [重复]

typescript 用于AngularFire2的角度Firebase模块样板(使用Firestore和存储)NgModule

如何使用 angularfire2 valuechanges 方法获取随机数据