Как избежать ограничения глубины вызовов функций? - PullRequest
0 голосов
/ 03 января 2019

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

Что считается функцией?Просто мой собственный созданный или тоже что-то вроде size()?

  function isValidItem(data, item) {
    return 
        ( // Person
          data.items[item].keys().hasAll(['image','type','name','job','age','party','experience'])
          && data.items[item].image.size() >= 1 && data.items[item].image.size() <= 200
          && data.items[item].type.size() >= 5 && data.items[item].type.size() <= 10
          && data.items[item].name.size() >= 1 && data.items[item].name.size() <= 50
          && data.items[item].job.size() >= 1 && data.items[item].job.size() <= 50
          && data.items[item].party.size() >= 1 && data.items[item].party.size() <= 50
          && data.items[item].experience.size() >= 1 && data.items[item].experience.size() <= 50
          && data.items[item].age.matches('^[0-9]+$')
        )
        || 
        ( // Party
            data.items[item].keys().hasAll(['image','type','name','orientation','experience','promi'])
          && data.items[item].image.size() >= 1 && data.items[item].image.size() <= 200
          && data.items[item].type.size() >= 5 && data.items[item].type.size() <= 10
          && data.items[item].name.size() >= 1 && data.items[item].name.size() <= 50
          && data.items[item].orientation.size() >= 1 && data.items[item].orientation.size() <= 50
          && data.items[item].experience.size() >= 1 && data.items[item].experience.size() <= 50
          && data.items[item].promi.size() >= 1 && data.items[item].promi.size() <= 50
        );
  }

  function itemsAreValid(data) {
    return data.items.size() >= 1
        && data.items.size() <= 10
        && isValidItem(data, 0)
        && (data.items.size() < 2 || isValidItem(data, 1))
        && (data.items.size() < 3 || isValidItem(data, 2))
        && (data.items.size() < 4 || isValidItem(data, 3))
        && (data.items.size() < 5 || isValidItem(data, 4))
        && (data.items.size() < 6 || isValidItem(data, 5))
        && (data.items.size() < 7 || isValidItem(data, 6))
        && (data.items.size() < 8 || isValidItem(data, 7))
        && (data.items.size() < 9 || isValidItem(data, 8))
        && (data.items.size() < 10 || isValidItem(data, 9));
  }

  function isValidTitle(data) {
    return data.title.size() >= 1 
        && data.title.size() <= 200
  }

  function isAuthed() {
    return request.auth.uid != null
        && request.auth.token.email_verified == true;
  }

  allow create, update:
    if isAuthed()
    && request.resource.data.user == request.auth.uid
    && request.resource.data.status == "review"
    && isValidTitle(request.resource.data)
    && itemsAreValid(request.resource.data);

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Я проверил это с командой правил безопасности Firebase, и мы обнаружили, что предел, который вы здесь превышаете, почти наверняка равен общему количеству допустимых выражений. Сейчас задокументировано, что это 10000, но это число на самом деле неверно. Это должно быть задокументировано как 1000. Вот почему, когда вы немного урезали правила, он смог начать работать. В этот момент вы, вероятно, попали под лимит в 1000.

Что вы можете сделать, чтобы улучшить вашу ситуацию, так это прекратить многократно вызывать функции. Например, вместо isValidItem(map, key) и повторного вызова map[key] вы можете просто написать isValidItem(value)

К сожалению, в настоящее время нет журнала или отладки для правил безопасности, поэтому вам придется иногда делать предположения, когда что-то идет не так.

Мы собираемся исправить документацию, а также обсудим более подробно.

0 голосов
/ 03 января 2019

Данные вызова () -> ссылка на документ каждый раз.

Ограничение доступа к документу, в этом вызове data () является проблемой. Вы ссылаетесь на документ, вызывая данные много раз. Чтобы избежать этого, вы можете передать data () в функцию и проверить все внутри нее.

Access call limits
There is a limit on document access calls per rule set evaluation:

10 for single-document requests and query requests.
20 for multi-document reads, transactions, and batched writes. The previous limit of 10 also applies to each operation.

For example, imagine you create a batched write request with 3 write operations and that your security rules use 2 document access calls to validate each write. In this case, each write uses 2 of its 10 access calls and the batched write request uses 6 of its 20 access calls.

Exceeding either limit results in a permission denied error. Some document access calls may be cached, and cached calls do not count towards the limits

https://firebase.google.com/docs/firestore/security/rules-conditions

...