如何使用云功能和云FIrestore维护状态

时间:2018-06-12 00:19:07

标签: firebase google-cloud-firestore google-cloud-functions

使用云功能时,如何保持正确的状态?它们不能保证以与它们被调用的顺序相同的方式发射。

以下是一系列事件:

  1. 文档已更新currentState: state1
  2. 文档已更新currentState: state2
  3. 云功能会触发state2更新。
  4. 云功能会触发state1更新。
  5. 如果您的应用程序要求以正确的状态顺序执行功能,则会出现问题。

1 个答案:

答案 0 :(得分:3)

云功能无法保证按顺序启动或仅启动一次。因此,你必须使它们具有幂等性。

您可以通过以下方式解决此问题:

  1. 始终使用交易来更新状态,以便2个客户不会同时尝试更改状态。
  2. 创建一个状态表,用于管理状态并根据当前状态与先前状态运行函数。
  3. 客户端不得将状态更改为小于当前存在的值。
  4. states.json

    [
      {"currentState": "state1", "action": "state2", "newStates": ["state2"]},
      {"currentState": "state1", "action": "state3", "newStates": ["state2", "state3"]},
      {"currentState": "state1", "action": "state4", "newStates": ["state2", "state3", "state4"]},
      {"currentState": "state1", "action": "state5", "newStates": ["state2", "state3", "state4", "state5"]},
      {"currentState": "state2", "action": "state3", "newStates": ["state3"]},
      {"currentState": "state2", "action": "state4", "newStates": ["state3", "state4"]},
      {"currentState": "state2", "action": "state5", "newStates": ["state3", "state4", "state5"]},
      {"currentState": "state3", "action": "state4", "newStates": ["state4"]},
      {"currentState": "state3", "action": "state5", "newStates": ["state4", "state5"]},
      {"currentState": "state4", "action": "state5", "newStates": ["state5"]}
    ]
    

    app.js

    function processStates (beforeState, afterState) {
      const states = require('../states');
      let newStates;
    
      // Check the states and set the new state
      try {
        newStates = states.filter(function(e) {return e.currentState == beforeState && e.action == afterState;})[0].newStates;
      }
      catch (err) {
        newStates = null;
      }
    
      console.log(`newStates: ${newStates}`);
    
      if (newStates) {
        newStates.forEach(newState) {
          // Process state change here
          switch (newState) {
            case 'state1': {
              // Process state1 change
              break;
            }
            case 'state2': {
              // Process state2 change
              break;
            }
            default: {
            }
          }
        }
      }
    }
    

    拥有状态数组后,您可以使用forEachmap等内容来迭代处理所需的命令。