# #firebase #google-cloud-firestore #firebase-security
Вопрос:
У меня есть поле в моем документе Firestore под названием lastApproval
, которое должно быть меткой времени, если оно имеет значение.
это мои упрощенные правила
match /users/{userID} {
allow create: if isValidUserStructure(incomingData())
allow update: if isValidUserStructure(incomingData())
}
function incomingData() {
return request.resource.data;
}
function isValidUserStructure(user) {
return user.email is string
amp;amp; user.fullname is string
amp;amp; user.lastApproval is timestamp // error in here
}
как вы можете видеть, isValidUserStructure
функция будет использоваться для проверки при создании и обновлении пользовательского документа.
при создании пользовательского документа это lastApproval
поле будет равно нулю, как это
const data = {
fullname: 'John Doe',
email: 'my@email.com',
lastApproval: null
};
await db.collection('users').doc('userIDHere').set(data);
но при обновлении документа мне нужна только метка времени.
const data = {
lastApproval: new Date()
};
await db.collection('users').doc('userIDHere').update(data);
а также я хочу передать правила безопасности, если lastApproval
они недоступны, например, если пользователь хочет обновить полное имя только так
const data = {
fullname: "My New Name"
};
await db.collection('users').doc('userIDHere').update(data);
поэтому я хочу, чтобы мои правила безопасности принимали метку времени, значение null и неопределенное значение для lastApproval
поля
Я пытался, но ошибся
пожалуйста, помогите
Комментарии:
1. Один важный момент, если у других людей была та же проблема, что и у меня : вам нужно отправить ключ поля, который вы хотите проверить (в примере вверх
lastApproval = null
), иначе правило не будет работать. Правила Firestore не поддерживаютuser.lastApproval == undefined
. Обязательно включите ключ поля, даже если он равен нулю, иначе правило не будет работать.
Ответ №1:
null
Насколько я знаю, такого типа не существует. Вы можете найти все доступные типы в документации.
Если вы хотите проверить, равно ли значение нулю, попробуйте user.lastApproval == null
вместо этого. Чтобы проверить lastApproval
, существует ли свойство в первую очередь, попробуйте это:
match /collection/{doc} {
allow write: if 'lastApproval' in request.resource.data amp;amp; (..otherLogic)
}
Таким образом, вы можете записать свою функцию как:
function isValidUserStructure(user) {
return user.email is string
amp;amp; user.fullname is string
amp;amp; (('lastApproval' in user amp;amp; user.lastApproval is timestamp) || !('lastApproval' in user))
}
Комментарии:
1. спасибо, я понял идею, ваша логика проверки наличия свойства кажется правильной, но я не знаю, почему она не проходит модульное тестирование моих правил безопасности. Я просто использую
((user.lastApproval is timestamp) || (user.lastApproval == null))
, чтобы пройти тестирование2. @Alexa289 вы должны проверить, определено ли это поле в первую очередь.
(('lastApproval' in user amp;amp; user.lastApproval is timestamp) || !('lastApproval' in user))
. Это!(lastApproval in user)
означает, что поле отсутствует, но вы все равно хотите разрешить запись, так как поле электронной почты и имя допустимы.