NodeJS 如何在Cloud Firestore中批量写入嵌套集合

f2uvfpb9  于 2023-06-22  发布在  Node.js
关注(0)|答案(1)|浏览(87)

我在通过Cloud Functions实现批量写入Firestore时遇到问题。
背景:这是一个为Wordle排行榜开发Chrome扩展的个人项目。
下面是我的云函数的意图:
1.请求Wordle解决方案
1.将“竞赛”文档添加到每个排行榜文档2a内的竞赛集合。文档的路径如下所示:/leaderboards/{leaderboardDocId}/contests/{contestDocId}
下面是我的云函数代码:

const functions = require('@google-cloud/functions-framework');
const https = require('https');

const admin = require("firebase-admin");
admin.initializeApp();

functions.cloudEvent('getWordleSolution', () => {  
  const incrementAndPad = (num) => {
    const str = String(num + 1);
    return str.padStart(2, "0");
  }

  const now = new Date();
  const year = now.getUTCFullYear();
  const month = incrementAndPad(now.getUTCMonth());
  const date = now.getUTCDate();

  const url = `https://www.nytimes.com/svc/wordle/v2/${year}-${month}-${date}.json`;
  https.get(url, (res) => {
    let puzzleData = "";

    res.on("data", (chunk) => puzzleData += chunk);
    res.on('end', () => writeToFirestore(JSON.parse(puzzleData)))
  })

  const writeToFirestore = async ({ id, solution, print_date }) => {
    const db = admin.firestore();
    const batch = db.batch()

    const leaderboardsRef = db.collection('leaderboards');
    const leaderboardDocsSnapshot = await leaderboardsRef.get();

    leaderboardDocsSnapshot.forEach((snapshot) => {
      const leaderboardRef = snapshot.ref;
      const contestsRef = leaderboardRef.collection('contests');
      batch.set(contestsRef.doc(id), { solution, print_date });
    })

    await batch.commit()
  }
});

值得注意的是:

  • 排行榜文档中可能不存在“竞赛”集合。我希望这个函数能在集合不存在的情况下创建它
  • 上面的代码不会在控制台中抛出任何错误。它只是不写入Firestore。

感谢阅读!
我尝试获取对leaderboards集合中所有文档的引用,循环遍历每个文档,通过批处理将竞赛文档添加到嵌套的竞赛集合中,然后执行批处理。代码没有抛出错误,但没有写入Firestore。

o2g1uqev

o2g1uqev1#

我不确定是否有官方的方法来做到这一点,但我会使用Promise.all来一次性更新它们,如下所示:

const writeToFirestore = async ({ id, solution, print_date }) => {
   let promises = [];
   const db = admin.firestore();
   const leaderboardsRef = db.collection('leaderboards');
   const leaderboardDocsSnapshot = await leaderboardsRef.get();

   leaderboardDocsSnapshot.forEach((snapshot) => {
      const leaderboardRef = snapshot.ref;
      const contestsRef = leaderboardRef.collection('contests');
      promises.push(contestsRef.doc(id).set({ solution, print_date }));
   });
   return await Promise.all(promises);
};

以下是Promise.all的文档

相关问题