Правило безопасности Firestore, не позволяющее двум идентификаторам получать доступ к документу

#javascript #google-cloud-firestore #firebase-security

#javascript #google-облако-firestore #firebase-безопасность

Вопрос:

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


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

Вот как выглядят правила :

 match /orders/{orderId} {
  allow read:   if request.auth.uid == resource.data.cust.uid ||
                   request.auth.uid == resource.data.shop.ownerUid;
  allow write:  if < Some Condition >;
}
  

Теперь при получении заказов для клиента я запрашиваю вот так, и все работает нормально. Правила безопасности пропускают его.

 let query = dbFirestore.collection('orders')
    .where("cust.uid", "==", firebase.auth().currentUser.uid)
    .orderBy('statusHistory.New', 'desc')
    .startAfter(lastVisible)
    .limit(5);

query.get();
  

Однако, когда я запрашиваю магазин (как показано ниже), я получаю ошибку «отказано в разрешении» (по правилам безопасности)

 let query = dbFirestore.collection('orders')
    .where("shop.ownerUid", "==", firebase.auth().currentUser.uid)
    .orderBy('statusHistory.New', 'desc')
    .startAfter(lastVisible)
    .limit(5);

query.get();
  

Оба запроса похожи, но один проходит, а другой завершается неудачей!!!

Еще один факт, который я хочу упомянуть, заключается в том, что клиент тоже может владеть магазином, поэтому ниже приведен один из возможных случаев :
request.auth.uid = shop.ownerUid = cust.uid = firebase.auth().currentUser.uid

У меня такое чувство, что это может иметь какое-то отношение к ошибке правил, но я не пришел ни к какому выводу.


Я также пытался добавить shopId в запрос и правила, но это все еще не удается.

 let query = dbFirestore.collection('orders')
    .where("shop.ownerUid", "==", firebase.auth().currentUser.uid)
    .where("shop.shopId", "==", shopId_of_this_shop)      // <---- This
    .orderBy('statusHistory.New', 'desc')
    .startAfter(lastVisible)
    .limit(5);
  

Правила :

 match /orders/{orderId} {
  allow read:   if request.auth.uid == resource.data.cust.uid ||
                   (request.auth.uid == resource.data.shop.ownerUid amp;amp;
                    request.resource.data.shop.shopId == resource.data.shop.shopId);
}
  

Для справки, ниже приведены данные из order документа :

введите описание изображения здесь

введите описание изображения здесь

Я ценю любую помощь в этом.

Ответ №1:

Это было связано с тем, что индекс не существовал.

Я не сгенерировал индекс для «shop.ownerUid», и поскольку запрос завершался ошибкой с «Ошибкой разрешения», а не «Требуется индекс». Я продолжал фокусироваться на правилах безопасности.

Запрос на «cust.uid» проходил, потому что у него был индекс.

Как только я понял и сгенерировал индекс в «shop.ownerUid» и поле статуса запроса, это сработало.