有没有办法批量读取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

有没有办法根据 firebase Auth 用户信息更新 firestore 文档字段?

firebase 中唯一的用户名,没有变通办法

Firebase Firestore:如何在 Android 上将文档对象转换为 POJO