我在实时 Firebase 中存储了一个用户,其中包含键 uid
(用户 ID)和字段:
uid
email
emailVerfied
我想找到与给定电子邮件对应的用户记录。我目前的黑客攻击还有很多不足之处。特别是如何在给定快照的情况下正确检索实际用户记录:
function readByEmail( user_email : string, next : any ){
firebaseApp.database().ref('/users/')
.orderByChild('email')
.equalTo(user_email)
.once('value', snap => {
// retrieve the user key:
const record = snap.val();
let key;
for ( let _key in record ) {
console.log('field: ', _key, record[_key])
key = _key;
}
next(record[key])
});
}
我应该如何摆脱丑陋的循环黑客,它根本无法保证工作?
最佳答案
如果您有一个子属性 email
,其中包含您要过滤的值,则可能有多个子节点与您过滤的值匹配。这就是您需要循环的原因,所以我会说这正在按预期工作。
执行循环的更惯用方法是使用 Firebase 的内置 forEach
方法:
firebaseApp.database().ref('/users/')
.orderByChild('email')
.equalTo(user_email)
.once('value', snap => {
let key;
snap.forEach(child => {
key = child.key;
});
next(snap.child(key).val())
});
如果您知道只有一个子项匹配,则可以监听 child_added
,它会针对每个子项触发。因此 once("child_added"
只会针对第一个 child 触发:
firebaseApp.database().ref('/users/')
.orderByChild('email')
.equalTo(user_email)
.once('child_added', snap => {
next(snap.val())
});
但是,如果您的应用已要求电子邮件值在 /users
下的所有节点中是唯一的,请考虑使用该值作为键。您需要对电子邮件地址进行编码,因为 Firebase 键中不允许使用 .
(将其编码为 ,
是自定义的)。当您使用(编码的)电子邮件地址作为 key 时,您可以像这样直接查找:
firebaseApp.database().ref('/users/'+user_email)
.once('value', snap => {
const record = snap.val();
key = snap.key;
next(record)
});
由于最多有一个节点与此读取匹配,因此您不再需要回调中的循环。
关于javascript - 在给定用户电子邮件或其他任意字段的 Firebase 实时数据库中查找表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50893259/