【问题标题】:firestore cloud function update another documentfirestore 云功能更新另一个文档
【发布时间】:2021-08-19 13:39:41
【问题描述】:

我想增加集合项目中文档 (item_id) 中“投票”字段的值。每次将新文档添加到集合投票时,我都希望云功能为我执行此操作。新文档包含 item_id。有谁知道我该怎么做?这就是我现在拥有的:

    import * as functions from "firebase-functions";
    import * as admin from "firebase-admin";
    admin.initializeApp();

    export const vote = functions.firestore.document("/Votes/{vote}")
    .onCreate((snapshot, context) => {
      const item = context.params.item_id; 
      const itemdoc = admin.firestore().collection("items").doc(item);

      itemdoc.get().then((doc) => {
        if (doc.exists) {
          itemdoc.update({
            "votes": admin.firestore.FieldValue.increment(1)})
              .catch((err) => {
                console.log("Error updating item vote", err);  
              });
        }
      });
    });

在 firebase 控制台日志中,路径必须是非空字符串。有谁知道我做错了什么?因为路径不应该为空。

【问题讨论】:

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


    【解决方案1】:

    以下应该可以解决问题:

    export const vote = functions.firestore.document("/Votes/{vote}")
        .onCreate((snapshot, context) => {
    
            const item = snapshot.data().item_id;
            const itemDocRef = admin.firestore().collection("items").doc(item);
        
            return itemDocRef.update({
                "votes": admin.firestore.FieldValue.increment(1)
            });
    
        });
    

    您需要在snapshot 上使用data() 方法,以获取新文档的JavaScript 表示。然后您获取item_id 属性。

    另一种可能是使用get()方法,如下:

    const item = snapshot.get("item_id");
    

    我建议将itemdoc 变量重命名为itemDocRef,因为它是DocumentReference


    跟随你的 cmets 更新:

    如果您想在更新后阅读项目文档,您应该执行以下操作:

    export const vote = functions.firestore.document("/Votes/{vote}")
        .onCreate(async (snapshot, context) => {
            const item = snapshot.data().item_id;
            const itemDocRef = admin.firestore().collection("items").doc(item);
    
            await itemDocRef.update({"votes": admin.firestore.FieldValue.increment(1)});
    
            const itemDocSnapshot = await itemDocRef.get();
    
            //Do whatever you want with the Snapshot
            console.log(itemDocSnapshot.get("user_id"));
            
            // For example update another doc
            const anotherDocRef = admin.firestore().collection("....").doc("....");
    
            await anotherDocRef.update({"user_id": itemDocSnapshot.get("user_id")});
            
            return null;
    
        });
    

    注意asyncawait 关键字的使用。

    【讨论】:

    • 更新后有没有办法请求user_id?更新的 itemrefdoc 包含该 user_id。或者是完全加载文档的唯一方法,就像它没有更新一样?
    • 我不确定你的确切目标。您的意思是要在更新后查询collection("items").doc(item) 中的文档?如果这就是你的意思,那确实是可能的。但是您需要使用get() 方法,因为使用update() 您无需加载文档,只需写入即可。
    • 每次写入和读取都由 firebase 计费,所以我的意思是在更新后(您刚刚帮我完成),即 1 次写入,那么是否可以获得文档数据?还是我应该查询以记录并为 1 次阅读付费?
    • 我明白了。我没有按时看到您更新的评论。感谢您的帮助!
    • 我将更新我的答案,因为在反向使用异步方法时正确管理 Cloud Function 的生命周期很重要。
    【解决方案2】:
    const item = context.params.item_id; 
    

    通过访问context.params,您试图在.document("/Votes/{vote}") 中找到通配符中的值,这肯定是未定义的。要从文档中读取字段,请尝试以下操作:

    const {item_id} = snapshot.data()
    // Getting item_id using Object destructuring
    
    if (!item_id) {
      // item_id is missing in document
      return null 
    }
    
    const itemdoc = admin.firestore().collection("items").doc(item_id);
    // Pass item_id in doc                                    ^^^^^^^
    

    您可以在documentation 中阅读有关onCreate 的更多信息。第一个参数snapshot 是包含您的文档数据的QueryDocumentSnapshot,第二个参数contextEventContext

    【讨论】:

      猜你喜欢
      • 2019-08-07
      • 2018-05-11
      • 2021-03-27
      • 1970-01-01
      • 1970-01-01
      • 2020-02-01
      • 2019-12-13
      • 2021-09-14
      • 2020-02-08
      相关资源
      最近更新 更多