Firebase Firestore: пользовательский доступ администратора

в Firebase Firestore я пытаюсь разрешить только (назначенным пользователем) администраторам писать/обновлять / удалять ресурсы, и для этого у меня есть следующие правила безопасности:

service cloud.firestore {
  match /databases/{database}/documents {
    match /resources {
      allow read;
      allow write, update, delete: if get(/users/$(request.auth.uid).isAdmin);
    }
    match /resources/{resource} {
      allow read;
      allow write, update, delete: if get(/users/$(request.auth.uid).isAdmin);
    }
  }
}

Я вхожу в систему с пользователем, который отмечен как администратор в пользователи коллекция:

users collection has a single admin

NfwIQAjfNdS85yDvd5yPVDyMTUj2 является UID, полученным из панели аутентификации:

The user exists

однако по какой-то причине (обновление: причины определены; см. ответ), я получаю PERMISSION_DENIED ошибки при записи ресурсы коллекция после того, как я абсолютно уверен, что вошел в систему с пользователем admin.

возможно, можно просмотреть журналы запросов из Firestore? Тогда я мог бы посмотреть на что!--1--> похоже, что это соответствует моим коллекциям и правилам.

2 ответов


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

во-первых все вызовы сервис-функция, определяемая get необходимо префикс пути с / базы данных / $(база данных) / документы/. Так что это правило:

allow write: if get(/users/$(request.auth.uid)).isAdmin;

становится этот:

allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).isAdmin;

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

второй, the


некоторые моменты я заметил

match /resources указывает на коллекцию, правила которой не влияют на ее документы. здесь я цитирую из doc

правила для коллекций не применяются к документам в этой коллекции. Необычно (и, вероятно, ошибка) иметь правило безопасности, которое записывается на уровне коллекции, а не на уровне документа.

поэтому вам не нужно писать правила для сборники

тогда в правилах allow write, update, delete: вы можете сказать allow write: и в частности allow create, update, delete: любой из трех вариантов или комбинировать их.

попробуй такое

service cloud.firestore {
    match /databases/{database}/documents {
      match /resources/{resource} {

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

        allow read;
        allow create, update, delete: if isAdmin();
    }
  }
}