Я недавно был вставлен в проект, который использует firebase, и я работаю над правилами безопасности, я смог успешно создать правила для почти всего и юнит-тесты для большинства случаев. К сожалению, я забыл о транзакциях, которые выполняются после создания некоторых документов. Например, после создания запроса он также добавляется в requests
внутри каждого пользователя, который является его частью, consumer
и provider
.
match /Requests/{requestId} {
allow read: if readRequest();
allow create: if createRequest();
}
match /Users/{userId} {
allow read: if isSignedIn();
allow update: if isUser(userId);
}
function isUser(userId) {
return request.auth.uid == userId;
}
function createRequest() {
return incomingData().archived == false &&
incomingData().attachmentURLs is list &&
incomingData().description is string &&
incomingData().location is string &&
incomingData().minPrice is int &&
incomingData().maxPrice is int &&
incomingData().requestStateDate is timestamp &&
incomingData().serviceId is string &&
incomingData().serviceType is string &&
incomingData().state == 'requested' &&
isConsumer(incomingData().consumerUID) &&
isProvider(incomingData().providerUID) &&
isUser(incomingData().consumerUID) &&
incomingData().keys().hasOnly(['archived', 'attachmentURLs', 'consumerUID', 'description', 'location', 'minPrice', 'maxPrice', 'providerUID', 'requestStateDate', 'serviceId', 'serviceType', 'state']) &&
incomingData().keys().hasAll(['archived', 'attachmentURLs', 'consumerUID', 'description', 'location', 'minPrice', 'maxPrice', 'providerUID', 'requestStateDate', 'serviceId', 'serviceType', 'state'])
}
function isConsumer(userId) {
return get(/databases/$(database)/documents/Users/$(userId)).data.role == 'Consumer';
}
function isProvider(userId) {
return get(/databases/$(database)/documents/Users/$(userId)).data.role == 'Provider';
}
Предполагается, что пользователь только долженобновлять свою собственную информацию, но в то же время, если создается запрос, тот, кто его создает (потребитель), должен иметь возможность добавить запрос в карту requests
внутри другого пользователя (поставщика).