过滤Firebase

时间:2017-07-09 22:25:15

标签: javascript firebase firebase-realtime-database

我在用户列表中匹配用户,如下所示:

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和回调,就像我上面一样?

1 个答案:

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