UPDATE
现在可以自动更新多个位置。看这篇博文了解详情。
var mergedUpdate = {};
mergedUpdate[ 'users/' + userId + '/widgets/' + widgetId ] = true;
mergedUpdate[ 'widgets/' + widgetId ] = widgetData;
var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com/");
ref.update(mergedUpdate);
这不会强制执行事务数据(如果值当前为 X,则将其设为 Y),但这部分可以移至安全规则。例如,如果我们想同时更新两个计数器,我们可以添加如下规则:
{
"counter1": {
".validate": "newData.val() === (data.val()||0)+1"
},
"counter2"1 {
".validate": "newData.val() === (data.val()||0)+1"
}
}
现在我们可以尝试与上面相同的多路径更新。如果自我们上次从服务器读取值以来这些值已更改,则尝试将失败。我们可以检查if( error.code === 'PERMISSION_DENIED' ) { ... }
查看失败是否是由于验证造成的,然后相应地重试。
原帖
做到这一点的唯一方法是在共同祖先上运行事务。
例如,如果您想更新 /a/b/c 和 /a/x/y,您可以在 /a 运行事务并更改这两个值。
这种方法的缺点是网络 I/O 的成本可能很高,因为事务中的所有数据都需要下载然后发送回服务器。
您可能需要考虑的一种更复杂但可能更强大的方法是重组数据,这样您就可以存储编辑历史记录,而不是存储实际值。例如,如果您要存储银行余额信息,则可以存储存款和取款的历史记录。然后,当您想要获得余额时,您将回放整个历史记录并计算最终余额。
这种方法的优点在于它可以让您进行原子更新。例如,如果您要将资金从账户 A 转账到账户 B,您只需在日志末尾附加一个元素,表示“从账户 A 转账到账户 B N 美元”。附加该单个元素是一个原子操作。
这就是我们采取的方法Firepad,我们的协作文本编辑器。