我有一个遗留的 Meteor 项目,其中包含“Order”对象和两个类似的方法:
updateOrderStatus: function(props) {
...
return Orders.update(
{
_id: props.orderInternalId
},
{
$set: {
statusHistory: statusHistory,
status: props.status
}
}
);
},
checkOrderStatus: function(props) {
...
// the update function call on both client and server
var updateStatus = function(order) {
newStatus = ...
Orders.update(
{
_id: order._id
},
{
$set: {
status: newStatus
}
}
);
};
if (Meteor.isClient) {
// for client, must subscribe to the order and fulfill first, else will return
Meteor.subscribe("orderByOrderId", { orderId: props.orderId }, function(
err
) {
if (err) return throwError(err);
var order = Orders.findOne({
orderId: props.orderId
});
updateStatus(order);
});
} else {
var order = Orders.findOne({
orderId: props.orderId
});
updateStatus(order);
}
}
调用上面的第一个方法时,该函数在客户端和服务器中运行两次。没有错误。没问题。
当调用第二个方法时,它会在客户端抛出这个错误:
update failed: Access denied. No allow validators set on restricted collection for method 'update'.
服务器上没有问题。订单更新已正确保存。
事实上,我们已经在生产中看到这个错误消息几个月了,它似乎没有影响任何东西。为什么这个错误会在客户端抛出,只是为了第二种方法?
注意:这个“订单”对象没有定义允许/拒绝的东西。
您正在订阅回调中更新。在回调中,您丢失了方法上下文。在客户端中,没有方法上下文就无法更新集合。
为什么对生产没有影响?方法在两侧运行。你在客户端失败然后在服务器上成功。
删除客户端逻辑(如果 Meteor.isClient ...)。目前没用
这个逻辑是针对optimistic ui的。如果你想解决这个问题,先订阅再调用方法。