Правила безопасности Firebase Firestore Переменная не используется - PullRequest
0 голосов
/ 18 февраля 2019

При написании правил для Firestore кажется, что пользовательские переменные не работают.Кто-нибудь знал почему или видел подобное поведение?Используя ниже, я получил отказ в доступе, хотя UID находится в массиве администратора.

service cloud.firestore {
      match /databases/{database}/documents {
        match /conferences/{confid} {
          allow read,write: if request.auth.uid in get(/databases/$(database)/documents/conferences/$(confid)).data.admin;
        }
      }
    }

Имитатор выдает следующую ошибку:

Вызвана функция [get] с путем к несуществующему ресурсу: / database /% 28default% 29 / Documents / conference /% 7Bconfid% 7D

Также проверяя это на реальных устройствах, я получил отказ в доступе.

Если, однако, я использую идентификатор документа, как показано ниже, он работает, и доступ предоставляется.

service cloud.firestore {
  match /databases/{database}/documents {
    match /conferences/{confid} {
      allow read,write: if request.auth.uid in get(/databases/$(database)/documents/conferences/ySWLb8NSTj9sur6n2CbS).data.admin;
    }
  }
}

Очевидно, я не могу жестко закодировать это для каждого идентификатора.

ОБНОВЛЕНИЕ

Помимо регистрации случая с поддержкой, я провел дополнительное тестирование.На изображении ниже симулятор теперь предоставляет доступ.

service cloud.firestore {
  match /databases/{database}/documents {
    match /conferences/{confID}{
      allow read, write: if request.auth.uid in get(/databases/$(database)/documents/conferences/$(confID)/permissions/permission).data.users;
        }
  }
}

Simulator

Для справки я использую ниже, чтобы запросить из моего веб-приложения:

db.collection("conferences")
  .get()
  .then(query => {
    console.log("SUCCESS!!!")
    query.forEach(function(doc) {
      // doc.data() is never undefined for query doc snapshots
      console.log(doc.id, " => ", doc.data());
    });
  }).catch((e) => {
    console.log(e)
  })

Это журнал из браузера:

FirebaseError: отсутствует или недостаточно разрешений.в новом FirestoreError (webpack-internal: ///./node_modules/@firebase/firestore/dist/index.cjs.js: 352: 28) в JsonProtoSerializer.fromRpcStatus (webpack-internal: ///./node_modules/@firebase/firestore/dist/index.cjs.js:5649:16) в JsonProtoSerializer.fromWatchChange (webpack-internal: ///./node_modules/@firebase/firestore/dist/index.cjs.js: 6146: 44) в PersistentListenStream.onMessage (webpack-internal: ///./node_modules/@firebase/firestore/dist/index.cjs.js: 14350: 43) в eval (webpack-internal: ///./node_modules/@firebase/firestore/dist / index.cjs.js: 14279: 30) в eval (webpack-internal: ///./node_modules/@firebase/firestore/dist/index.cjs.js: 14319: 28) в eval (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:7411:20)

Я использую последний пакет Firebase 5.8.3.

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

service cloud.firestore {
  match /databases/{database}/documents {
    match /conferences/{confID}{
      allow read, write: if request.auth.uid != null
        }
  }
}

Это даже смущает меня больше.Это потому, что правило более сложное и требуется слишком много времени, чтобы проверить его и вернуть отказано в доступе?

Update-2

Быстро протестировали это на мобильном телефонеприложение через флаттер.Тот же результат.Доступ запрещен с этим набором правил.

service cloud.firestore {
  match /databases/{database}/documents {
    match /conferences/{confID}{
      allow read, write: if request.auth.uid in get(/databases/$(database)/documents/conferences/$(confID)/permissions/permission).data.users;
        }
  }
}

Firestore

Ответы [ 2 ]

0 голосов
/ 30 июня 2019

Одним из решений было бы поместить пользователей с разрешениями в массив в документе конференции, поэтому request.resource.data.permissions

Итак, вместо этого:

get(/databases/$(database)/documents/conferences/$(confID)/permissions/permission).data.users

используйте это:

request.resource.data.permissions

Это не решило бы проблему get(), но исключило бы необходимость вызова get(), который мог бы сэкономить вам 15% или более на вашей квоте.

0 голосов
/ 28 февраля 2019

Я думаю, что моя проблема в том, что запрос не соответствует правилам безопасности.Если вам нужен только один конкретный документ, он будет работать, но если вы запросите несколько документов в коллекции, вы заблокированы правилами безопасности.У меня было два варианта.Перестройте мои данные так, чтобы в одном документе содержались все необходимые мне данные, или измените правила безопасности, чтобы соответствовать запросам.В конце я прикрепил к каждому документу идентификатор, такой как UID, чтобы убедиться, что запрос соответствует правилам безопасности.

...