有没有办法批量读取firebase文档
Posted
技术标签:
【中文标题】有没有办法批量读取firebase文档【英文标题】:Is there a way to batch read firebase documents 【发布时间】:2020-04-21 16:26:57 【问题描述】:我正在使用 Flutter 和 Firebase 作为我的后端来制作一个移动应用程序。
我有一个存储用户信息的用户文档集合。其中一个字段是一个引用数组(另一个集合中的引用文档),我想在批处理之类的操作中使用它,然后允许读取所有文档。
我知道批处理只允许写入数据库,我的第二个选项是事务,它需要在读取后写入,我试图避免。
有没有一种方法可以在一个操作中读取多个文档而无需使用 Transaction?
【问题讨论】:
你的最后一句话我不清楚。请编辑问题以解释您要通过通常对事务执行的批处理来完成什么。如果您提供文档内容的具体示例,将会很有帮助。 对不起,我的校对应该做得更好 您可以使用IN
查询一次性按 ID 加载多达 10 个文档。见***.com/questions/46721517/…。如果您需要超过 10 个文档,则必须执行多个查询,因此您不妨单独加载它们。
感谢您的回答,该链接也很有帮助。
【参考方案1】:
Firestore 不提供正式的批量读取 API。正如弗兰克在他的评论中提到的,有一种方法可以使用IN
来使用它们的 ID 从单个集合中获取多个文档。但是,所有文档必须在同一个集合中,并且每个查询不能超过 10 个文档。您最好只为每个文档单独获取(),因为IN
查询有限制,并且不能保证执行速度比个人获得的速度快。这两种解决方案都不能保证是“一致的”,因此在任何给定的时间点,获取的任何一个文档都可能比其他文档“更新鲜”。
【讨论】:
感谢道格的回答,虽然我试图从不同的集合中获取多个文档,所以 IN 不一定能解决我的问题。您的回答有助于我了解 Firebase 的功能和限制。 @doug-stevenson“并且每个查询不能超过 10 个文档”,文档只提到“使用 IN 运算符在同一字段上组合最多 10 个相等 (==) 子句“据我了解,限制是您可以在一个字段上查询多达 10 个相等子句并返回尽可能多的文档。不只是 10 个文件,我错了吗? @Yahine 是的,但在这种情况下,他正在对 id 属性执行 IN 查询。所以这里也是一样的。 如果您按字段排序并且对要返回的文档数量有限制,则使用 IN 比使用串行获取有好处。使用 IN 查询,这些可能都来自单个字段值,因为它可能有更多文档并且它填充了“限制”,而通过并发获取时,您必须将限制应用于每个获取(导致到总读取数的 10 倍),然后在最后进行排序,然后根据需要截断。【参考方案2】:Firestore 有一个 REST API,允许您使用可能是您需要的文档路径执行批量 GET。
见https://firebase.google.com/docs/firestore/reference/rest/v1beta1/projects.databases.documents/batchGet
【讨论】:
【参考方案3】:如果您知道需要获取的文档 ID 和文档的集合路径,您始终可以使用在 firebase Admin SDK 中公开的 getAll() 方法(至少对于 Node.js 环境)。
然后,例如,您可以编写一个HTTPS Callable Function 来接受绝对文档路径列表并使用getAll()
方法对它们执行“批量获取”操作。
例如
// Import firebase functionality
const functions = require('firebase-functions');
const admin = require('firebase-admin');
// Configure firebase app
admin.initializeApp(functions.config().firebase);
// HTTPS callable function
exports.getDocs = functions.https.onCall((data, context) =>
const docPathList = data.list; // e.g. ["users/Jkd94kdmdks", "users/8nkdjsld", etc...]
const firestore = admin.firestore();
var docList = [];
for (var i = 0; i <= docPathList.length - 1; i++)
const docPath = docPathList[i];
const doc = firestore.doc(docPath);
docList.push(doc);
// Get all
return firestore.getAll(...docList)
.then(results =>
return data : results.map(doc => doc.data()) ;
)
.catch(err =>
return error : err ;
)
);
不确定您可以使用 getAll()
获取的文档数量的限制(如果有)是多少,但我知道我的应用程序能够使用此方法每次调用成功获取至少 50 个文档。
【讨论】:
以上是关于有没有办法批量读取firebase文档的主要内容,如果未能解决你的问题,请参考以下文章
Firebase 函数:无法读取未定义的属性“user_id”
Uncaught FirebaseError: Firebase: No Firebase App '[DEFAULT]' has been created - 在 vue.js 中调用 Fireba
Stripe 和 Firebase:FirebaseError:collection() 的第一个参数应为 CollectionReference、DocumentReference 或 Fireba