Ale*_*ser 5 firebase firebase-security flutter google-cloud-firestore
我正在尝试使用 Firestore 安全规则来编辑一些数据,如下所示,在 Flutter 中有一个事务:
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,
),
});
});
}
Run Code Online (Sandbox Code Playgroud)
请注意,用户 1 正在尝试更新他/她自己的数据以及用户 2 的数据。但是,我只希望 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';
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
Run Code Online (Sandbox Code Playgroud)
仍然不起作用。Firestore 的某些东西要么非常不直观,要么存在严重的错误。
另一件要注意的事情:一些 userMetadata 当前可能没有正在更新的字段。
我只希望 user1 能够更新 user2 的这个单个字段。
只允许更新某些字段的一般方法是检查request.resource.datawith的 diff resource.data。
需要更新的示例文档有 3 个字段:名称、城市、standingBalance。我们希望任何人都可以更改standingBalance,但只有相应的用户才能更改他的姓名和城市。
下面的例子考虑的是 user1 应该拥有对 的完全write访问权限user1's sendRequest并且只能single field update访问user2's receivedRequests,其他场景不会有太大变化。
match /userMetadata/{uid} {
allow read: if uid == request.auth.uid || uid == 'PREVIEW';
allow write: if uid == request.auth.uid && uid != 'PREVIEW';
match /receivedRequests/{req} {
allow read: if uid == request.auth.uid;
allow write: if uid == request.auth.uid;
allow update: if uid == request.auth.uid
|| (request.resource.data.keys().hasOnly(['name','city','standingBalance'])
&& request.resource.data.name == resource.data.name
&& request.resource.data.city == resource.data.city
&& request.resource.data.standingBalance != resource.data.standingBalance
&& request.auth.uid != null
)
}
match /sentRequests/{req} {
allow read: if uid == request.auth.uid;
allow write: if request.auth != request.auth.uid || request.auth.uid != 'PREVIEW';
}
Run Code Online (Sandbox Code Playgroud)
检查以hasOnly确保没有其他键添加到文档中。另外,我不知道“预览”是什么,所以请自行验证规则。
在 firestore 规则中包含一个fieldsChanged变量将是一个很好的功能请求;)
| 归档时间: |
|
| 查看次数: |
159 次 |
| 最近记录: |