Firebase Realtime Database Security, только чтение сообщений за последние 10 минут с использованием временной метки не работает - PullRequest
1 голос
/ 27 апреля 2020

Я видел несколько постов и документации по достижению этого, но не могу заставить его работать.

Я сохраняю метку времени для каждого сообщения чата с firebase.database.ServerValue.TIMESTAMP.

Если я добавлю правило безопасности, найденное в документации firebase (вставлено ниже), оно вообще не вернет никаких сообщений. Всякий раз, когда я удаляю фрагмент, проверяющий отметку времени, все сообщения возвращаются, как и ожидалось.

".read": "data.child('timestamp').val() > (now - 600000)",

Вот мои правила безопасности для всех моих документов (см. .read в chat/ для Speci c Правило, я задаюсь вопросом)

  "rules": {
    "online": {
      "$uid": {
        ".read": "auth != null && auth.token.email_verified == true",
        ".write": "$uid === auth.uid && auth.token.email_verified == true"
      }
    },
    "chat": {
      ".indexOn": ["timestamp"],
      // signed in and message was sent in last 10 min
      ".read": "auth != null && auth.token.email_verified == true && data.child('timestamp').val() > (now - 600000)",
      // signed in, your user id, and authed thru ig
      ".write": "auth != null && auth.token.email_verified == true && root.child('users').child(auth.uid).child('iga').val() == true",
      "$uid": {
        ".validate": "newData.hasChildren(['username', 'timestamp', 'text', 'user_id'])",
        "timestamp": { 
          ".validate": "newData.val() <= now"
        },
        "text": { 
          ".validate": "newData.isString() && newData.val().length > 0 && newData.val().length <= 280"
        },
        "user_id": {
          ".validate": "newData.val() === auth.uid"
        }
      }
    },
    "users": {
        "$uid": {
        // only read your user
        ".read": "$uid === auth.uid && auth.token.email_verified == true",
        // only admin can write
        ".write": "false",
        ".validate": "newData.hasChildren(['iga'])",
      }
    },
    "video_src": {
      ".read": "auth != null",
      ".write": "auth.uid === 'Fcbp0p6Gd3Q5baljAV0rGWBqSR22'"
    },
    "captions": {
      ".read": "auth != null",
      ".write": "auth.uid === '2HgVzfosZqgK0LINUeYWKF1Bxyi2'",
      "$uid":{
        ".validate": "newData.isString() && newData.val().length > 0 && newData.val().length <= 140"
      }
    }
  }
}

Вот как я запрашиваю данные чата:

   const timestamp = new Date().getTime()
   return this.chatRef
      .orderByChild('timestamp')
      .startAt(timestamp)
      .on('child_added', 
        snapshot => callback(this.parseMessage(snapshot))
      )

Может кто-нибудь увидеть, где я иду не так здесь ?

Спасибо!

1 Ответ

0 голосов
/ 27 апреля 2020

Из документации Firebase :

Правила не являются фильтрами

Правила применяются в виде атома c. Это означает, что операция чтения или записи немедленно завершается неудачей, если в этом месте или в родительском месте нет правила, предоставляющего доступ. Даже если каждый затронутый дочерний путь доступен, чтение в родительском местоположении полностью завершится неудачей.

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

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

Облачные правила безопасности Firestore оценивают каждый запрос на предмет его потенциального результата и отклоняют запрос, если он может вернуть документ, на который у клиента нет разрешения. читать. Запросы должны соответствовать ограничениям, установленным вашими правилами безопасности.

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

...