我在用户列表中匹配用户,如下所示:
export async function getLoginData(uid) {
let loginData;
const usersRef = await database.ref('users');
const snap = await usersRef.once('value');
snap.forEach((item) => {
const itemVal = item.val();
if (itemVal.uid === uid) {
loginData = itemVal;
}
});
return loginData;
}
风格方面,我不是这个的粉丝。我更愿意为匹配做一个过滤器:
loginData = snap.filter((item) => item.val().uid === uid);
但快照中没有过滤方法。有没有办法从Firebase写出更干净,一行的数据检索?或者它总是必须是一个forEach和回调,就像我上面一样?
答案 0 :(得分:1)
在担心当前过滤方法的风格之前,考虑其性能可能会更好。您正在下载/users
节点下的所有数据,然后过滤掉item.val().uid <> uid
中的所有内容。这种客户端过滤会浪费用户的带宽。
您应该尽可能使用Firebase的内置查询功能。在这种情况下,它似乎很简单:
let loginData;
const usersRef = await database.ref('users');
const snap = await usersRef.orderByChild('uid').equalTo(uid).once('value');
snap.forEach((item) => {
const itemVal = item.val();
loginData = itemVal;
});
在这种情况下,你仍然需要循环。由于查询可能会匹配多个子节点,因此代码需要处理这种情况。
如果您确定每个用户节点都有唯一的UID,您应该考虑将该UID作为密钥存储用户数据(而不是另一个生成的密钥):
users
uid1
name: "user2878765"
uid2
name: "Frank van Puffelen"
将用户数据存储在密钥下会自动确保UID是唯一的,并且可以在不需要查询的情况下查找用户的数据。这也意味着你不再需要forEach()
:
let loginData;
const usersRef = await database.ref('users');
const snap = await usersRef.child(uid).once('value');
const itemVal = snap.val();
loginData = itemVal;
这也使您更容易从函数中返回正确的承诺:
export async function getLoginData(uid) {
const snap = await database.ref('users').child(uid).once('value');
return snap.val();
}