Правила Firebase - Как проверить, существует ли пользователь в поддокументе - PullRequest
0 голосов
/ 26 февраля 2019

Я работаю над форумоподобной структурой с использованием Firebase Store / Firebase Rules.Моя структура примерно такая:

Collection --- Document ------ Collection --- Document
Topic1         CreationDate    UsersJoined    UserUID1
Topic2         Title                          UserUID2
Topic3         UpdatedDate                    UserUID3
...            ...                            ...

По сути, каждая тема имеет коллекцию пользователей.Моя цель - написать правило безопасности, в котором только пользователи из «UsersJoined» могут читать / писать в соответствующую тему.Вот то, что я сейчас имею в качестве своих правил:

service cloud.firestore {
  match /databases/{database}/documents {
    match /Topics/{topicUID} { 
      allow read, create, update, delete: if exists(/databases/$(database)/documents/Topics/$(topicUID)/UsersJoined/$(request.auth.uid));

      match /UsersJoined/{userUID=**} {
        allow read, create, update, delete;
      }
    }
  }
}

Так что, когда я использую встроенный симулятор, чтение работает просто отлично;однако, когда я запрашиваю прочитать его через мой код для IOS, он говорит, что у меня нет достаточного разрешения.

Я пытался просто сделать allow read: if request.auth.uid != null;, и я могу читать.Я уверен, что UserUID существует в коллекции UsersJoined.

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

Collection ----------- Document
MyTestUserCollection   UserUID1
Topic1                 UserUID2 
Topic2                 ...
...

Затем я использовал это правило: if exists(/databases/$(database)/documents/MyTestUserCollection/$(request.auth.uid));и чтение работает, как на симуляторе, так и на кодах IOS.

Моя проблема не в том, что я не могу прочитать, когда список пользователей вложен в тему.Поэтому мой вопрос заключается в том, что, ... написав правило, которое проверяет («читает») данные во вложенной коллекции, нарушаю ли я правило «разрешить чтение» (поскольку технически оно еще не определило, могу ли я читать)?Или я немного усложняю вещи, и есть лучший способ структурировать мои коллекции / документы?Или я просто не правильно пишу правило?

Я не верю, что мой код на IOS является проблемой, но на всякий случай это то, что я делаю, чтобы запросить чтение из моей базы данных: (пользователь вошел в систему через Firebase Auth)

[[myFirestore collectionWithPath:@"Topics"]
 getDocumentsWithCompletion:^(FIRQuerySnapshot *snapshot, NSError *error) {
     if (error != nil) {
         NSLog(@"Error getting documents: %@", error);
     } else {
         NSLog(@"Read it");
     }
 }];

Любая помощь с благодарностью!

1 Ответ

0 голосов
/ 26 февраля 2019

Ваши правила безопасности позволяют пользователю читать определенную тему, если они следуют этой теме.Ваш код пытается прочитать все темы, которые не разрешены вашими правилами.Это объясняет, почему сервер отклоняет операцию чтения.

Это легче всего запомнить, осознав, что сами правила не фильтруют данные.Вместо этого они либо позволяют слушателю, либо нет.А так как ваши правила не разрешают слушателю все /Topics, этот слушатель отклоняется.

Одним из решений является только чтение определенной темы, последователем которой вы являетесь.Чтобы определить темы, вам может потребоваться сохранить документ со списком тем пользователя, например, в коллекции /Profiles.Это довольно часто встречается в базах данных NoSQL: вы, по сути, храните обе стороны отношения «многие ко многим».

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

...