What doesn't work the first time?:
The order in which database entries that I fetch displays
I am running this
1st part In ViewDiDLoad
let thisUserRef = Database.database().reference().child("users").child(uid)
let myPeopleRef = thisUserRef.child("likers")
myPeopleRef.queryLimited(toLast: 30).observeSingleEvent(of: .value, with: { snapshot in
let userArray = snapshot.children.allObjects as! [DataSnapshot]
for person in userArray.reversed() where uid == Auth.auth().currentUser?.uid {
let personUid = person.value as! String
self.printPersonInfo(uid: personUid) //// this calls a DispatchQueue.main.async that appends the data in the array and reloads
}
})
func printPersonInfo(uid: String) {
print(uid)
let usersRef = Database.database().reference().child("users")
let thisUser = usersRef.child(uid)
thisUser.observeSingleEvent(of: .value, with: { snapshot in
let xx = snapshot.childSnapshot(forPath: "xx").value as? String ?? "No Entry"
let yy = snapshot.childSnapshot(forPath: "yy").value as? String ?? "No Entry"
let rr = snapshot.childSnapshot(forPath: "rr").value as? String ?? "No Entry"
let zz = snapshot.childSnapshot(forPath: "zz").value as? String ?? "No Entry"
let ll = snapshot.childSnapshot(forPath: "ll").value as? String ?? "No Entry"
let p = Usery(xx: xx, yy: yy, rr: rr, zz: zz, ll: ll)
self.person.append(p)
print(self.person, "person")
self.table.reloadData()
})
}
//////this gets the various data elements of the users that get displayed.
///////So to summarize, the query determines which users get displayed. This func determined which data of those users gets displayed.
Example of database entires of last 30
user K
user B
user F
user G
user K
user B
user K
.....
The only time this doesn't work is if you install the app clean for the first time. Then the order in which it displays is
user K
user K
user B
user B
user F
user G
JSON
users
uid
likers
chailbyAutoID: uid1
chailbyAutoID: uid2
One possible solution is to use DispatchGroups to control the loading of the data, which therefore would control the sequence in which a class var array is populated.
In this example, we'll read all of the users uids from a users node and populate an array. It would look like this
users
uid_0
name: "Wilbur"
uid_1:
name: "Orville"
We'll then go back and re-read additional user data from that node, using array.reversed() so they populate a result array in reversed order. We'll need a class to store each user data and then a class array to store all of the users are they are read in. Here's the class vars
struct PersonClass {
var uid = ""
var name = ""
}
var personArray = [PersonClass]()
and the code to populate them in reverse order
func readUserDataUsingDispatch() {
let ref = self.ref.child("users") //self.ref points to my firebase
ref.observeSingleEvent(of: .value, with: { snapshot in
//this just builds and array of user id's - we'll iterate through them to read the rest of the data
let idArray = snapshot.children.allObjects as! [DataSnapshot]
var allKeys = [String]()
for userSnap in idArray {
allKeys.append( userSnap.key ) //[uid_0, uid_1] etc
}
let group = DispatchGroup()
for uid in allKeys.reversed() {
group.enter()
let thisUser = ref.child(uid)
thisUser.observeSingleEvent(of: .value, with: { userSnapshot in
let name = userSnapshot.childSnapshot(forPath: "name").value as! String
let person = PersonClass(uid: uid, name: name)
self.personArray.append(person)
print("added uid")
group.leave()
})
}
group.notify(queue: .main) {
print("done")
}
})
}
when you run the code this is the output, indicating the data is loaded
added uid
added uid
done
and then when printing the class var personArray
it's the users in reverse order.
uid_1 Orville
uid_0 Wilbur