Удаление Firebase Observer не работает

Я загружаю некоторые данные, чтобы показать их в tableView. Я пытаюсь удалить наблюдателя для этого. Прямо сейчас наблюдатель показывает дублированный контент. Он показывает пост 10-15 раз.

Вот как я наблюдаю:

   func loadData(){
        let placeIdFromSearch = ViewController.placeidUebertragen
        ref = Database.database().reference().child("placeID/\(placeIdFromSearch)/\(ViewComments.subComment)/subcomment/")
        
        ref.observe(.childAdded) { (snapshot) in
            
            print("something changed")
            guard let dic = snapshot.value as? [String: Any] else { return }
            let newPost = importSubPosts(dictionary: dic, key: snapshot.key)
            guard let userUid = newPost.userID else { return }
            self.fetchUser(uid: userUid, completed: {
                self.table.insert(newPost, at: 0)
                self.tableView.reloadData()
            })
        }

    }

    func fetchUser(uid: String, completed: @escaping () -> Void) {
        ref = Database.database().reference().child("user").child(uid)
        ref.observe(.value) { (snapshot) in
            guard let dic = snapshot.value as? [String: Any] else { return }
            let newUser = UserModel(dictionary: dic)
            self.users.insert(newUser, at: 0)
            completed() 
        }
    }

Это должно удалить наблюдателя:

ref = Database.database().reference().child("placeID/\(placeIdFromSearch)/\(ViewComments.subComment)/subcomment/")
ref.removeAllObservers()

Но ничего не происходит.

PS: Если это поможет, если я отключу эту часть, ошибка исчезнет. Но тогда у меня нет изображения профиля пользователя. Это потому, что я уже использую эту функцию в другом tableView?

ref.observe(.value) { (snapshot) in
            guard let dic = snapshot.value as? [String: Any] else { return }
            let newUser = UserModel(dictionary: dic)
            self.users.insert(newUser, at: 0)
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Документация Firebase содержит ряд примеров того, как читать и записывать данные

В этом случае кажется, что есть пара проблем;

Один из них - как реализовать слушателей:

.childAdded — это событие запускается один раз для каждого существующего дочернего элемента и затем снова каждый раз, когда новый ребенок добавляется к указанному пути

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

Если вы заинтересованы в загрузке только одного узла, «подкомментарий» см. в разделе загрузки одного узла ниже.

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

let usersRef = my_firebase.child("users")
usersRef.observeSingleEvent(by: .value, with: { snapshot in
    //all users are returned to the app in the snapshot
    //   .value means 'give me everything in the specified node'
    // so then we can iterate over the snapshot to get each users data
}
  • Загрузить один узел -

Вторая проблема, которая связана с первой проблемой в функции «fetchUser» — похоже, вы хотите прочитать одного пользователя из Firebase один раз.

Хотя вы можете использовать .observe для этого, он фактически считывает ВСЕ данные и прослушивает все текущие события, которые не выглядят так, как вы хотите.

Лучшее решение — прочитать пользователя один раз с помощью observeSingleEvent aka getData, который считывает его и не оставляет слушателя, что устраняет необходимость удалять наблюдателей после завершения чтения.

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

ref.child("users/\(uid)/username").getData(completion:  { error, snapshot in
  guard error == nil else {
    print(error!.localizedDescription)
    return;
  }
  let userName = snapshot.value as? String ?? "Unknown";
});

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