首页 文章

Firebase的 Cloud 功能多次调用

提问于
浏览
7

我正在尝试使用Firebase的 Cloud 功能,以便将我的 firebase-queue 工作人员转移到 Cloud 功能 . 每当我在给定的ref创建一个新节点时,我添加了一个简单的函数来添加最后更新的时间戳 . 该函数如下所示:

var functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp(functions.config().firebase);

exports.setLastUpdatedTimestamp = functions.database.ref('/nodes/{nodeId}')
  .onWrite(event => {
    const original = event.data.val();
    console.log('Adding lastUpdatedTimestamp to node ', original.name);
    return event.data.ref.child('lastUpdatedAtFromFC').set(Date.now());
  });

我部署了这个 Cloud 功能,并从我的应用程序中添加了一个节点 . 我转到Firebase Functions仪表板,看到该函数已被调用169次,我不明白为什么 . 当我查看日志时,我会看到日志,例如将函数附加到所有过去的节点 .

是否 onWrite 的行为类似于 child_added ,并为所有现有实体运行该函数?

每当我再次更改和部署该功能时,是否会重复此操作?

我期待它只为新添加的节点运行一次 .

3 回答

  • 9

    编写处理数据库写入的函数时,这是一个常见的错误 . 当你在一个位置处理初始写入的事件时,再做一次写回到同一个位置,第二次写入将触发另一个将再次运行该函数的事件,依此类推,这将是一个无限循环 .

    您需要在函数中使用一些逻辑来确定第二个写事件是否不应该重写到数据库 . 这将阻止循环 . 在您的情况下,您不需要函数来设置上次更新时间 . 您可以在客户端上使用特殊值来指示服务器将当前时间插入字段 .

    https://firebase.google.com/docs/reference/js/firebase.database.ServerValue#.TIMESTAMP

  • 7

    道格是正确的 . 另外,最好知道如果你有一个函数卡在无限循环中,让它停止的方法是重新部署你的函数(使用 firebase deploy )和循环修复,或者完全删除函数(将其从 index.js 中删除并运行 firebase deploy ) .

  • 0

    我有这个问题 . 这里有两个问题 . 一旦它开始,如何停止无限循环 . 那已经回答了 . 但真正的问题是如何使用Firebase Cloud 功能触发器将lastUpdated日期字段添加到对象 .

    这是我尝试处理 onWrite() 循环问题 .

    const functions = require('firebase-functions');
    const admin = require('firebase-admin');
    admin.initializeApp();
    
    
    exports.onWriteFeatherUpdateSummary = functions.database.ref('/messages/{id}')
        .onWrite((change, context) => {
          // Grab the current value of what was written to the Realtime Database.
          let updated = change.after.val();
          // Grab the previous value of what was written to the Realtime Database.
          const previous = change.before.val();
          let isChanged = true;
          let isCreated = (previous === null); // object 'created'
    
          // Only when the object gets updated
          if (!isCreated) {
            // An object should never directly change the lastUpdated value, this is for trhe trigger only
            isChanged = (updated.lastUpdated === previous.lastUpdated);
          }
    
          console.log(`isChanged: ${isChanged} ; isCreated: ${isCreated}`);
    
          if(isChanged) {
            // Insert whatever extra data you wnat on the update trigger
            const summary = `This is an update!`;
    
            // Add a 'createdDate' field on the first trigger
            if (isCreated) {
              // Make sure your object has a createdDate (Date) before the lastUpdated (Date)!
              Object.assign(updated,
                  {
                    createdDate : admin.database.ServerValue.TIMESTAMP
                  }
                );
            }
    
            // Add lastUpdated Date field on very update trigger (but not when you just changed it with the trigger!)
            Object.assign(updated,
                {
                  summary : summary,
                  lastUpdated : admin.database.ServerValue.TIMESTAMP
                }
              );
          }
    
          return change.after.ref.set(updated);
        });
    

相关问题