Правила Firestore - Проверка наличия документа - Недостаточные разрешения - PullRequest
1 голос
/ 14 октября 2019

Я хочу запросить ссылку на документ, чтобы узнать, существует ли документ в данный момент. Если его не существует, я хочу написать новый документ по этой ссылке.

К сожалению, это не работает с моими правилами безопасности. Если документ уже существует, я хочу, чтобы только уполномоченные лица могли его просматривать. Мои правила выглядят так:

Правила Firestore

function getItemData(item){
   return get(/databases/$(database)/documents/equipment/$(item)).data;
}

function getUserData(){
   return get(/databases/$(database)/documents/users/$(request.auth.uid)).data;
}

match /equipment/{item}{
   allow create: if request.auth != null;
   allow read: if !exists(/databases/$(database)/documents/equipment/$(item)) ||
               getUserData().clientId == getItemData(item).clientId;
}

Структура документа

users > userId: {
  clientId: "idhere"
}

equipment > item: {
  clientId: "idhere",
  serial: "serialnumber"
}

Мой нативный код реакции, в котором я выполняю запрос get

const docRef = firestore.collection("equipment").where('clientId', '==', clientId).where("serial", "==", serial);
docRef.get().then(doc => {
  if(!doc.exists){
    //add new item to existing document reference
  }
}).catch(error => {
  //Error here reads "Missing or insufficient persmissions"
})

Я могу читать предметы, если запрашиваю их напрямую. Однако, кажется, что мои функции where () противоречат правилам.

Кто-нибудь знает, почему это произойдет?

Редактировать: Если я изменю свое правило на это

match /equipment/{item}
   allow read: if true

Я нахожу успех, поэтому я определенно подтвердил, что именно это правило вызывает мою проблему. При использовании симулятора я могу получить доступ к документу напрямую. Похоже, что где утверждения являются проблемой

Ответы [ 2 ]

1 голос
/ 14 октября 2019

Похоже, вы ожидаете, что правило проверит для каждого документа в наборе результатов, если содержимое других документов предполагает, что оно должно быть читаемым. Запрос не выполняется, поскольку правила безопасности не являются фильтрами . Пожалуйста, не забудьте понять документацию здесь. Вы не можете написать правила, которые удаляют документы из запрошенного результирующего набора - запрос должен быть «все или ничего».

Правило работает для запросов get () документа, потому что запрошенный документ известен заранее - {item} имеет конкретное значение. Но в случае запроса правила не могут проверять каждый возможный документ по отдельности. Вам нужно будет найти другой способ выразить свое намерение.

0 голосов
/ 14 октября 2019

Если вы не хотите, чтобы пользователь мог читать существующий документ, вы не должны давать ему разрешение read. А это значит, что они также не смогут обнаружить существование документа, пытаясь прочитать его.

Но вы, вероятно, все еще можете достичь своего варианта использования, только разрешив пользователю create разрешение, если документеще не существует:

allow create: if request.auth != null && !exists(resource['__name__']) 

Теперь клиент может просто попытаться создать документ. Если это не помогло, вы знаете, что документ уже существует (или не соблюдены другие правила безопасности).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...