【问题标题】:Update Sub-collections on CloudFunctions更新 CloudFunctions 上的子集合
【发布时间】:2020-02-27 09:30:30
【问题描述】:

我需要帮助。

我的项目中有 2 个集合,一个称为 Products,另一个称为 Users。

我将选定的产品信息复制到用户的子集合中作为收藏夹,在这种情况下:

用户(收藏)> 用户(文档)> 收藏(收藏)> 产品(文档)

我的想法是创建一个云功能,它将监视“产品集合”产品(集合)>产品(文档)中任何产品的任何更新,然后将这些更改反映在用户>收藏夹子集合中在此处更新产品的值:

用户(收藏)> 用户(文档)> 收藏(收藏)> 产品(文档)

这怎么可能来自 index.js ?这是我的代码:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

    exports.updateFavoritedProducts = functions.firestore.document('products/{productId}').onUpdate((change, context) => {

admin.firestore().collection('products').get(queryProductsSnapshot => {

    queryProductsSnapshot.forEach(productQuery => {
    const pricePQ = productQuery.price;

    console.log('tetesfsf');

    return admin.firestore().collection('users').get(queryUsersSnapshot => {
            queryUsersSnapshot.forEach(userSnapshot => {

                return admin.firestore().collection('users').doc(userSnapshot.id).collection('favorites').get(queryUserProductsSnapshot => {
                    queryUserProductsSnapshot.forEach(queryUserProductSnapshot => {
                        if (queryUserProductSnapshot.id === productQuery.id) {

                            return admin.firestore().doc(`users/${userSnapshot.id}/favorites/${queryUserProductSnapshot.id}`).update({ amountVolume: '123456'
                            })
                        } else {
                            console.log("No events found");
                            return null
                        }
                    })
                });
            })
            })
    });
})
});

【问题讨论】:

  • 您的代码中有两个QuerySnapshot.forEach 循环,其中一个似乎没有找到任何文档。看来您应该在调用任何方法之前检查QuerySnapshot 是否为空。
  • 这对我来说仍然不起作用;您是否知道如何重写此代码,以便在“产品集合”级别进行更新后,它可以在“收藏夹子集合”中进行更新?
  • 您是否添加了我提到的if 检查?如果是这样,并且错误仍然存​​在,请更新您的问题以显示更新后的代码。
  • 我想通了并在此处发布了解决方案。谢谢!

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


【解决方案1】:

我使用 user1889692 的答案更新了我项目中一个嵌套更深的子集合中的所有文档。

时间线(集合)>时间线(文档)>发布者ID(集合)>发布者IDID(文档)>帖子(集合)>帖子ID(文档)

这是我的工作代码:

 exports.onCreateTimelineTest = functions.firestore
   .document("/timelineTest/{buguId}")
   .onCreate(async (snapshot, context) => {

 const timeNow =new Date();
 const db = admin.firestore();
     return db.collection("timeline")
     .get()
     .then((timelineQuerySnapshot) => {
     timelineQuerySnapshot.forEach(async(timelineQuerySnapshot) => {


       console.log("all the documnets inside timeline are", timelineQuerySnapshot.id);

        await db.collection("timeline")
        .doc(timelineQuerySnapshot.id)
         .collection("publisherId")
         .get()
         .then((publisherSnapshot)=>{
         publisherSnapshot.forEach(async(publisherSnapshot)=>{


           console.log("all the documnets inside timeline are", publisherSnapshot.id);

         await db.collection("timeline")
          .doc(timelineQuerySnapshot.id)
          .collection("publisherId")
          .doc(publisherSnapshot.id)
          .collection("posts")
          .where('uploadTime', '<=', timeNow)
          .get()
          .then((postSnap)=>{
         postSnap.forEach(async(postSnap)=>{


         console.log("all the documnets inside timeline are", postSnap.id);

         return db.collection("timeline")
         .doc(timelineQuerySnapshot.id)
         .collection("publisherId")
         .doc(publisherSnapshot.id)
         .collection("posts")
         .doc(postSnap.id)
         .set({
         'name': 'madhav'
                          }).catch((err)=>{
                          console.log('Error getting documents', err);
                          return Promise.reject(err);
                          });
                       });
         return null
         }).catch((err) => {
                    console.log('Error getting documents', err);
                    return Promise.reject(err);
                   });
         });
         return null
         }).catch((err) => {
          console.log('Error getting documents', err);
          return Promise.reject(err);
         });
     });
     return null
     }).catch((err) => {
      console.log('Error getting documents', err);
      return Promise.reject(err);
     });

  });

【讨论】:

    【解决方案2】:

    我终于想出了如何使用嵌套承诺来做到这一点。这是解决方案:

    exports.updateFavoritedProducts = functions.firestore.document('products/{productId}').onUpdate((change, context) => {
        const data = change.after.data();
        const productID = data.id;
    
     return db.collection('products').where('id', '==', productID).get().then((productsQuerySnap) => {
    
        productsQuerySnap.forEach((productQuerySnap) => {
            const newPrice = productQuerySnap.data().price;
            const newPriceUnit = productQuerySnap.data().priceUnit;
    
            db.collection('users').get().then((usersQuerySnap) => {
                usersQuerySnap.forEach((userQuerySnap) => {
    
                    return db.collection('users').doc(userQuerySnap.id).collection('favorites').doc(productQuerySnap.id).update({ 
                        price: newPrice,
                        priceUnit : newPriceUnit
    
                     }).catch((err) => {
                        console.log('Error getting documents', err);
                        return Promise.reject(err);
                        });
                    });
                    return null
                })
                .catch((err) => {
                    console.log('Error getting documents', err);
                    return Promise.reject(err);
                });
            return null
        });
        return null
    })
        .catch((err) => {
            console.log('Error getting documents', err);
            return Promise.reject(err);
        });
    });
    

    【讨论】:

      【解决方案3】:

      如果您想创建一个触发所有用户的所有产品更新的云函数,请将其声明为:

      functions.firestore.document('users/{userId}/products/{productId}').onUpdate((change, context) => {
      

      如果你想在函数体内访问userIdproductId,你可以得到它们:

      context.params.userId
      context.params.productId
      

      【讨论】:

      • 但是改变并没有发生在那个路径上!最初的更改发生在 products > productId。一旦发生这种情况;我想更新以下路径中的信息: users/{userId}/products/{productId} 。所以我需要调用我的函数来触发产品集合更改而不是用户
      • 在这种情况下,您的代码已经在正确的路径上触发。它有什么问题?
      • 一旦触发;如何更新其他集合中的更改: users(collection) > user(doc) > favorites(collection) > product (doc) 。我刚刚用我尝试过的方法编辑了我的问题,但仍然无法正常工作;
      • 这段代码有什么问题?请记住,Stack Overflow 是一个出了名的低效交互式调试器,因此最好尽可能多地告诉我们:哪一行没有按照您的预期执行,以及该行之前的所有相关值是什么(通常通过记录它们的值,并在您的问题中包含该代码及其输出)。
      • 我刚刚用日志中的错误代码更新了帖子。您知道如何更改代码,以便可以为用户集合中的收藏夹子集合进行此更新吗?不确定我的代码到底在哪里做错了,一旦我更新产品集合中的字段,就不会更新子集合
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-12
      • 1970-01-01
      • 2020-08-25
      • 2023-04-05
      • 1970-01-01
      • 2021-08-16
      • 1970-01-01
      相关资源
      最近更新 更多