Правила соответствия Firestore для поиска данных в документе, который находится в другой коллекции - PullRequest
0 голосов
/ 19 мая 2019

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

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

У меня есть 3 коллекции, пользователи, разрешения и домашняя работа вместе с некоторыми примерами данных.

пользователи

{
    id:  fK3ddutEpD2qQqRMXNW,
    name: "Steven Smith"
},

{
    id:  YI2Fx656kkkk25,
    name: "Becky Kinsley"
},

{
    id:  CAFDSDFR244bb,
    name: "Tonya Benz"
}

разрешения

{
    id:  fK3ddutEpD2qQqRMXNW,
    followers: [YI2Fx656kkkk25,CAFDSDFR244bb]  
}

домашняя работа

{
    id:  adfsajkfsk4444,
    owner:  fK3ddutEpD2qQqRMXNW,
    name: "Math Homework",
    isDone: false
}

Начало правил моего пожарного магазина:

 service cloud.firestore {

//lock down the entire firestore then open rules up.
  match /databases/{database}/documents {

    match /{document=**} {
      allow read, write: if false;
    }

match /homework/{      } {
      allow get: if isSignedIn()

    }

// helper functions
    function isSignedIn() {
      return request.auth != null;
    }

    function isUser(userId) {
      return request.auth.uid == userId;
    }

    function isOwner(userId) {
        return request.auth.uid == resource.data.uid;
    }

  }
}

Вариант использования:

Стивен Смит поделился своим списком домашних заданий с Тоней Бенц,

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

var homeworkRef = db.collection("homework");
var query = homeworkRef.where("owner", "==", "fK3ddutEpD2qQqRMXNW");

Вопрос:
Какое правильное правило соответствия Firestore берет поле «владелец» из коллекции домашних заданий, чтобы найти его в качестве идентификатора в коллекции разрешенийкогда пользователь Tonya Benz вошел в систему, чтобы этот запрос мог выполняться.

1 Ответ

1 голос
/ 19 мая 2019

С вашим текущим запросом и структурой базы данных вы не сможете достичь своей цели с помощью правил безопасности.

Во-первых, похоже, что вы ожидаете, что сможете фильтровать результаты запросана основе содержимого другого документа.Правила безопасности не могут действовать как фильтры запросов. Все документам, которым соответствует запрос, должен быть предоставлен доступ для чтения по правилам безопасности, либо весь запрос отклоняется.Вам нужно будет задать запрос, в котором конкретно указано, к каким документам должен быть разрешен доступ.К сожалению, нет единого запроса, который мог бы сделать это с вашей текущей структурой, потому что это потребовало бы своего рода «соединения» между разрешениями и домашней работой.Но Firestore (как и все базы данных NoSQL) не поддерживает объединения.

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

Вы можете сохранить список пользователей, которые должны были прочитать, иметь доступ к определенному документу в домашней работе, в том же документе, представленном в виде поля списка.В запросе может быть указан фильтр, основанный на присутствии uid пользователя в этом поле списка.И в правиле может быть указано, что доступ на чтение предоставляется только пользователям, чьи идентификаторы присутствуют в этом списке.

{
    id:  adfsajkfsk4444,
    owner:  fK3ddutEpD2qQqRMXNW,
    name: "Math Homework",
    isDone: false,
    readers: [ 'list', 'of', 'userids' ]  // filter against this list field
}

Суть в том, что вам нужно будет выполнить эти два требования:

  1. Ваш запрос должен быть конкретным, примерно точно , который указывает, что он ожидает быть читаемым.Вы не можете использовать правило для фильтрации результатов.
  2. Ваше правило нуждается в способе определения, не использующем ничего более сложного, чем поля самого документа или get() в других известных документах.доступ должен быть для текущего uid.
...