基于已知键数组批量请求Firebase DB的最有效方法是什么?

15

我需要一种解决方案,根据关键字进行Firebase数据库API调用以获取多个项目的数据(子元素),并将这些关键字(在一个响应中)的数据返回。

由于我不需要实时数据,因此某种标准的REST调用一次(而不是Firebase数据库监听器),我认为这会是理想的。

应用程序不会再有另一个监听器和WebSocket连接打开。然而,我查看了Firebase的API文档,好像没有办法做到这一点。

我看到的大多数答案都建议使用某种组合键/索引,并使用组合键进行相应的过滤,但这只适用于搜索范围。或者他们建议仅嵌套数据而不必担心冗余和磁盘空间(并且更快),而不是通过外键检索相关数据。

然而,问题是我正在使用Geofire及其查询方法仅返回条目的键,而不是条目的数据。所有的文档和以前的答案都建议使用实时SDK检索数据,我已经尝试使用once方法,或者对所有项目进行REST调用,并使用orderBystartAtendAt参数进行过滤,并通过所需的键本地过滤。

这可能有效,但是检索我不需要的大量项目仅进行本地过滤似乎很浪费。使用once监听器的方法也很浪费,因为它对于每个项键都会有一个服务器往返。这种方法在这篇非常好的帖子中有点解释,但根据这个解释,它仍然为每个项(即使是异步和通过相同的连接)做了一个往返。

这个可怜的人问了一个类似的问题,但没有得到太多有帮助的回复(真正解决制作n个服务器请求的成本的答案)。

是否有人能一劳永逸地解释如何实现这个功能以及各种方法的优缺点?谢谢。


这是一个非常好的问题,我希望有人能够回答它。 - Barry MSIH
@caveman39 你是如何解决这个问题的?我已经发布了类似的问题,链接为http://stackoverflow.com/questions/40518576/get-children-based-on-keys-firebase - JCarlosR
3个回答

2
看起来你正在寻找Cloud Functions。 你可以创建一个名为from http request的函数,并在其中执行所有数据库读取操作。
这些函数在云中执行,其结果被发送回调用者。 HTTP调用是触发Cloud Function的一种方式,但你可以设置其他方法(计划,使用Firebase SDK从应用程序中触发,数据库触发器...)。数据直到离开服务器(因此仅在请求响应或请求另一个区域的数据库时)才会产生费用。 Cloud Function的计费基于使用的CPU,调用次数和运行实例,更多详细信息请参见配额部分
你将得到类似以下内容:
const database = require('firebase-admin').database();
const functions = require('firebase-functions');

exports.getAllNodes = functions.https.onRequest((req, res) => {
  
  let children = [ ... ]; // get your node list from req
  let promises = [];

  for (const i in children) {
    promises.push(database.ref(children[i]).once('value'));
  }

  Promise.all(promises)
    .then(result => {
      res.status(200).send(result);
    })
    .catch(error => {
      res.status(503).send(error);
    });
});

这意味着您将需要使用Firebase CLI进行部署。

0
我需要一个解决方案,基于键值对进行Firebase DB API调用,并返回这些键的数据(子项)(在一个响应中)。
其中一种解决方案可能是设置一个单独的服务器,向您的Firebase服务器发出所有所需的调用,将它们聚合并作为一个响应发送回来。
已经存在可以实现此功能的工具。
最近由Facebook团队规范的较受欢迎的工具之一是GraphQL。https://graphql.org/ 在幕后,您设置了graphql服务器以映射查询,这些查询都会进行单独的API调用,以获取您需要适合查询的数据。完成所有API调用后,graphql将以JSON对象的形式将其作为响应发送回来。

-1

这是如何在 JavaScript 中进行一次性调用文档的方法,希望能对您有所帮助。

 // Get a reference to the database service
 let database = firebase.database();
 // one time call to a document
 database.ref("users").child("demo").get().then((snapshot) => {
     console.log("value of users->demo-> is", snapshot.node_.value_)
 });

这个答案质量很低。你假设API是相似的,但也许它们并不相似。谁知道呢... - ChristianB
我很抱歉,我在这里还比较新,仍在摸索如何回答问题。我已经更新了答案,请给我一个赞,如果我的修改后的答案有帮助的话。 - Neo Wakeup
这可能有助于您撰写更好的答案。导览,以及如何编写一个好答案? - ChristianB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接