代码之家  ›  专栏  ›  技术社区  ›  Sahand

如何在then语句中定义firebase cloud函数触发器

  •  0
  • Sahand  · 技术社区  · 6 年前

    我需要确保在定义firebase函数之前运行此代码,因为它取决于代码中的变量集:

    const hotelBedTimeouts = [];
    
    var beds = db.ref('/beds');
    
    // Initialise the bed timeout holder object
    beds.once("value", function(snapshot){
      var hotels = snapshot.val();
    
      for (var i = 0; i < hotels.length; i++) {
        // push empty list to be filled with lists holding individual bed timeouts
        if(hotels[i]){
          hotelBedTimeouts.push([]);
          for(var j = 0; j < hotels[i].length; j++) {
            // this list will hold all timeouts for this bed
            hotelBedTimeouts[i].push({});
          }
        } else {
          hotelBedTimeouts.push(undefined);
        }
      }
    });
    

    有人建议我把这个函数放在 .then() 声明之后 once() 打电话来。所以我试了一下:

    const hotelBedTimeouts = [];
    
    var beds = db.ref('/beds');
    
    // Initialise the bed timeout holder object
    beds.once("value", function(snapshot){
      var hotels = snapshot.val();
    
      for (var i = 0; i < hotels.length; i++) {
        // push empty list to be filled with lists holding individual bed timeouts
        if(hotels[i]){
          hotelBedTimeouts.push([]);
          for(var j = 0; j < hotels[i].length; j++) {
            // this list will hold all timeouts for this bed
            hotelBedTimeouts[i].push({});
          }
        } else {
          hotelBedTimeouts.push(undefined);
        }
      }
    }).then( () => {
      // Frees a bed after a set amount of time
      exports.scheduleFreeBed = functions.database.ref('/beds/{hotelIndex}/{bedIndex}/email').onUpdate( (snapshot, context) => {
         // My code
    });
    

    不幸的是,这导致我的整个firebase函数被删除:

    $ firebase deploy --only functions
    
    === Deploying to 'company-23uzc'...
    
    i  functions: deleting function scheduleFreeBed...
    ✔  functions[scheduleFreeBed]: Successful delete operation.
    

    可以用这种方式定义一个firebase函数吗?

    如何确保firebase函数始终能够访问后端代码中定义的某些变量?

    编辑:

    这是我在道格·史蒂文森(Doug Stevenson)回答之后第一次尝试解决问题:

    const hotelBedTimeouts = [];
    var beds = db.ref('/beds');
    const promise = beds.once("value");
    
    // Frees a bed after a set amount of time
    exports.scheduleFreeBed = functions.database.ref('/beds/{hotelIndex}/{bedIndex}/email').onUpdate( (snapshot, context) => {
    
      promise.then( (snapshot) => {
          var hotels = snapshot.val();
    
          for (var i = 0; i < hotels.length; i++) {
            // push empty list to be filled with lists holding individual bed timeouts
            if(hotels[i]){
              hotelBedTimeouts.push([]);
              for(var j = 0; j < hotels[i].length; j++) {
                // this list will hold all timeouts for this bed
                hotelBedTimeouts[i].push({});
              }
            } else {
              hotelBedTimeouts.push(undefined);
            }
          }
        });
    
      var originalEmail = snapshot.after.val();
      var hotelIndex = context.params.hotelIndex;
      var bedIndex = context.params.bedIndex;
      if (originalEmail === -1) {
        clearTimeout(hotelBedTimeouts[hotelIndex][bedIndex].timeoutFunc); // clear current timeoutfunc
        return 0; // Do nothing
      }
    
      // replace old timeout function
      hotelBedTimeouts[hotelIndex][bedIndex].timeoutFunc = setTimeout(function () { // ERROR HERE
        var bedRef = admin.database().ref(`/beds/${hotelIndex}/${bedIndex}`);
        bedRef.once("value", function(bedSnap){
          var bed = bedSnap.val();
          var booked = bed.booked;
          if (!booked) {
            var currentEmail = bed.email;
            // Check if current bed/email is the same as originalEmail
            if (currentEmail === originalEmail) {
              bedSnap.child("email").ref.set(-1, function() {
                console.log("Freed bed");
              });
            }
          }
        });
      }, 300000); // 5 min timeout
    
    
      return 0;
    });
    

    不过,在执行函数时,似乎还没有正确定义hotelBedTimeouts,请看下面的错误:

    TypeError: Cannot read property '15' of undefined
    

    我在代码中的注释中标记了此错误的目的行。

    名单怎么还没有定义?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Doug Stevenson    6 年前

    Firebase CLI不支持这种类型的函数定义。相反,你应该开始最初的工作 里面 函数,然后缓存结果,这样就不必再次执行它了。或者,您可以尝试开始工作,并保留一个承诺,该功能可以在以后使用,例如:

    const promise = doSomeInitialWork()  // returns a promise that resolves with the data
    
    exports.scheduleFreeBed = functions.database.ref(...).onUpdate(change => {
        promise.then(results => {
            // work with the results of doSomeInitialWork() here
        })
    })