【发布时间】:2020-09-18 10:39:57
【问题描述】:
我正在尝试使用 Firestore 安全规则来编辑一些数据,如下所示,在 Flutter 中使用 transaction:
Future sendRequest(uidSend, uidRec, pid, title) async {
final crSend = ChatRequest(uid: uidRec, pid: pid, title: title);
var _lsSend = List();
_lsSend.add(crSend.toJson());
final crRec = ChatRequest(uid: uidSend, pid: pid, title: title);
var _lsRec = List();
_lsRec.add(crRec.toJson());
final uMSendDocref = userMetadataCollection.document(uidSend);
final uMRecDocref = userMetadataCollection.document(uidRec);
Firestore.instance.runTransaction((transaction) async {
await transaction.update(uMSendDocref, <String, dynamic>{
"sentRequests": FieldValue.arrayUnion(
_lsSend,
),
});
await transaction.update(uMRecDocref, <String, dynamic>{
"receivedRequests": FieldValue.arrayUnion(
_lsRec,
),
});
});
}
请注意,user1 正在尝试更新他/她自己的数据以及 user2 的数据。但是,我只希望 user1 能够更新 user2 的这个单个字段。我这样制定我的 Firestore 规则:
match /userMetadata/{uid} {
allow read: if uid == request.auth.uid || uid == 'PREVIEW';
allow write: if uid == request.auth.uid && uid != 'PREVIEW';
match /receivedRequests {
allow read: if uid == request.auth.uid;
allow write: if request.auth != null && request.auth.uid != 'PREVIEW';
}
match /sentRequests {
allow read: if uid == request.auth.uid;
allow write: if request.auth != null && request.auth.uid != 'PREVIEW';
}
}
receivedRequests(和sentRequests)只要求用户有一个非空的授权来编辑,即任何用户都应该能够编辑。但是,在运行事务时出现权限错误。这是为什么?也许我误解了 Firestore 规则?也许事务正在尝试读取?有什么想法吗?
更新:
我尝试使用批处理:
Future sendRequest(uidSend, uidRec, pid, title) async {
//update own uM with post
//update other uM with user
final crSend = ChatRequest(uid: uidRec, pid: pid, title: title);
var _lsSend = List();
_lsSend.add(crSend.toJson());
final crRec = ChatRequest(uid: uidSend, pid: pid, title: title);
var _lsRec = List();
_lsRec.add(crRec.toJson());
final uMSendDocref = userMetadataCollection.document(uidSend);
final uMRecDocref = userMetadataCollection.document(uidRec);
var batch = Firestore.instance.batch();
batch.updateData(uMSendDocref, <String, dynamic>{
"sentRequests": FieldValue.arrayUnion(
_lsSend,
),
});
batch.updateData(uMRecDocref, <String, dynamic>{
"receivedRequests": FieldValue.arrayUnion(
_lsRec,
),
});
return await batch.commit();
}
还是不行。 Firestore 的某些问题要么令人难以置信,要么存在严重的错误。
另外需要注意的是:一些 userMetadata 当前可能没有正在更新的字段。
【问题讨论】:
-
一个事务确实首先进行读取。这就是它如何在事务处理函数中获取要修改的文档的初始内容。也许您想要批量写入,而不是先读取。
-
或者,我可以只阅读文档的一部分吗?
-
读取操作(在客户端 SDK 和安全规则中)始终读取整个文档。
-
不要以为是这样。查看更新。
-
@OP 不是
receivedRequests和sentRequests集合吗? - 在这种情况下,“单字段”如何工作?
标签: firebase flutter google-cloud-firestore firebase-security