Firestore: как установить безопасность для типов объектов с пользователями в качестве имен полей - PullRequest
0 голосов
/ 26 июня 2018

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

database
  users
    {userId}
        friends
           userId1: true
           userId2: true

Имена полей 'userId1' и 'userId2' будут различаться в зависимости от userId человека, указанного в списке друзей.

Вопрос в том,Как мне написать правило безопасности, чтобы я мог найти свои документы (через мой {userId}) и документы других пользователей, где my {userId} - это поле в объекте 'friends' документа другого пользователя?

Я думаю, это должно быть что-то вроде ..

  match /users/{userId} {
      allow read, update, delete: if resource.data.userId == request.auth.uid;
      allow read: if resource.data.friends.{userId} == true;
    }   

Но, конечно, это не работает, потому что вы не можете использовать переменную {userId} для именования поля, которое вы хотите выполнить тестна.Итак, если это невозможно, как можно найти документы и как-то сохранить мой {userId} в чужом документе?


Редактировать


Хорошо,Я думаю, что у меня определены правила (см. Ниже).Однако при попытке проверить эти правила я не могу написать вызов Swift для извлечения данных на основе этого объекта друзей.Мой звонок в Swift:

db.collection("users").whereField(FieldPath(["friends.\(userId)"]), isEqualTo: true)

Итак, мои вопросы:

  1. Правильны ли приведенные ниже правила?
  2. Как сделать Swiftпозвонить, чтобы найти людей с определенным идентификатором пользователя в имени поля типа объекта?

    service cloud.firestore {match / database / {database} / documents {match / users / {documentId} {allow read,write: if isOwner ();
    разрешить чтение: if getFriend (request.auth.uid) == true;

            function isOwner() {
                return request.auth.uid == resource.auth.uid;
            }
    
            function getFriend(userId) {
                return getUserData().friends[userId]
            }
    
            function getUserData() {
                return get(/databases/$(database)/documents/rooms/{documentId}).data
            }
        } 
    }
    

    }

1 Ответ

0 голосов
/ 28 июня 2018

Я до сих пор не решил проблему доступа к полям в объекте, но отмечается, что мои Правила безопасности там, как правило, недействительны.Вы не можете иметь несколько строк с одним и тем же типом правила, вы не можете иметь несколько строк, например, с «allow: read».Вы должны использовать && и ||.Например, правильное определение основных правил, если вы хотите проверить две вещи:

// Database rules
service cloud.firestore {
    // Any Cloud Firestore database in the project.
    match /databases/{database}/documents {
        // Handle users
        match /users/{documentId} {
            // The owner can do anything, you can access public data
            allow read: if (isOwner() && isEmailVerified()) || isPublic();
            allow write: if isOwner() && isEmailVerified();

            // Functions //
            function isSignedIn() {
                return request.auth != null;
            }

            function isOwner() {
                return request.auth.uid == resource.data.userId;
            }

            function isPublic() {
                return resource.data.userId == "public";
            }

            function isEmailVerified() {
                return request.auth.token.email_verified
            }      
        } 
    }
}
...