Как гарантировать, что данные не извлекаются и не добавляются целиком при каждом добавлении новой записи?

#ios #swift #firebase #firebase-realtime-database

#iOS #swift #firebase #firebase-realtime-database

Вопрос:

 func generateDataForRecents()  {
        if URLArrayStringThisSeason.count == 0 {
            self.activityIndicator2.isHidden = false
            self.activityIndicator2.startAnimating()
        }


        let databaseRef = FIRDatabase.database().reference()

        databaseRef.child("palettes").queryLimited(toFirst: 100).observe(.value, with: { (snapshot) in

            if let snapDict = snapshot.value as? [String:AnyObject]{

                for each in snapDict as [String:AnyObject]{

                    let URL = each.value["URL"] as! String

                    self.URLArrayStringRecents.append(URL)
                    //print(self.URLArrayString.count)

                    //print(snapshot)

                    //let pictureTitle = each.value["title"] as! String
                    print(self.URLArrayStringRecents.count)
                }
            }

            self.whatsNewCollectionView?.reloadData() //Reloads data after the number and all the URLs are fetched
            self.activityIndicator2.stopAnimating()
            self.activityIndicator2.isHidden = true
        })


    }
  

Следующий код выполняет извлечение данных при каждом вызове функции или при добавлении новых данных.

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

Например, когда уже идентифицировано 15 записей, а затем внезапно добавляется новая запись, массив URL-адреса будет содержать 15 16, что составляет в общей сложности 31.

Как мне сделать так, чтобы новые данные добавлялись в массив вместо добавления всего снимка?

Ответ №1:

Вы делаете это, прослушивая .childAdded события, а не прослушивая .value :

 var query = databaseRef.child("palettes").queryLimited(toFirst: 100)
query.observe(.childAdded, with: { (snapshot) in
    let URL = snapshot.childSnapshot(forPath/: "URL").value as! String
    self.URLArrayStringRecents.append(URL)
}
  

Поскольку у вас есть запрос с ограничением, добавление 101-го элемента означает, что один элемент будет удален из представления. Итак, вы тоже захотите обработать .childRemoved :

 query.observe(.childRemoved, with: { (snapshot) in 
    // TODO: remove the item from snapshot.key from the araay
})
  

Я рекомендую вам потратить некоторое время на соответствующую документацию по обработке дочерних событий, прежде чем продолжить.

Комментарии:

1. исправление хм: его пусть URL = snapshot.childSnapshot(forPath: «URL»).значение как! String а не childByAppendingPath . Но спасибо за предупреждение!

2. Спасибо! Я не был уверен в синтаксисе там. Исправлено.

Ответ №2:

Пожалуйста, проверьте метод ниже. Я использую этот метод, не получая дублирующейся записи.

 func getallNotes()
{
    let firebaseNotesString: String = Firebase_notes.URL
    let firebaseNotes = FIRDatabase.database().referenceFromURL(firebaseNotesString).child(email)
    firebaseNotes.observeEventType(.Value, withBlock: { snapshot in

        if snapshot.childSnapshotForPath("Category").hasChildren()
        {
            let child = snapshot.children
            self.arrNotes = NSMutableArray()
            self.arrDictKeys = NSMutableArray()
            for itemsz in child
            {
                let childz = itemsz as! FIRDataSnapshot
                let AcqChildKey : String = childz.key

                if AcqChildKey == AcqIdGlobal
                {
                    if (childz.hasChildren() == true)
                    {
                        let dictChild = childz.value as! NSMutableDictionary
                        self.arrDictKeys = NSMutableArray(array: dictChild.allKeys)

                        for i in 0..<self.arrDictKeys.count
                        {
                            let _key = self.arrDictKeys.objectAtIndex(i).description()
                            print(_key)
                            let dictData : NSMutableDictionary = NSMutableDictionary(dictionary: (dictChild.valueForKey(_key)?.mutableCopy())! as! [NSObject : AnyObject])
                            dictData.setObject(_key, forKey: "notesId")

                            self.arrNotes.addObject(dictData)
                        }
                    }
                }
            }
            self.tableviewNote.reloadData()
        }
    })
}
  

Ответ №3:

Что касается запроса для удаленного дочернего элемента,

 query.observe(.childRemoved, with: { (snapshot) in

            print(snapshot)
            let URL = snapshot.childSnapshot(forPath: "URL").value as! String
            self.URLArrayStringThisSeason = self.URLArrayStringThisSeason.filter() {$0 != URL}
            self.thisSeasonCollectionView.reloadData()
        })
  

он получит URL удаленного дочернего элемента, а затем соответствующим образом обновит массив.