angular - 如何在 Firebase onSnapshot 中使用 .catch
问题描述
我创建了一个 Ionic Firebase 聊天应用程序。我认为我遇到的问题是我在消息页面的初始化时设置了一个查询快照,其中包含以下内容:
ngOnInit() {
this.messageService.getAllMessages()
.doc(`${this.userId[0] + '-' + this.userId[1]}`)
.collection('message')
.orderBy('createdAt', 'asc')
.onSnapshot((doc) => {
this.messages = [];
doc.forEach((snap) => {
this.messages.push({
content: snap.data().content,
createdAt: snap.data().createdAt,
userId: snap.data().userId
});
});
console.log('messages', this.messages);
});
}
问题是,如果第一次尝试发送消息时没有消息,则页面在我第一次尝试访问时不会加载。
该消息有点晦涩,但我很确定我遇到了这个问题,因为 Firebase 没有返回任何数据,但是无法在查询中添加 .catch 来捕获错误并进行处理,以便用户可以仍然导航到消息页面。
ERROR Error: Uncaught (in promise): Error: No value accessor for form control with unspecified name attribute
Error: No value accessor for form control with unspecified name attribute
at _throwError (vendor.js:70776)
at setUpControl (vendor.js:70646)
at NgModel._setUpStandalone (vendor.js:73693)
at NgModel._setUpControl (vendor.js:73668)
at NgModel.ngOnChanges (vendor.js:73604)
at checkAndUpdateDirectiveInline (vendor.js:63813)
at checkAndUpdateNodeInline (vendor.js:65493)
at checkAndUpdateNode (vendor.js:65432)
at debugCheckAndUpdateNode (vendor.js:66400)
at debugCheckDirectivesFn (vendor.js:66343)
at resolvePromise (polyfills.js:3193)
at resolvePromise (polyfills.js:3150)
at polyfills.js:3254
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (polyfills.js:2785)
at Object.onInvokeTask (vendor.js:57358)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (polyfills.js:2784)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (polyfills.js:2557)
at drainMicroTaskQueue (polyfills.js:2963)
defaultErrorLogger @ vendor.js:55398
handleError @ vendor.js:55450
next @ vendor.js:57952
schedulerFn @ vendor.js:52576
__tryOrUnsub @ vendor.js:133918
next @ vendor.js:133857
_next @ vendor.js:133804
next @ vendor.js:133781
next @ vendor.js:133566
emit @ vendor.js:52556
(anonymous) @ vendor.js:57389
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ polyfills.js:2753
push../node_modules/zone.js/dist/zone.js.Zone.run @ polyfills.js:2512
runOutsideAngular @ vendor.js:57315
onHandleError @ vendor.js:57389
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.handleError @ polyfills.js:2757
push../node_modules/zone.js/dist/zone.js.Zone.runGuarded @ polyfills.js:2526
_loop_1 @ polyfills.js:3056
api.microtaskDrainDone @ polyfills.js:3065
drainMicroTaskQueue @ polyfills.js:2970
Promise.then (async)
scheduleMicroTask @ polyfills.js:2946
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ polyfills.js:2775
onScheduleTask @ polyfills.js:2663
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.scheduleTask @ polyfills.js:2766
push../node_modules/zone.js/dist/zone.js.Zone.scheduleTask @ polyfills.js:2600
push../node_modules/zone.js/dist/zone.js.Zone.scheduleMicroTask @ polyfills.js:2620
scheduleResolveOrReject @ polyfills.js:3241
resolvePromise @ polyfills.js:3187
(anonymous) @ polyfills.js:3103
webpackJsonpCallback @ runtime.js:26
(anonymous) @ pages-messages-messages-module.js:1
vendor.js:116244 POST https://firestore.googleapis.com/google.firestore.v1.Firestore/Write/channe
所以我的问题是,有没有办法在firebase的.Snapshot查询中处理空返回值?
我试过这个:
ngOnInit() {
try {
this.messageService.getAllMessages()
.doc(`${this.users[0] + '-' + this.users[1]}`)
.collection('message')
.orderBy('createdAt', 'asc')
.onSnapshot((doc) => {
this.messages = [];
doc.forEach((snap) => {
this.messages.push({
content: snap.data().content,
createdAt: snap.data().createdAt,
userId: snap.data().userId
});
});
console.log('messages', this.messages);
});
} catch (error) {
console.log('Message page error', error);
}
}
解决方案
虽然道格的答案是正确的,但您仍然需要onSnapshot
在权限被拒绝时捕获错误
为此,请使用以下语法:
const unsubscribeMe = firestoreInstance
.collection('example')
.onSnapshot(
querySnapshot => {
if (querySnapshot.empty) {
return
}
const organizations = querySnapshot.docs.map(ref => ({
id: ref.id,
...ref.data(),
}))
},
error => {
console.log(error)
}
)
请参阅此处的javascript 参考,其中包含可能适合您需要的其他方法签名。
推荐阅读
- python - Plotly Dash/Apache Kafka - 我想看到一个实时绘制的图表,而不是在完成绘图时出现
- r - 如何为行数据框中发现的任何不匹配选择行名称和行
- node.js - 无法使用 SSL 连接到 AWS Aurora Serverless
- ubuntu - 另一个重复实例已在此存档目录中运行
- redis - 使用 Redis 集群时,stackexchange.redis 是“智能客户端”吗?
- video - 如何使用 ffmpeg 将 VCD(dat 文件) 转换为一批图像,然后将这些图像转换为另一个视频?
- javascript - GraphQLFederationModule 健康检查
- jquery - 如何使用 jquery 选择器选择 django 模板变量值的 id?
- php - 显示 ASCII 字符的页面标题
- network-programming - 我们有 IOS 应用程序应该在应用程序商店中发布,应用程序使用 swift 进行有线通信