angular - 无法使用函数更新用户数据
问题描述
在我的 Angular 项目中,我正在尝试使用登录功能让用户使用 google 登录,然后根据他们是否已经拥有该approved
角色来更新他们的用户数据。
在尝试完成这项工作时,我的任何console.log
陈述都没有触发,所以我不确定我可以做些什么来进入这些块。
async handleSignIn() {
const credential = await this.afAuth.signInWithPopup(new firebase.default.auth.GoogleAuthProvider());
return this.manageUserData(credential.user)
}
private async manageUserData(user: User) {
let data$; // Init Variable
let update$; // Init Variable
const userCollection = this.afs.collection<User[]>('users'); // Sets Path for Data
console.log(user.uid);
data$ = userCollection.doc<User>(user.uid).snapshotChanges().pipe( // Fetches Document
map(action => { // Maps To Be Able To Do Things
const payload = action.payload.data(); // Sets Payload Data as the main `payload` variable
console.log("In place", payload)
if(payload.roles.approved == true || false) {
console.log("main block")
update$ = {
uid: user.uid,
email: user.email,
displayName: user.displayName,
photoURL: user.photoURL
}
} else {
console.log("else block")
update$ = {
uid: user.uid,
email: user.email,
displayName: user.displayName,
photoURL: user.photoURL,
roles: {
approved: false
}
}
}
const userRef: AngularFirestoreDocument<User> = this.afs.doc(`users/${user.uid}`);
return userRef.set(update$, { merge: true });
})
)
}
该console.log(user.uid)
语句返回我的 Firebase UID:rKlGL943eqfaPVWLh2EEUVBoOvg2
编辑:我也尝试在这里使用三元运算符并更好地组织功能:
function hasApprovedStatus() {
update$ = {
uid: user.uid,
email: user.email,
displayName: user.displayName,
photoURL: user.photoURL
}
userRef.set(update$, { merge: true });
}
function hasNoApprovedStatus() {
update$ = {
uid: user.uid,
email: user.email,
displayName: user.displayName,
photoURL: user.photoURL,
roles: {
approved: false
}
}
userRef.set(update$, { merge: true })
}
data$ = userCollection.doc<User>(user.uid).snapshotChanges().pipe( // Fetches Document
map(action => action.payload.data().roles.approved ? hasApprovedStatus() : hasNoApprovedStatus())
)
}
解决方案
问题可能是您的 async 方法manageUserData()
实际上并没有做return
任何事情。
该方法正在创建一个 ObservableuserCollection.doc<User>(user.uid).snapshotChanges()
并将其分配给本地 var data$
,但它没有从该方法返回它,也没有订阅它。因此,您似乎正在创建一个永远不会被订阅的 Observable,因此您的map
函数将永远不会被调用。
您需要做的是return
您正在创建的 Observable(另外,除非您打算将该 var 用于某事,否则无需将其分配给本地 var):
return userCollection.doc<User>(user.uid).snapshotChanges().pipe(...
这将导致manageUserData()
返回一个async
解析为 Observable 的 Promise(因为它是 )。
由于handleSignIn()
返回 的返回值manageUserData()
,因此该 Promise 将传递给调用 的任何人handleSignIn()
。该调用方法看起来像这样:
async signIn() {
const handle: Observable<any> = await this.handleSignIn();
handle.subscribe();
}
由于handleSignIn()
返回一个 Promise,我们必须await
通过该 Promise 的解析然后订阅生成的 Observable(即您的snapshotChanges()
)。
除非您需要它是基于 Promise 的,否则您可能会考虑简单地返回 Observable ,manageUserData()
而handleSignIn()
不是将其包装在 Promise 中(通过制作这些方法async
),那么您不需要额外的步骤await
来解决 Promise。
这是一个 StackBlitz,其中该方法调用链的模拟版本正常工作。
更新响应评论,2020 年 12 月 29 日:
如果您需要过滤流以便map
函数中的第一行const payload = action.payload.data()
始终从方法调用中检索值,您可以在管道action.payload.data()
中添加过滤器map
运算符:
return userCollection.doc<User>(user.uid).snapshotChanges().pipe(
filter(action => Boolean(action.payload?.data?.())),
map(action => { ... )
)
其他一些观察:
map
函数的第一行是
const payload = action.payload.data();
您在其中调用属性的data()
方法payload
。真的data()
是一种方法还是只是一种属性?
map
函数中的第三行是
if(payload.roles.approved == true || false) { ...
这是一个奇怪的构造条件。您正在测试什么条件?
本质上什么都不做, || false
因为它只评估 if payload.roles.approved == true
is false
,所以你只是在检查if (false || false)
,这似乎不是很有用。
如果您的意图是检查 if payload.roles.approved
is either strict 或strict ,那么您会这样做(请注意,我使用的是严格相等true
,而不是松散相等,因为这是首选,除非有充分的理由使用松散相等):false
===
if(payload.roles.approved === true || payload.roles.approved === false) { ...
推荐阅读
- python - pip install paho-mqtt 回溯(最后一次调用)
- or-tools - 谷歌 OR 工具 CP 求解器
- javascript - 如何从客户端发送 JavaScript 对象以及如何在 Spring Boot 后端接收和解析它们?
- mysql - 从 MariaDB Galera 集群捕获更改数据
- javascript - 日期选择器无法填充日期字段
- android - 为什么我的 AIDE 不下载 Google Firebase 库?
- php - PHP表单处理算法
- google-apps-script - Google Script ~ 如何自动授权应用程序?
- jquery - Jquery 表单文件上传验证
- javascript - HTTPS 调用不会在 Cordova android 发布 apk 中进行