Firebase 云函数多次执行

Firebase cloud-function multiple executions

我有一个 firebase (Google) 云函数如下

// Initialize the Auth0 client
var AuthenticationClient = require('auth0').AuthenticationClient;
var auth0 = new AuthenticationClient({
    domain:       'familybank.auth0.com',
    clientID:     'REDACTED'
});

function getAccountBalance(app) {
    console.log('accessToken: ' + app.getUser().accessToken);
    auth0.getProfile(app.getUser().accessToken, function (err, userInfo) {
        if (err) {
            console.error('Error getting userProfile from Auth0: ' + err);
        }
        console.log('getAccountBalance userInfo:' + userInfo)

        let accountowner = app.getArgument(PARAM_ACCOUNT_OWNER);

        // query firestore based on user
        var transactions = db.collection('bank').doc(userInfo.email)
                          .db.collection('accounts').doc(accountowner)
                          .collection('transactions');
        var accountbalance = transactions.get()
            .then( snapshot => {
                var workingbalance = 0
                snapshot.forEach(doc => {
                    workingbalance = workingbalance + doc.data().amount;
                });

                app.tell(accountowner + " has a balance of $" + workingbalance)
            })
            .catch(err => {
                console.log('Error getting transactions', err);
                app.tell('I was unable to retrieve your balance at this time.')
            });
    });
}
actionMap.set(INTENT_ACCOUNT_BALANCE, getAccountBalance);
app.handleRequest(actionMap);

执行时,我看到以下日志

注意部分函数被执行多次,第二次执行失败。如果我在记录 userInfo 后关闭 auth0.getProfile 调用,则该函数有效,但显然没有 userInfo.

知道为什么这个函数的某些部分会执行多次以及为什么有些调用会失败吗?

userInfo 在第 (2) 点未定义,因为出现错误(在其正下方的行中报告,这是先前记录的消息)。您的错误块不会离开函数,因此它会继续 运行 并使用无效的 userInfo 对象。

但这并不能解释为什么回调被调用两次 - 一次使用有效的 userInfo,一次使用 errAuthenticationClient.getProfile() 的文档(虽然不是示例)表明它 return 是一个 Promise(或 undefined - 虽然它没有说明为什么它可能 return undefined), 所以我想知道这是否最终会调用回调两次。

因为它 return 是一个 promise,你可以省略回调函数并用这样的方式处理它:

function getAccountBalance(app) {
    let accountowner = app.getArgument(PARAM_ACCOUNT_OWNER);
    console.log('accessToken: ' + app.getUser().accessToken);
    var accessToken = app.getUser().accessToken;
    auth0.getProfile( accessToken )

      .then( userInfo => {
        console.log('getAccountBalance userInfo:' + userInfo)

        // query firestore based on user
        var transactions = db.collection('bank').doc(userInfo.email)
                          .db.collection('accounts').doc(accountowner)
                          .collection('transactions');
        return transactions.get();
      })

      .then( snapshot => {
        var workingbalance = 0
        snapshot.forEach(doc => {
          workingbalance = workingbalance + doc.data().amount;
        });

        app.tell(accountowner + " has a balance of $" + workingbalance)
      })

      .catch( err => {
        console.error('Error:', err );
        app.tell('I was unable to retrieve your balance at this time.')
      })

    });
}