правило firestore для проверки нескольких созданий в пакете - PullRequest
0 голосов
/ 15 января 2020

Я пишу приложение, в котором пользователи могут оставлять комментарии в темах. Поскольку для этого я использую бэкэнд No SQL в Firestore, я храню каждый комментарий в двух местах:

/threads/THREADID/comments/COMMENTID
/users/USERID/comments/COMMENTID

Таким образом, у меня есть обзор всех комментариев в теме, но также и всех комментарии, оставленные пользователем. Чтобы оба этих комментария всегда создавались, я использую пакетную запись. Пакетные записи - это atomi c, так что это никогда не должно вызывать проблем, но меня беспокоит то, что злонамеренный пользователь может использовать собственный код для создания комментария только в одном месте, а не в обоих. Мне нужно найти правило, которое подтверждает, что либо оба комментария созданы, либо ни один из них не должен.

  match /users/{userId}/comments/{commentId} {  
    allow create: if exists(/databases/$(database)/documents/threads/$(request.resource.data.threadId)/comments/$(commentId)
  }

  match /threads/{threadId}/comments/{commentId} {  
    allow create: if exists(/databases/$(database)/documents/users/$(request.auth.uid)/comments/$(commentId)
  }

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

Спасибо!

1 Ответ

0 голосов
/ 15 января 2020

РЕДАКТИРОВАТЬ:

Облачная функция была бы гораздо более подходящей для решения этой проблемы. С помощью триггера onCreate этот документ может быть автоматически создан / users после создания в / threads. При этом мое старое решение без облачных функций приведено ниже:

Решение без облачных функций:

Не существует эквивалента getAfter () () функция, которая существует для проверки данных после пакета или транзакции). Итак, как я это сделал, по следующим правилам:

  match /users/{userId}/comments/{commentId} {  
    allow create: if getAfter(/databases/$(database)/documents/threads/$(request.resource.data.threadId)/comments/$(commentId)).data.author == userId;
  }

  match /threads/{threadId}/comments/{commentId} {  
    allow create: if getAfter(/databases/$(database)/documents/users/$(request.auth.uid)/comments/$(commentId)).data.createdAt == request.time;
  }

Функции getAfter () проверят правильность после обратной записи и получат проверку значения поля. Поскольку мне нужно только проверить, существуют ли они, значение поля на самом деле не имеет значения.

...