I am creating an application for a library. I am trying to fetch all the books the user has checked out from Firebase, but my attempts to make the function asynchronous with a DispatchGroup doesn't seem to be working. I suspect this to be because of the for-in loop found inside of the function.
func fetchHistory() {
if items.count > 0 {
items.removeAll()
}
let myGroup = DispatchGroup()
myGroup.enter()
var itemNames = [String]() // this holds the names of the child values of /users/uid/items/ <-- located in Firebase Database
guard let uid = fAuth.currentUser?.uid else {return}
fData.child("users").child(uid).child("items").observe(.value, with: { snapshot in
// make sure there is at least ONE item in the history
if snapshot.childrenCount > 0 {
let values = snapshot.value as! NSDictionary
for i in values.allKeys {
itemNames.append(i as! String)
}
print(itemNames)
let uid = fAuth.currentUser!.uid // get the UID of the user
for item in itemNames {
fData.child("users").child(uid).child("items").child(item).observe(.value, with: { snapshot in
let values = snapshot.value as! NSDictionary
let bookTitle = values["title"] as! String
print(bookTitle)
let bookAuthor = values["author"] as! String
print(bookAuthor)
let bookCoverUrl = values["coverUrl"] as! String
print(bookCoverUrl)
let bookStatus = values["status"] as! String
print(bookStatus)
let bookDueDate = values["dueDate"] as! String
print(bookDueDate)
let book = Book(name: bookTitle, author: bookAuthor, coverUrl: bookCoverUrl, status: bookStatus, dueDate: bookDueDate)
self.items.append(book)
})
}
self.booksTable.isHidden = false
} else {
self.booksTable.isHidden = true
}
})
myGroup.leave()
myGroup.notify(queue: DispatchQueue.main, execute: {
self.booksTable.reloadData()
print("Reloading table")
})
}
Here is the output from the print() statements:
########0
Reloading table
["78DFB90A-DE5B-47DE-ADCA-2DAB9D43B9C8"]
Mockingjay (The Hunger Games, #3)
Suzanne Collins
https://images.gr-assets.com/books/1358275419s/7260188.jpg
Checked
Replace
The first two lines of output should be printed AFTER everything else has printed. I really need some help on this, I have been stuck on this for hours. Thanks!
Edit: As requested, here is my Firebase structure:
users:
meZGWn5vhzXpk5Gsh92NhSasUPx2:
ID: "12345"
firstname: "Faraaz"
items:
78DFB90A-DE5B-47DE-ADCA-2DAB9D43B9C8
author: "Suzanne Collins"
coverUrl: "https://images.gr assets.com/books/1358275419s/..."
dueDate: "Date"
status: "Checked"
title: "Mockingjay (The Hunger Games, #3)"
type: "regular"
Bookvalues directly to the main model object driving your table view. You should populate a local array, and then only update your model object in thenotifyblock. Right now, if the user happened to scroll after some records had appended but before the finalreloadData, you could get errors about inconsistency regarding the state of the table view and the model.