【问题标题】:Get data by id from firebase通过 id 从 firebase 获取数据
【发布时间】:2020-04-04 13:44:11
【问题描述】:

我在 node.js 上使用 firebase。

我给定的结构应该是这样的:

{
...
batch-1:
        id-1(suppose):
                     name:...
                     phone:...
        id-2:
             ...
        id-3:
             ...
batch-2:
        ...
batch-3:
        ...
...


batch-n:
       ...
}

在这样的架构中,如何通过标识符获取 id-1 对象? 数据库是否必须遍历所有批次? 有更好的解决方案吗? 主要任务:创建一个包含许多对象的批处理,这些对象将具有 SHORT 和 UNIQUE 标识符,并通过此标识符以最佳方式接收数据

【问题讨论】:

  • 让 ref = admin.database().ref('batches/'); ref.child('batch-1').orderByKey().equalTo('id-1').on('value', (snapshot) => res.json(Object.assign({}, snapshot.val( ))));如果你知道批号((

标签: node.js database firebase firebase-realtime-database


【解决方案1】:

这是我的方法,它允许您通过 id 搜索或通过键值搜索,例如 email uniqueemail

// gets primary key
const getSnapshotValKey = snapshot => (Object.keys(snapshot).length > 0 ? Object.keys(snapshot)[0] : null)

const getUser = async ({ id, key, value }) => {
  let user = null

  const ref = id ? '/users/' + id : 'users'
  const userRef = admin.database().ref(ref)

  const valueRef = id ? userRef : await userRef.orderByChild(key).equalTo(value)
  const snapshot = await valueRef.once('value')

  const val = snapshot.val()
  if (val) {
    const key = id || getSnapshotValKey(val)

    user = {
      id: key,
      ...(id ? val : val[key]),
    }
  }

  return user
}

【讨论】:

  • 这是我觉得我能做到的最简单的
【解决方案2】:

要搜索作为未知 ID 列表子级的特定 ID,您需要使用 orderByChild()。在您的用例中,您正在寻找批次 ID 列表中的特定 ID。如果您在此列表中使用orderByChild(),您将获得每个批次 ID 的结果,即使它没有您想要的 ID。这是因为即使null(不存在)值也包含在结果中(并在开始时排序)。要获取所需 ID 的数据,您将获取查询的最后一个结果的数据,如果存在,它将是 sorted to the end of the list。请注意,如果所需的 ID 不存在,则最后一个结果(如果有任何结果)将具有 null 值。要仅返回查询的最后一个结果,您可以使用 limitToLast(1)

将所有这些放在一起,给出以下代码:

let idToFind = "unique-id-1";

let batchesRef = firebase.database().ref(); // parent key of "batch-1", "batch-2", etc.
                                            // assumed to be the database root here

batchesRef.orderByChild(idToFind).limitToLast(1).once('value')
  .then((querySnapshot) => {
    if (!querySnapshot.numChildren()) { // handle rare no-results case
      throw new Error('expected at least one result');
    }
    let dataSnapshot; 
    querySnapshot.forEach((snap) => dataSnapshot = snap); // get the snapshot we want out of the query's results list

    if (!dataSnapshot.exists()) { // value may be null, meaning idToFind doesn't exist
      throw new Error(`Entry ${idToFind} not found.`);
    }

    // do what you want with dataSnapshot
    console.log(`Entry ${idToFind}'s data is:`, dataSnapshot.val());
  })
  .catch((error) => {
    console.log("Unexpected error:", error);
  })

对于小型数据集,上面的代码可以正常工作。但是,如果批次列表开始变得非常大,您可能希望构建一个索引,将特定 ID 映射到包含它的批次 ID。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    相关资源
    最近更新 更多