Cloud Functions 数据操作问题中的 Firebase Admin

Firebase Admin in Cloud Functions data manipulation problem

Firebase 实时数据库结构

freepacks 包含 2 个重要元素:

  1. current,即我将从移动应用程序下载的测验包 ID(从 quizpacks 检索)。
  2. history,这是一个节点,我在其中添加我在 current 中随时间推移使用 Cloud Functions 中的计划函数添加的所有测验包 ID。

每次云函数执行时我需要做什么

第 1 步:history 中添加 current 的值和当前时间戳。

第 2 步:current 值替换为历史上 没有 的另一个测验包 ID。

完成

我是如何尝试完成这个目标的

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

admin.initializeApp();

exports.scheduledFunction = functions.pubsub.schedule('* * * * *').onRun((context) => {

    // Current timestamp
    const dt = new Date();
    const timestamp = `${
        (dt.getMonth()+1).toString().padStart(2, '0')}/${
        dt.getDate().toString().padStart(2, '0')}/${
        dt.getFullYear().toString().padStart(4, '0')} ${
        dt.getHours().toString().padStart(2, '0')}:${
        dt.getMinutes().toString().padStart(2, '0')}:${
        dt.getSeconds().toString().padStart(2, '0')}`

    // Download the entire node 'freepacks'
    return admin.database().ref('quiz/freepacks').once('value').then((currentSnap) => {
        const currentPack = currentSnap.val().current;

        // Add current to history
        admin.database().ref('quiz/freepacks/history/' + currentPack).set(timestamp);
        
        // Download entire history node
        admin.database().ref('quiz/freepacks/history').once('value').then((historySnap) => {
            const history = historySnap.val();
            console.log('HISTORY: ' + history);

            // Download entire quizpacks node
            admin.database().ref('quiz/quizpacks').once('value').then((quizpacksSnap) => {
                for(quizpack in Object.keys(quizpacksSnap.val())) {
                    console.log('ITERANDO: ' + quizpack);
                    // Add the new current if it isn't in history
                    if (historySnap[quizpack] == undefined) {
                        admin.database().ref('quiz/freepacks/current').set(quizpack);
                        break;
                    }
                }
            });

        })

    });
    
});

我从前面的代码中得到了什么

起点:

第一次执行:历史更新良好,但更新current无效

第二次执行广告等等... current 不再更新(卡在 0)

我对 JavaScript 和 Firebase Admin 的体验是 ~0...我的代码有什么问题?在此先感谢您的帮助!

首先是所有 read/write 操作 return 承诺,因此您应该处理它们。在这个答案中,我使用了 async-await 语法。 .ref("quiz/freepacks") 获取完整节点,即当前节点和历史节点,因此您不必像在原始代码中那样再次查询历史节点。其他更改只是 Javascript 调整,例如使用 .find() 而不是 for-loop 等等..

尝试将函数更改为:

exports.scheduledFunction = functions.pubsub
  .schedule("* * * * *")
  .onRun(async (context) => {
    // Getting Date
    const dt = new Date();
    const timestamp = `${(dt.getMonth() + 1).toString().padStart(2, "0")}/${dt
      .getDate()
      .toString()
      .padStart(2, "0")}/${dt.getFullYear().toString().padStart(4, "0")} ${dt
      .getHours()
      .toString()
      .padStart(2, "0")}:${dt.getMinutes().toString().padStart(2, "0")}:${dt
      .getSeconds()
      .toString()
      .padStart(2, "0")}`;

    // Download the entire node 'freepacks'
    const currentSnap = await firebase
      .database()
      .ref("quiz/freepacks")
      .once("value");

    // Checking current free pack ID and array of previous free packs
    const currentPack = currentSnap.val().current || "default";
    const freeHistoryIDs = [
      ...Object.keys(currentSnap.val().history || {}),
      currentPack,
    ];

    // Add current free pack to free history
    await firebase
      .database()
      .ref("quiz/freepacks/history/" + currentPack)
      .set(timestamp);

    // Download entire quizpacks node
    const quizpacksSnap = await firebase
      .database()
      .ref("quiz/quizpacks")
      .once("value");

    const quizPackIDs = Object.keys(quizpacksSnap.val() || {});

    const newPack = quizPackIDs.find((id) => !freeHistoryIDs.includes(id));
    console.log(newPack);
    if (!newPack) {
      console.log("No new pack found")
    }
    return firebase.database().ref("quiz/freepacks/current").set(newPack || "none");
  });