首页 > 解决方案 > 有没有办法加快这个 Firebase 云功能的执行时间?

问题描述

我有以下正确执行的firebase云功能(js sdk)。我想知道是否有办法加快执行时间。此函数平均需要 250 毫秒,其中 userGroups 集合包含 10 个项目。我希望使用包含大约 500 个项目的 userGroups 集合来运行此函数。任何帮助表示赞赏!

.ref('users/{userId}/mood/')
.onUpdate((change, context) => {
  const userId = context.params.userId
  const beforeData = change.before.val(); 
  const afterData = change.after.val(); 
  const afterDataValue = parseInt(afterData.value || 0);
  const afterDataElement = afterData.element;
  const beforeDataValue = parseInt(beforeData.value || 0);
  const beforeDataElement = beforeData.element;

  const userGroups = admin.database().ref('/users/' + userId + '/groups/location/Items');

  const groupMood = userGroups.once("value")
  .then(function(snapshot) {
    snapshot.forEach(function(childSnapshot){
      const itemId = childSnapshot.key
      const currentElementValueRef = admin.database().ref('/groups/location/Items/' + itemId + '/mood/' + afterDataElement + '/value');
      const currentElementVoteCountRef = admin.database().ref('/groups/location/Items/' + itemId + '/mood/' + afterDataElement + '/votecount');


      if(beforeDataElement){
        const previousElementValueRef = admin.database().ref('/groups/location/Items/' + itemId + '/mood/' + beforeDataElement + '/value');
        const previousElementVoteCountRef = admin.database().ref('/groups/location/Items/' + itemId + '/mood/' + beforeDataElement + '/votecount');

        previousElementValueRef.transaction(value => {
          return (parseInt(value || 0) - beforeDataValue>0?parseInt(value || 0) - beforeDataValue:0)
        })

        currentElementValueRef.transaction(value => {
          return parseInt(value || 0) + afterDataValue
        })

        previousElementVoteCountRef.transaction(votecount => {
          return (parseInt(votecount || 0) - 1>0?parseInt(votecount || 0) - 1:0)
        })

        currentElementVoteCountRef.transaction(votecount => {
          return parseInt(votecount || 0) + 1
        }) 

      } else {     
        currentElementValueRef.transaction(value => {
          return parseInt(value || 0) + afterDataValue
        })

        currentElementVoteCountRef.transaction(votecount => {
          return parseInt(votecount || 0) + 1
        })

        const voteCountRef = admin.database().ref('/groups/location/Items/' + itemId + '/mood/votecount');

        voteCountRef.transaction(votecount => {
          return parseInt(votecount || 0) + 1
        })  
      } 
    })
  })
  return groupMood })

标签: firebase-realtime-databasegoogle-cloud-functions

解决方案


看起来您正在循环内从数据库中读取数据。如果我不得不猜测,那就是函数的大部分时间都花在了那里。三个想法:

  1. 在你做任何其他事情之前:你应该检查什么实际上需要时间,而不是依赖我的预感。您可以使用https://cloud.google.com/trace/或简单地将一些console.log()语句添加到您的代码中。

  2. /groups/location/Items/当函数启动时,您可能会将整个集合读入一个变量。然后您的代码将简单地从循环中的该变量中读取(快速),而不是从数据库中读取(慢速)。只有当/groups/location/Items/集合足够小以适合内存时,这才有可能。

  3. 您可以在每次/users/***/groups/location/Items更新时进行小计算,并将其存储在数据库中的节点中,而不是像上面那样运行一项大作业。我不完全理解您的代码的作用,但是过去许多小计算而不是单个大计算的模式对我很有帮助。

祝你好运!


推荐阅读