【问题标题】:Using firebase cloud function to copy all documents from a master collection in Firestore to new sub-collection使用 Firebase 云功能将所有文档从 Firestore 中的主集合复制到新的子集合
【发布时间】:2020-05-23 17:11:57
【问题描述】:

我在 Firestore 中有一个包含几百个文档的主集合(几个月后会增长到几千个)。

我有一个用例,每次在 /users/ 集合中创建新的用户文档时,我都希望将 master 中的所有文档复制到 /users/{userId}/。

为此,我创建了一个firebase云功能,如下所示:

// setup for new user
exports.setupCollectionForUser = functions.firestore
  .document('users/{userId}')
  .onCreate((snap, context) => {

    const userId = context.params.userId;

    db.collection('master').get().then(snapshot => {

      if (snapshot.empty) {
        console.log('no docs found');
        return;
      }

      snapshot.forEach(function(doc) {

        return db.collection('users').doc(userId).collection('slave').doc(doc.get('uid')).set(doc.data());
      });
    });
 });

这行得通,唯一的问题是,只有大约 200 个文档需要很长时间(约 3-5 分钟)。这真是太糟糕了,因为很大程度上取决于这些文件被复制的速度。我希望这最多不超过几秒钟。此外,这些文档完全显示出来,而不是它们所写的那样,或者至少看起来是这样。

我做错了吗?为什么要花这么长时间?

有没有办法可以将此操作分解为多次读取和写入,以便我可以保证在几秒钟内获得最少的文档,而不是等到所有文档都被复制过来?

请指教。

【问题讨论】:

    标签: node.js firebase google-cloud-firestore google-cloud-functions


    【解决方案1】:

    如果我没记错的话,通过使用Promise.all() 正确管理并行写入并返回 Promises 链,它通常应该会提高速度。

    尝试如下调整您的代码:

    exports.setupCollectionForUser = functions.firestore
        .document('users/{userId}')
        .onCreate((snap, context) => {
    
            const userId = context.params.userId;
    
            return db.collection('master').get().then(snapshot => {  
    
                if (snapshot.empty) {
                    console.log('no docs found');
                    return null;
                } else {
    
                    const promises = [];
                    const slaveRef = db.collection('users').doc(userId).collection('slave');
                    snapshot.forEach(doc => {
    
                          promises.push(slaveRef.doc(doc.get('uid')).set(doc.data()))
    
                    });
    
                    return Promise.all(promises);
    
                }
    
            });
    
        });
    

    我建议您观看来自 Firebase video series 的有关“JavaScript Promises”的 3 个视频,其中解释了为什么在后台触发的 Cloud Function 中返回 Promise 或值是关键。


    还要注意,如果您确定要保存在 slave 集合中的文档少于 500 个,则可以使用 batched write。 (您可以将它用于 500 多个文档,但是您必须管理不同批次的批量写入...)

    【讨论】:

      猜你喜欢
      • 2020-04-04
      • 2022-01-17
      • 2018-07-01
      • 2018-10-21
      • 2022-01-21
      • 2021-05-09
      • 1970-01-01
      • 1970-01-01
      • 2018-12-31
      相关资源
      最近更新 更多