在给定用户电子邮件或其他任意字段的firebase实时数据库中查找表

时间:2018-06-17 02:42:14

标签: javascript firebase firebase-realtime-database

我有一个用户存储在实时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])

    });
}

我应该如何摆脱那些根本无法工作的丑陋循环黑客?

1 个答案:

答案 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)
});

由于最多只有一个节点与此读取匹配,因此您不再需要回调中的循环。