我有一个用户存储在实时firebase中,其中包含密钥uid
(用户ID)和字段:
uid
email
emailVerfied
我想在给定电子邮件的情况下找到相应的用户记录。我目前的黑客还有很多不足之处。特别是如何在给定snapshot
:
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])
});
}
我应该如何摆脱那些根本无法工作的丑陋循环黑客?
答案 0 :(得分:1)
如果您的子属性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"
只会为第一个孩子开火:
firebaseApp.database().ref('/users/')
.orderByChild('email')
.equalTo(user_email)
.once('child_added', snap => {
next(snap.val())
});
但是,如果您的应用已经要求电子邮件值在/users
下的所有节点中都是唯一的,请考虑使用该值作为关键字。您需要对电子邮件地址进行编码,因为Firebase密钥中不允许.
(将其编码为,
是自定义的)。当您使用(编码的)电子邮件地址作为密钥时,您可以像这样直接查找:
firebaseApp.database().ref('/users/'+user_email)
.once('value', snap => {
const record = snap.val();
key = snap.key;
next(record)
});
由于最多只有一个节点与此读取匹配,因此您不再需要回调中的循环。