updateChildValue записывает данные

Имея следующую проблему:

Я денормализовал свою структуру данных в своей базе данных Firebase в реальном времени. Вследствие этого мне нужно обновить имя пользователя во всех других "постах" (в данном случае рецептах), а также в рецептах с разными авторами. Для этого каждый раз, когда пользователь создает комментарий к рецепту, этот пользователь также создает ссылку на этот рецепт в своем пользовательском объекте.

Теперь, когда вы меняете свое имя пользователя, он читает все эти ссылки и изменяет имя пользователя на этом пути, как показано ниже (Swift):

ref.child("users/profile").child(uid ?? "ERROR").child("comments/DE").observeSingleEvent(of: .value, with: { (recipes) in
   // recipe dict is a dictionary of all the references to recipes a user has commented
   let recipeDict = recipes.value as! [String:Any]
   // now every reference is being used to change the username at given place to the new username with variable "username"
   var updateObjects: [String:String] = [:]
   for i in recipeDict.keys {
      updateObjects["recipes/DE/\(i)/comments/\(uid ?? "ERROR")/username"] = username
   }
   // Now the changes stored in the "updateObjects" variable will be applied
   ref.updateChildValues(updateObjects)
})

Теперь это работает, но проблема с этим подходом заключается в том, что, скажем, рецепт удаляется, ссылка не удаляется (это было бы сложно, поскольку правила безопасности не позволяют обновлять профиль другого пользователя, поэтому, следовательно, не их ссылки). Так что для меня это не имеет большого значения, но поскольку функция updateChildValues ​​создает недостающие объекты, она и есть. Что в итоге происходит, так это то, что на месте, где будет удаленный рецепт, создается "новая" пустая структура рецепта без каких-либо других узлов, кроме комментария. Это приводит к сбою моего приложения, и я не хочу этого. Как мне этого не допустить?

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

1 ответ

Вы можете написать правила безопасности, чтобы отклонить операцию записи в несуществующий комментарий, если запись - это просто имя пользователя. Например, предположим, что еще одним свойством каждого комментария являетсяtext, вы могли бы сделать:

"comments": {
  "$commentid": {
    "$uid": {
      "username": {
        ".write": "data.parent.parent.child('text').exists()"
      }
    }
  }
}     

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

Другие вопросы по тегам