Firebase: проверка выхода значения Child (automati c ID) - PullRequest
1 голос
/ 14 марта 2020

У меня есть небольшая БД Firebase, мне нужно проверить, выходит ли значение узла

Я добавляю дочерний элемент с

childByAutoId()

, поэтому моя БД выглядит так

(randomID - это случайное число, сгенерированное из firebase)

numbers:
---"randomID": "stringSavedFromMyCode"
---"randinID": "stringSavedFromMyCode"

Знаете ли вы, как я могу сделать это простым способом, чтобы проверить это?

Если "stringSavedFromMyCode" (строка с указанием кода Swift) равно значению, присутствующему в БД, его нельзя устанавливать на .setValue в Firebase

Не знаю, хорошо ли я объяснил

Спасибо

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

до того, как я привык

ref.child("numbers").childByAutoId().setValue(stringSavedFromMyCode)

1 Ответ

1 голос
/ 14 марта 2020

Если я правильно понимаю, вы хотите записать значение в базу данных, если оно еще не существует.


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

  1. запустите запрос для значения со значением, подобным ref.child("numbers").queryOrderedByValue().queryEqualToValue("stringSavedFromMyCode")queryLimited(toFirst: 1)
  2. Проверьте, есть ли в запросе результаты
  3. Если нет, запишите новый узел со значением.

Это может работать большую часть времени, но имеет неотъемлемое состояние гонки между этапами 1 и 3. Удалить. В этом состоянии гонки вам нужно использовать транзакцию , которая, к сожалению, должна будет выполняться на всем узле numbers в вашей текущей структуре данных.


Лучшее решение - изменить вашу структуру данных.

Если вы хотите, чтобы что-то было уникальным в определенной области действия в Firebase, вы должны использовать это в качестве ключа узлов в этих областях. Поэтому, если вы хотите сохранить уникальные номера, используйте фактические номера в качестве ключей в numbers:

numbers:
---"stringSavedFromMyCode": true
---"string2SavedFromMyCode": true

Учитывая, что Firebase хранит данные как JSON, приведенная выше структура гарантирует, что каждый stringSavedFromMyCode может произойти только один раз под numbers. Дубликаты невозможны на уровне структуры данных.

Таким образом, последняя строка вашего вопроса будет примерно переведена в:

ref.child("numbers").child(stringSavedFromMyCode).setValue(true)

Но чтобы гарантировать, что вы пишете только тогда, когда его не существует, вам все равно нужно будет использовать транзакцию:

  1. Выполнить транзакцию на ref.child("numbers").child("stringSavedFromMyCode").
  2. Если currentData.value равно nil.
  3. Если оно то есть, установите новое значение на currentData.

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

{
  "rules": {
    "numbers": {
      "$number": {
        ".write": "!data.exists()"
      }
    }
  }
}

Эти правила в основном говорят: «Вы можете написать узел под номером, если он еще не существует». Но я определенно рекомендую прочитать полную документацию по правилам безопасности , поскольку они являются ключевым компонентом моделирования и защиты данных в Firebase.


См. Также:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...