Firebase 云函数。在特定集合的子集合中创建文档

Firebase Cloud Function. Create documents in sub-collection of specific collections

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

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

这是基本代码。第一点的工作原理是它 return 拥有该产品的用户 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",
      });
    });
 });

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

  • 使用 guard pattern 进行 data.question == true 检查。
  • 您不需要获取 userProfile/<uid>,因为您没有使用它的内容。
  • 一次更改多个文档时,您应该考虑 batching them together 以简化错误处理。
  • ref.add(data) 是 shorthand for 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
 });

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