friend 。
所以,我不是在摸索这个 RxJS 的东西,因为它与 Angular 相关。我有一个 Promise 工作(用户身份验证事件), 但是我尝试从 Firebase 异步获取数据的尝试并不顺利。
这段代码在大多数情况下都有效,除了一种情况:当用户登录时(通过重定向)。在这种情况下,我们看到 用户身份验证事件发生,然后(大概)运行更改检测周期,导致 UI 更新为 显示当前登录的用户,然后(大概)来自 Firebase 的数据库事件(我们在 控制台),但没有另一个变化检测周期(我认为应该有),所以 UI 不会随着 来自 d/b 的新信息。如果我等待 10-15 秒(大致;我实际上没有计时),或者如果我在 UI 中输入一些内容 文本字段,然后 UI 使用数据快照更新。
我通过 Observable.fromEventPattern()
将 Observable 连接到 Firebase 事件。
如果您已经登录并打开,这个东西就像一个冠军 或刷新页面。如果您尝试登录,它就不起作用。我没有完全登录可能也无济于事 了解重定向中发生的事情。
那么……我做错了什么? (我确定我确实做错了很多事。)
我在 https://github.com/JohnL4/FirebaseRxPlay/releases/tag/problem-reproduction 有一个玩具应用程序重现了我的问题。
最佳答案
我在我的项目中遇到了同样的问题。我觉得它与 zone.js 以及 Angular 检测是否有变化有关,因为你必须触发一些导致 View 更新的 Action 才能看到你的变化。 我决定像这样在 NgZone 中运行所有 firebase 的回调
tagsRef.on('value', snapshot => {
this.zone.run(() => {
const tags = Object.keys(snapshot.val() || {});
observer.next(tags);
});
});
我也为身份验证回调做了同样的事情
getAuthRedirectResult$(): Observable<firebase.auth.UserCredential> {
return new Observable<firebase.auth.UserCredential>(observer => {
this.firebaseService.auth.getRedirectResult()
.then((result: firebase.auth.UserCredential) => {
if (result.user) {
this.zone.run(() => {
observer.next(result);
});
}
})
.catch(error => {
this.zone.run(() => {
observer.error(error);
});
});
});
这解决了我的问题。
我唯一不确定的是为什么这个问题只发生在 auth 的重定向之后。
编辑#1:
我对此进行了更多调查,显然是在 <root>
中运行重定向 firebase 身份验证回调之后区域,而不是 angular
区。所以这就解释了为什么没有触发变化检测。
编辑#2:
angularfire2 repo 中的以下提交表示 firebase 可以在 angular Zone 存在之前添加 websocket 监听器。所以我认为这就是我看到身份验证回调在 <root>
中运行的原因区域而不是 angular
区域。
Since Firebase is adding WebSocket listeners before the Angular Zone exists, all callbacks when data is received are being executed outside of Angular's zone and are not triggering change detection
https://github.com/angular/angularfire2/pull/648/commits/8b2c7a400418a68b6f25654067ce6cf918ceb681
关于angular - 通过重定向登录后,Firebase Datasnapshot Observable 未立即更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43097291/