如何只订阅 firebase 集合更改
How to only subscribe to firebase collection changes
我在 angular 应用中通过 @angular/fire
使用 firebase javascript SDK。
使用 angularfire Collection#stateChanges()
,我以为我 只是订阅了集合的状态变化 (根据描述)。 IE。在初始订阅时,不会 returned。但是,我发现 stateChanges() 会立即 return 收集集合中的所有内容,然后继续 return 状态更改。
有没有办法只订阅未来的状态变化而不是"replay"过去的变化(直接使用firebase-js-sdk
或通过@angular/fire
)?
例如,如果您已经下载了集合当前状态的副本,那么在简单地订阅集合更新时,您不希望重新下载集合状态。
感谢您的帮助!
您可能正在寻找的是集合的 stateChanges 方法。
来自文档:
Why would you use it? - The above methods return a synchronized array sorted in query order. stateChanges() emits changes as they occur rather than syncing the query order. This works well for ngrx integrations as you can build your own data structure in your reducer methods.
以及使用 @angular/fire
的代码示例:
this.angularFirestore
.collection('my-collection')
.stateChanges(['added', 'removed', updated']) // double check the state change references, these were assumed
.pipe(...);
目前,firebase 仅 不支持订阅查询更改。当您订阅查询时,您还必须立即下载所有相关文档(请参阅 firebase-js-sdk 存储库中的问题 #1551)。
话虽这么说,正如那个问题所指出的那样,您可以通过向文档添加 updatedAt
属性 并查询 updatedAt > now
所在的所有文档来伪造此功能。这将使您订阅未来的更改。
此解决方法的一个限制是 Firestore 仅支持在查询中的单个字段上使用不等式过滤器(>=
、<
等),因此使用您的不等式过滤器最多updatedAt
字段可能有问题。
以下方法是我在类似案例中使用的方法。
我有用户、组和组中用户的请求。
登录后,我获得了所需的数据(所有数据一目了然)。
但是对于登录用户,我需要订阅该组请求的任何插入、删除或编辑(不仅是 updated-at..)。
所以我创建了一个更改请求的集合。 (groupRequestsChanged)
我已订阅
collection('groupRequestsChanged').doc(group-id-here...).valueChanged().subscribe()
这种方法在某些情况下很有用。
我来晚了,但我通过首先获得尽可能多的文档来显示(分页),然后使用 stateChanges
订阅更改来处理这个问题。所以首先我做一些像
public displayedMessages: Array<any>;
this.db.collection('messages').ref.limitToLast(100).get().then(result => {
// display the result,
this.displayedMessages = result;
//then watch changes:
this.db.collection('messages').stateChanges().pipe(
skip(1),
map(changes => {
changes.forEach(itemDoc => {
if (itemDoc.type == 'added') {
this.displayedMessages.push(item);
} else if (itemDoc.type == 'modified') {
// find the message in displayedMessages and update the data
} else if (itemDoc.type == 'removed') {
// find the index and splice it.
}
})
})
)
})
这里的关键是 skip(1)
来自 rxjs。它会跳过第一个发出的值,即整个集合。你刚刚用 get
得到了全部,所以你不需要 stateChanges
的第一个发射。所以现在每次更改该集合时,您只会得到更改。
我在 angular 应用中通过 @angular/fire
使用 firebase javascript SDK。
使用 angularfire Collection#stateChanges()
,我以为我 只是订阅了集合的状态变化 (根据描述)。 IE。在初始订阅时,不会 returned。但是,我发现 stateChanges() 会立即 return 收集集合中的所有内容,然后继续 return 状态更改。
有没有办法只订阅未来的状态变化而不是"replay"过去的变化(直接使用firebase-js-sdk
或通过@angular/fire
)?
例如,如果您已经下载了集合当前状态的副本,那么在简单地订阅集合更新时,您不希望重新下载集合状态。
感谢您的帮助!
您可能正在寻找的是集合的 stateChanges 方法。 来自文档:
Why would you use it? - The above methods return a synchronized array sorted in query order. stateChanges() emits changes as they occur rather than syncing the query order. This works well for ngrx integrations as you can build your own data structure in your reducer methods.
以及使用 @angular/fire
的代码示例:
this.angularFirestore
.collection('my-collection')
.stateChanges(['added', 'removed', updated']) // double check the state change references, these were assumed
.pipe(...);
目前,firebase 仅 不支持订阅查询更改。当您订阅查询时,您还必须立即下载所有相关文档(请参阅 firebase-js-sdk 存储库中的问题 #1551)。
话虽这么说,正如那个问题所指出的那样,您可以通过向文档添加 updatedAt
属性 并查询 updatedAt > now
所在的所有文档来伪造此功能。这将使您订阅未来的更改。
此解决方法的一个限制是 Firestore 仅支持在查询中的单个字段上使用不等式过滤器(>=
、<
等),因此使用您的不等式过滤器最多updatedAt
字段可能有问题。
以下方法是我在类似案例中使用的方法。 我有用户、组和组中用户的请求。
登录后,我获得了所需的数据(所有数据一目了然)。
但是对于登录用户,我需要订阅该组请求的任何插入、删除或编辑(不仅是 updated-at..)。
所以我创建了一个更改请求的集合。 (groupRequestsChanged)
我已订阅
collection('groupRequestsChanged').doc(group-id-here...).valueChanged().subscribe()
这种方法在某些情况下很有用。
我来晚了,但我通过首先获得尽可能多的文档来显示(分页),然后使用 stateChanges
订阅更改来处理这个问题。所以首先我做一些像
public displayedMessages: Array<any>;
this.db.collection('messages').ref.limitToLast(100).get().then(result => {
// display the result,
this.displayedMessages = result;
//then watch changes:
this.db.collection('messages').stateChanges().pipe(
skip(1),
map(changes => {
changes.forEach(itemDoc => {
if (itemDoc.type == 'added') {
this.displayedMessages.push(item);
} else if (itemDoc.type == 'modified') {
// find the message in displayedMessages and update the data
} else if (itemDoc.type == 'removed') {
// find the index and splice it.
}
})
})
)
})
这里的关键是 skip(1)
来自 rxjs。它会跳过第一个发出的值,即整个集合。你刚刚用 get
得到了全部,所以你不需要 stateChanges
的第一个发射。所以现在每次更改该集合时,您只会得到更改。