Отсутствующие или недостаточные разрешения при записи в Firestore с использованием поля в правилах доступа

Я получаю сообщение об ошибке при попытке записи в Firestore.

Я пытаюсь использовать поле, содержащее пользовательский uid для моего правила безопасности.

service cloud.firestore {
  match /databases/{database}/documents {

    match /messages/{document=**} {
      allow read: if resource.data.user_uid == request.auth.uid;
      allow write: if resource.data.user_uid == request.auth.uid;
    }
  }
}

Если у меня есть данные в моей базе данных Firestore, правило чтения работает нормально - но когда я пытаюсь написать, я получаю: Error: Missing or insufficient permissions. Есть ли что-то, что я делаю неправильно с этим правилом записи?

P.S. Если я изменю свое правило на это, я могу написать в свою базу данных, но это недостаточно безопасно для моих целей:

 match /messages/{document=**} {
      allow read: if resource.data.user_uid == request.auth.uid;
      allow write: if request.auth != null;
    }

Ответ 1

resource.data относится к уже сохраненным данным, поэтому ваше правило позволяло пользователям обновлять только те данные, которые уже содержат их идентификатор пользователя.

Что вы, вероятно, хотите проверить, так это request.resource.data - новые поступающие данные.

Здесь довольно обширный документ об этих полях и других правилах безопасности: https://firebase.google.com/docs/firestore/security/rules-conditions

Ответ 2

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

Как и OP, я храню идентификатор пользователя (uid) вместе со своими ресурсами. Однако, когда я хочу создать новый ресурс, еще нет uid. Используя пример из документации, я получил правила безопасности, которые выглядят так:

service cloud.firestore {
  match /databases/{database}/documents {
    match /messages/{document=**} {
      allow read, update, delete: if request.auth.uid == resource.data.uid;
      allow create: if request.auth.uid != null;
    }
  }
}

Ответ 3

Вы можете сделать свою базу данных доступной только для чтения, а не для записи:

  service cloud.firestore {
    match /databases/{database}/documents {
     match /{document=**} {
       allow read: if true;
       allow write: if false;
      }
   }
}