#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» и поле статуса запроса, это сработало.