javascript - 如何停止执行 Firebase 触发的 Firebase 函数?

标签 javascript typescript firebase firebase-realtime-database google-cloud-functions

背景

据我所知,Firebase 触发的函数可以从一个触发事件运行多次(我想我可以从 Firebase 的日志中看到这一点)。

由于这可能是一种数据损坏行为,我想实现一些标志,如果发现该标志为 true,该功能将允许该函数停止。

在数据库中创建该对象后,我希望此函数 (Typescript) 只运行一次。

例如:

adm.database().ref('/Users/{UserID}')

我计划在数据库中为每个用户节点存储一个键值对:

{"alreadyTriggered":true}

或者将'trigger'存储在一个单独的节点中,都没有关系。

然后当 Firebase 决定触发相应的函数时,我会检查并停止函数的执行,如果它不是第一次运行的话:

data = snapshot.val();
if (data.alreadyTriggered) {
    return;
}
// The function continues here

实现

(部分括号可以省略,是在浏览器窗口写的伪代码-Typescript)

索引.ts:

    import * as u from './users';
    import * as ff from 'firebase-functions';
    import * as adm from 'firebase-admin';
    import * as types from './types';

    // Triggered function
    export const userCreated = ff.database.ref('/Users/{userId}').onCreate((sn, ctx) => {
      let user: types.User = sn.val();
      console.log(`New user created, User Id: ${ctx.params.userId}`);
      return u.onCreated(user);
    });

用户.ts:

// Function implementation

export function onCreated(user: types.User): Promise<void> {
    return adm.database().ref("/Triggers").once('value', snapshot => {
        let data: any = snapshot.val();
        const alreadyTriggered: boolean = data.alreadyTriggered; 
    }).then(alreadyTriggered => {
        if (alreadyTriggered) {
            // We would like to stop any execution here
            return
        }
        else {
            console.log(`Continuing processing`)
        }
    }).then(() => {
        // This code should be reached only if alreadyTriggered is set to false
        // do actual work with the user object
        //...someNewData
        //then save it
        adm.database().ref('/Users').child(user.userId).update(someNewData)
    })
}

问题

问题是我不知道如何可靠地停止执行函数。我尝试使用 return(不起作用)、break(仅用于循环),然后我开始使用 throw new Error('Stopping function execution' ),但它似乎并没有可靠地停止 - 有时我在日志中看到函数 确实 继续执行,尽管 alreadyTriggered 肯定是 true

问题

如何从代码中停止执行 Firebase Typescript 函数?

最佳答案

您的 return 语句没有从顶级函数返回。它只是从您传递给 then() 的 lambda 函数返回。您必须沿着 promise 链传播信息,以告知下一个回调是否执行其工作。

return adm.database().ref("/Triggers").once('value', snapshot => {
    let data: any = snapshot.val();
    const alreadyTriggered: boolean = data.alreadyTriggered; 
}).then(alreadyTriggered => {
    if (alreadyTriggered) {
        // We would like to stop any execution here
        return false
    }
    else {
        console.log(`Continuing processing`)
        return true
    }
}).then((continue) => {
    // This code should be reached only if alreadyTriggered is set to false
    // do actual work with the user object
    //...someNewData
    //then save it
    if (continue) {
        return adm.database().ref('/Users').child(user.userId).update(someNewData)
    }
})

您还错过了上面 update 返回的 promise 的返回,这会导致您的函数超时。

请注意,使用 async/await 语法这一切都容易得多。

关于javascript - 如何停止执行 Firebase 触发的 Firebase 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59515529/

相关文章:

javascript - 将 MySQL 数组转换为 json 数组

firebase - Firebase存储配额已超出

javascript - 如何使 Visual Studio Code 使用路径映射进行自动导入?

typescript - Angular2 (beta3) "expression has changed after it was checked"更新表单值

javascript - Firestore 查询具有类似数组的文档 (Node.js/Admin SDK)

http - Firebase 托管,禁用 HTTPS?

javascript - 选择 onChange 事件触发从数组值填充隐藏输入值的 javascript

javascript - 使用正则表达式删除特殊字符

javascript - 具有延迟的 hoverintent 函数

node.js - 如何使用 Typescript 读取多个 parquet 文件?