【问题标题】:How can I write a Scheduled Function in TypeScript to reset userHighScore for all users in my Firebase Realtime Database?如何在 TypeScript 中编写计划函数来重置 Firebase 实时数据库中所有用户的 userHighScore?
【发布时间】:2019-10-05 19:40:36
【问题描述】:

我有一个带有排行榜的 iOS/swift 游戏,我希望在每周一上午 12:00 将分数全部重置为 0。

我已全部设置好 Cloud Functions,并且我的 index.ts 中有代码,这些代码将在每周一上午 12:00 运行,但我不确定如何在 TypeScript 中编写代码以将所有 userHighScores 更新为 0。

这是我目前在 index.ts 中的内容:

import * as functions from 'firebase-functions';

functions.pubsub.schedule(‘0 0 * * 1’).onRun((context) => {


    // This code should set userHighScore to 0 for all users, but isn't working 

    .ref('/users/{user.user.uid}/').set({userHighScore: 0});


console.log(‘This code will run every Monday at 12:00 AM UTC’); 
});

保存上述代码并在终端中运行“firebase deploy”后,我看到的错误如下:

Found 23 errors.

npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! functions@ build: `tsc`
npm ERR! Exit status 2
npm ERR! 
npm ERR! Failed at the functions@ build script.
npm ERR! This is probably not a problem with npm. There is likely 
additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/derencewalk/.npm/_logs/2019-05-19T00_39_38_037Z-debug.log

Error: functions predeploy error: Command terminated with non-zero exit code2

当我 Firebase 仅部署 console.log 代码时没有任何错误,所以我很确定这只是 .ref 代码行格式错误。正确的语法是什么?

提前感谢您的帮助。

更新

这是每周一上午 12:00 更新数据库中所有用户的所有 userHighScores 的工作代码:

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

export const updateHighScores = functions.pubsub.schedule('0 0 * * 1').onRun((context) => {

//console.log(‘This code will run every Monday at 12:00 AM UTC’);
const db = admin.database();
return db
  .ref('users')
  .once('value')
  .then(snapshot => {
    const updates:any = {};
    snapshot.forEach((childSnapshot:any) => {
      const childKey = childSnapshot.key;
      updates['users/' + childKey + '/userHighScore'] = 0;
      updates['users/' + childKey + '/earnedExtraTime'] = 0;
    });
    return db.ref().update(updates);
  });
});

【问题讨论】:

    标签: typescript firebase google-cloud-functions


    【解决方案1】:

    你的代码有几个问题。

    首先,ref() 是一个 Reference 的方法,在 Node.js 的 Admin SDK(如果你想与实时数据库交互,它是在云函数中使用的 SDK)。因此你需要做类似admin.database().ref(...).set({userHighScore: 0});

    其次,用'/users/{user.user.uid}/' 声明Reference 将不起作用,因为您需要将字符串或现有引用传递给ref() 方法(或根本没有,在这种情况下它将指向数据库的根目录)。见https://firebase.google.com/docs/reference/admin/node/admin.database.Database#ref

    第三,如果要修改users节点下的所有子节点,首先需要用once()方法查询它们,然后为每个子节点写入新值,用@987654335 @ 或 update() 方法。

    我假设你的数据库结构如下:

    databaseRoot
        - users
            - user1_uid
                - userName: "xyz"
                - userHighScore: 66
                - otherDataElement: ....
            - user2_uid
                - userName: "abcd"
                - userHighScore: 32
                - otherDataElement: ....
    

    因此我建议将您的代码修改如下:

    import * as functions from 'firebase-functions';
    import * as admin from 'firebase-admin';
    admin.initializeApp();
    
    
    export const updateHighScores = functions.pubsub.schedule(‘0 0 * * 1’).onRun((context) => {
    
        // This code should set userHighScore to 0 for all users, but isn't working
        //console.log(‘This code will run every Monday at 12:00 AM UTC’);
        const db = admin.database();
        return db
          .ref('users')
          .once('value')
          .then(snapshot => {
            const updates = {};
            snapshot.forEach(childSnapshot => {
              const childKey = childSnapshot.key;
              updates['users/' + childKey + '/userHighScore'] = 0;
            });
            return db.ref().update(updates);
          });
    });
    

    请注意,我们添加了 Admin SDK(请参阅 https://firebase.google.com/docs/admin/setup#add_the_sdk)并对其进行初始化(请参阅 https://firebase.google.com/docs/admin/setup#initialize_without_parameters

    【讨论】:

    • 非常感谢!我遇到了错误,但已经解决了其中一些问题。 “错误 TS1002:未终止的字符串文字”已通过重新键入“.schedule('0 0 * * 1')”中的撇号来修复,以便它们是直的。接下来说“错误 TS7017:元素隐式具有 'any' 类型,因为类型 '{}' 没有索引签名。”似乎已通过在函数上方添加此代码来解决:“interface updates {[key:string]: any;}”(如此处建议:stackoverflow.com/questions/42193262/…
    • 但我仍然从原始帖子中得到所有相同的“nmp ERR!”。我尝试更新到 TypeScript 3.3.1(如此处建议:stackoverflow.com/questions/54498868/…),但仍然出现所有错误。你知道这些错误发生了什么吗?再次感谢!
    • 所有错误都已解决,代码部署和运行完美! :) 我现在将更新帖子以显示工作代码。非常感谢您的帮助!
    • 它只需要在两个地方添加 ":any":在 "const updates" 和 ".forEach(childSnapshot" 之后"
    • 很高兴我能提供帮助。不要犹豫相应地更新代码,因为我无法测试它!
    猜你喜欢
    • 2021-09-03
    • 2020-11-25
    • 1970-01-01
    • 2021-11-02
    • 2018-09-10
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 2019-05-24
    相关资源
    最近更新 更多