Различие правил безопасности Firebase между get () и getAfter () - PullRequest
1 голос
/ 24 марта 2019

В документе написано:

Используя функции get () и exist (), ваши правила безопасности могут оценивать входящие запросы к другим документам в базе данных.

Это хорошо для меня, и пример имеет смысл для меня:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      // Make sure a 'users' document exists for the requesting user before allowing any writes to the 'cities' collection
      allow create: if exists(/databases/$(database)/documents/users/$(request.auth.uid))

      // Allow the user to delete cities if their user document has the
      // 'admin' field set to 'true'
      allow delete: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true
    }
  }
}

, но затем он говорит

Для записи вы можете использовать getAfter ()функция для доступа к состоянию документа после завершения транзакции или пакета записей, но до фиксации транзакции или пакета.

Возможно, я все еще не до конца понимаю концепцию.Мои вопросы:

  1. Почему для транзакции или пакетной записи специально нужно использовать getAfter (), можем ли мы просто использовать get ()?
  2. Если вам нужно использовать getAfter() для транзакции или пакетной записи, означает ли это, что вам все еще нужен метод get () для обычной записи?как они существуют одновременно?

Спасибо.

1 Ответ

2 голосов
/ 24 марта 2019

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

В цитируемой вами документации предполагается, что getAfter полезен для проверки содержимого базы данных после того, как будет записано состояние всей транзакции (в некой «промежуточной» среде в памяти), но до того, как транзакция фактически изменит базу данных , видимую всем. Это отличается от get, поскольку get просматривает только фактическое содержимое базы данных, до окончательного подтверждения транзакции . Короче говоря, getAfter использует всю поэтапную запись всей транзакции или пакета, тогда как get использует фактическое существующее содержимое базы данных.

Вы ни в коем случае не обязаны использовать getAfter, если get отлично подходит для вашего случая.

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

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

...