问题
I have a structure in which users are registering for events, and the registered events are stored as the following:
I am trying to access the registeredEvents and display the children on a table view. So far, I have done this:
override func viewDidLoad() {
super.viewDidLoad()
let id = Auth.auth().currentUser?.uid
let ref = Database.database().reference()
ref.child("users").child(id!).child("registeredEvents").observeSingleEvent(of: .value, with: { snapshot in
print(snapshot.childrenCount)
for rest in snapshot.children.allObjects as! [DataSnapshot] {
print(rest.value!)
self.eventsArray.append(rest.value!)
}
})
print(eventsArray)
self.tblEvents.dataSource = self
self.tblEvents.delegate = self
}
It prints all the children's values like it is supposed to, but it wont do anything after that observe closure. It will not print eventsArray, or anything that I put in a print statement. Also, eventsArray only contains things it had before the closure. Could you please let me know why this is happening, and what needs to be done to fix it, specifically in the form of code?
回答1:
Firebase is asynchronous - code runs much faster than the internet so the code following the closure
print(eventsArray)
will actually run before the code in the closure. Also, Firebase data is only valid inside that closure so ensure you're working with data in the closure first. In this case to correct it try this
override func viewDidLoad() {
super.viewDidLoad()
self.tblEvents.dataSource = self
self.tblEvents.delegate = self
let id = Auth.auth().currentUser?.uid
let ref = Database.database().reference()
ref.child("users").child(id!).child("registeredEvents").observeSingleEvent(of: .value, with: { snapshot in
print(snapshot.childrenCount)
for rest in snapshot.children.allObjects as! [DataSnapshot] {
print(rest.value!)
self.eventsArray.append(rest.value!)
}
print(self.eventsArray) //or refresh your tableView here
})
}
The code is passing a bunch of .value objects, which are dictionaries, to your eventsArray. You may want to consider crafting objects to hold that dictionary data and adding those objects to the array instead.
for restSnap in snapshot.children.allObjects as! [DataSnapshot] {
let event = EventClass(withSnap: restSnap)
self.eventsArray.append(event)
}
the dataSource array would look like this
var eventsArray = [EventClass]()
and the EventClass would be
class EventClass {
var first_name = ""
var event_key = ""
init(withSnap: DataSnapshot) {
self.event_key = withSnap.key
self.first_name = withSnap.childSnapshot(forPath: "First name").value ?? "No first name"
let registeredEventsSnap = withSnap.childSnapshot(forPath: "registeredEvents")
//iterate over the registeredEventsSnap to get all the events
}
}
来源:https://stackoverflow.com/questions/59588174/code-not-executing-after-observe-firebase-method-swift4