Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Firebase实时数据库事务和云功能_Node.js_Firebase_Firebase Realtime Database_Google Cloud Functions - Fatal编程技术网

Node.js Firebase实时数据库事务和云功能

Node.js Firebase实时数据库事务和云功能,node.js,firebase,firebase-realtime-database,google-cloud-functions,Node.js,Firebase,Firebase Realtime Database,Google Cloud Functions,我在Firebase实时数据库中有一个列表,结构如下: list: { change: { rate: integer, last: Date }, lock: string, elements: { ... }, size: integer } 客户端只向列表中添加元素。 元素的子元素上的onCreate事件触发了一个云函数。它事务性地增加数据库中的list.size,然后对可能涉及删除全部或部分子元素的元素执行计算。 还有一个云函数是由元素的

我在Firebase实时数据库中有一个列表,结构如下:

list: {
  change: {
    rate: integer,
    last: Date
  },
  lock: string,
  elements: {
    ...
  },
  size: integer
}
客户端只向列表中添加元素。 元素的子元素上的
onCreate
事件触发了一个云函数。它事务性地增加数据库中的
list.size
,然后对可能涉及删除全部或部分子元素的元素执行计算。 还有一个云函数是由元素的子元素上的
onDelete
事件触发的,该事件只在数据库中事务性地递减
list.size
。 问题是计数器在一段时间后变得不准确。有时它会显示列表中的更多元素,有时会显示更少的元素。 以下是[调整后的]代码:

exports.element_add=functions.database.ref('/list/elements/{element}).onCreate( (快照、上下文)=>{ 常量元素=snapshot.ref.parent; 回报新的承诺( (解决、拒绝)=>{ const start=new Date().getTime(); 异步瀑布( [ //读写到list.change // ... (下一步)=>{ //增量列表大小 _changeSize(elements.parent,+1,1,next) }, //如果需要,获取锁并对列表元素进行计算 // ... ], //最后 职能(e){ //松开锁 // ... //处理错误 如果(e) 退货拒收(e); 解决(); } ); }); }); exports.element_remove=functions.database.ref('/list/elements/{element}).onDelete( (快照、上下文)=>{ 常量元素=snapshot.ref.parent; 回报新的承诺( 功能(解析、拒绝){ _changeSize(elements.parent,-1,1, 职能(e){ 如果(e) 退货拒收(e); 解决(); } ) } ) }); 函数_changeSize(列表、增量、尝试、完成){ list.child('size')。事务( //更新 (大小)=>{ 如果(大小===null) 返回null; 返回大小+增量; }, //最后 (e、提交、快照){ 如果(e){ 错误(`size transaction error:${e},1秒后重试`); //再试一次 返回setTimeout(_changeSize,1000,list,delta,尝试+1,完成); } log(提交?`新列表大小为${snapshot.val()}`:'列表大小未更新'); //如果提交,则返回新大小 完成(空,已提交?snapshot.val():未定义); }, //不要在本地申请 假的 ); } 除了上面的两个云函数外,没有其他实体使用
list.size
。问题是为什么
list.size
的值与
list.elements
不同步


更新2020-02-26:显然,某些onCreate/onDelete事件被多次接收!我们观察到它们在云函数的实例之间传播了3次。这是正常行为还是我们做错了什么?

您必须使用实时数据库

如下所示,用于递增:

exports.element_add = functions.database.ref('/list/elements/{element}').onCreate(
  (snapshot, context) => {

    const sizeRef = admin
    .database()
    .ref('/list/size');

    return sizeRef
      .transaction(current_value => {
        return (current_value || 0) + 1;
      });

});
exports.element_delete = functions.database.ref('/list/elements/{element}').onDelete(
  (snapshot, context) => {

    const sizeRef = admin
    .database()
    .ref('/list/size');

    return sizeRef
      .transaction(current_value => {
        if (current_value > 0) {
            return current_value - 1;
        } else  {
           //Normally we should never reach this line...
           return null;
        }
      });

});
并按以下方式递减:

exports.element_add = functions.database.ref('/list/elements/{element}').onCreate(
  (snapshot, context) => {

    const sizeRef = admin
    .database()
    .ref('/list/size');

    return sizeRef
      .transaction(current_value => {
        return (current_value || 0) + 1;
      });

});
exports.element_delete = functions.database.ref('/list/elements/{element}').onDelete(
  (snapshot, context) => {

    const sizeRef = admin
    .database()
    .ref('/list/size');

    return sizeRef
      .transaction(current_value => {
        if (current_value > 0) {
            return current_value - 1;
        } else  {
           //Normally we should never reach this line...
           return null;
        }
      });

});

你必须使用实时数据库

如下所示,用于递增:

exports.element_add = functions.database.ref('/list/elements/{element}').onCreate(
  (snapshot, context) => {

    const sizeRef = admin
    .database()
    .ref('/list/size');

    return sizeRef
      .transaction(current_value => {
        return (current_value || 0) + 1;
      });

});
exports.element_delete = functions.database.ref('/list/elements/{element}').onDelete(
  (snapshot, context) => {

    const sizeRef = admin
    .database()
    .ref('/list/size');

    return sizeRef
      .transaction(current_value => {
        if (current_value > 0) {
            return current_value - 1;
        } else  {
           //Normally we should never reach this line...
           return null;
        }
      });

});
并按以下方式递减:

exports.element_add = functions.database.ref('/list/elements/{element}').onCreate(
  (snapshot, context) => {

    const sizeRef = admin
    .database()
    .ref('/list/size');

    return sizeRef
      .transaction(current_value => {
        return (current_value || 0) + 1;
      });

});
exports.element_delete = functions.database.ref('/list/elements/{element}').onDelete(
  (snapshot, context) => {

    const sizeRef = admin
    .database()
    .ref('/list/size');

    return sizeRef
      .transaction(current_value => {
        if (current_value > 0) {
            return current_value - 1;
        } else  {
           //Normally we should never reach this line...
           return null;
        }
      });

});

您提到了一个实时数据库事务。您如何执行交易?为什么不使用标准事务机制()?事务实际上在
\u changeSize()
中使用。请看第一行,你提到了一个实时数据库事务。您如何执行交易?为什么不使用标准事务机制()?事务实际上在
\u changeSize()
中使用。请看第一行。事务实际上在
\u changeSize()
中使用。请看第一行。您是使用真正的实时数据库事务,还是使用另一个
node.js
库来实现此“事务”?真正的事务。
\u changeSize
接收到“list”ref,然后它在
list.size
上启动一个事务。你能把
\u changeSize
的确切代码添加到你的问题中吗?都在代码片段中。代码段中有3个函数<代码>\u changeSize()是最后一个。事务实际上在
\u changeSize()
中使用。请看第一行。您是使用真正的实时数据库事务,还是使用另一个
node.js
库来实现此“事务”?真正的事务。
\u changeSize
接收到“list”ref,然后它在
list.size
上启动一个事务。你能把
\u changeSize
的确切代码添加到你的问题中吗?都在代码片段中。代码段中有3个函数<代码>\u changeSize()是最后一个。