【问题标题】:Firebase Cloud Function. Create documents in sub-collection of specific collectionsFirebase 云功能。在特定集合的子集合中创建文档
【发布时间】:2025-12-10 04:50:01
【问题描述】:

这是我试图在这里完成的基本前提。如果用户询问有关产品的问题,我想向当前拥有该产品的其他用户发送通知。基本上是说“嘿,某某对这个产品有疑问。也许你可以帮忙,因为你已经拥有它了”

每个 userProfile 集合都有一个名为“notify”的子集合,其中存储了各种事物的通知。我需要做的是对 userProducts 进行排序并找到拥有该产品的每个用户,然后仅在拥有该产品的特定用户的通知子集合中创建一个通知帖子。

这里是基本代码。第一点起作用,因为它确实返回了拥有该产品的用户 ID 数组。我现在苦苦挣扎的地方是让它在 Notify 子集合中为那些特定用户创建一个新文档。这可能吗?

exports.Questions = functions.firestore
.document("/userPost/{id}")
.onCreate(async (snap, context) => {
const data = snap.data();

if (data.question == true) {
  const userProducts = await db
    .collection("userProducts")
    .where("product", "==", data.tag)
    .get();

  const userData = userProducts.docs.map((doc) => doc.data().userId);



  await db
    .collection("userProfile")
    .where("userId", "in", userData)
    .get()
    .then((querySnapshot) => {
      return querySnapshot.docs.ref.collection("notify").add({
        message: "a user has asked about a product you own",
      });
    });
 });

【问题讨论】:

    标签: javascript firebase google-cloud-firestore google-cloud-functions


    【解决方案1】:

    您当前的解决方案是正确的,但可以进行改进。

    • 使用guard pattern 进行data.question == true 检查。
    • 您不需要获取userProfile/<uid>,因为您没有使用它的内容。
    • 一次更改多个文档时,您应该考虑使用batching them together 来简化错误处理。
    • ref.add(data)ref.doc().set(data) 的简写,您可以在批量写入中使用它来创建新文档。
    exports.Questions = functions.firestore
      .document("/userPost/{id}")
      .onCreate(async (snap, context) => {
        const data = snap.data();
    
        if (!data.question) {
          console.log("New post not a question. Ignored.")
          return;
        }
    
        const userProducts = await db
          .collection("userProducts")
          .where("product", "==", data.tag)
          .get();
    
        const userIds = userProducts.docs.map(doc => doc.get("userId")); // more efficient than doc.data().userId
    
        // WARNING: Limited to 500 writes at once.
        // If handling more than 500 entries, split into groups.
        const batch = db.batch();
    
        const notificationContent = {
          message: "a user has asked about a product you own",
        };
    
        userIds.forEach(uid => {
          // creates a ref to a new document under "userProfile/<uid>/notify"
          const notifyDocRef = db.collection(`userProfile/${uid}/notify`).doc();
    
          batch.set(notifyDocRef, notificationContent);
        });
    
        await batch.commit(); // write changes to Firestore
     });
    

    注意:对于之前没有人购买过的产品,这里没有特殊处理。考虑也 ping 产品的所有者。

    【讨论】: