I am really struggling with how to read and store my data from the firebase real-time database. This is what my database looks like:
text json
{
"Live": {
"Today": {
"121321": {
"title": "rnd",
"description": "blah blah blah",
"stamp": 1111
},
"121441": {
"title": "arnd",
"description": "blh blah blah",
"stamp": 134
}
},
"Tomorrow": {
"143821": {
"title": "brnd",
"description": "blh blah blah",
"stamp": 1134
}
},
"ThisWeek": {
"18934": {
"title": "drnd",
"description": "blh blh blah blah blah",
"stamp": 237812
},
"323123": {
"title": "crnd",
"description": "blh blh blah blah",
"stamp": 138921
}
}
}
}
I have highlighted what I call events in green. Events have a title, description, and stamp. I then have an outer nest of today, tomorrow, and this week. Today, tomorrow, and this week are each separate dictionaries that hold any number of events.
I have created a class in a separate swift file:
class Event: NSObject {
var EventTitle: String?
var EventDescription: String?
var EventStamp: Int?
}
I want to have three arrays. The first array will have all events for "today", the second will have all events for "tomorrow" and the third will have all events for "this week". I will eventually need to sort the events in each array by stamp. However, I am stuck on how to convert the firebase datasnapshots into events and then put all events into an array. My code so far
//declaring empty arrays to fill later
var todayEvents = [Event]()
var tomorrowEvents = [Event]()
var thisweekEvents = [Event]()
//Getting snapshots
ref?.child(".../LiveEvents").observeSingleEvent(of: .value, with: { (snapshot) in
let todaysnap = snapshot.childSnapshot(forPath: "Today")
let tomorrowsnap = snapshot.childSnapshot(forPath: "Tomorrow")
let thisweeksnap = snapshot.childSnapshot(forPath: "ThisWeek")
//need to assign data to events and to arrays Today, Tomorrow, Thisweek
})
When I try to print my snap data I get an optional value and if I try to assign variable using as string then I get an error like "Cannot convert value of type 'DataSnapshot' to type 'Int' in coercion." I have looked at other answers, but I believe my situation is different since I have double nested data and I want to assign to different arrays. I'm using swift 4
Thank you
---If I do print(todaysnap) I get
Snap (Today) {
121321 = {
title = rnd;
description = blah blah blah;
stamp = 1111
};
121441 = {
title = arnd;
description = blh blah blah;
stamp = 134
};
} Doing print(todaysnap.value) gives me the same thing except the type is "Optional" instead of "Snap (Today)"
Here's the complete code to read all of the data in the Live node, and put Today, Tomorrow and ThisWeek events into separate array's
var todayArray = [String]()
var tomorrowArray = [String]()
var thisWeekArray = [String]()
let liveRef = self.ref.child("Live")
liveRef.observeSingleEvent(of: .value, with: { snapshot in
let todaySnap = snapshot.childSnapshot(forPath: "Today")
for todayChild in todaySnap.children {
let todayChildSnap = todayChild as! DataSnapshot
let todayDict = todayChildSnap.value as! [String: Any]
let title = todayDict["title"] as! String
todayArray.append(title)
}
let tomorrowSnap = snapshot.childSnapshot(forPath: "Tomorrow")
for tomorrowChild in tomorrowSnap.children {
let tomorrowChildSnap = tomorrowChild as! DataSnapshot
let tomorrowDict = tomorrowChildSnap.value as! [String: Any]
let title = tomorrowDict["title"] as! String
tomorrowArray.append(title)
}
let thisWeekSnap = snapshot.childSnapshot(forPath: "ThisWeek")
for thisWeekChild in thisWeekSnap.children {
let thisWeekChildSnap = thisWeekChild as! DataSnapshot
let thisWeekDict = thisWeekChildSnap.value as! [String: Any]
let title = thisWeekDict["title"] as! String
thisWeekArray.append(title)
}
print("Today")
for today in todayArray {
print(" " + today)
}
print("Tomorrow")
for tomorrow in tomorrowArray {
print(" " + tomorrow)
}
print("This Week")
thisWeekArray.map { print(" " + $0) } //gettin' all swifty here
})
and the output is
Today
rnd
arnd
Tomorrow
brnd
This Week
drnd
crnd
However... I would probably change the stucture:
Live
event_0 //generated with childByAutoId
title: "rnd"
timestamp: "20180918"
event_1
title: "brnd"
timestamp: "20180919"
because you can now query on every node, pulling out today's events. Tomorrow's events or ThisWeeks event or any day or range you like.
I'm going to uploading new data each day so today, tomorrow and this week will be refreshed each day
and with this structure, all you would need to do is add nodes and your queries will figure out what nodes are for what periods of time.
Since your Event class doesn't do any processing and essentially just a structure to hold your data, how about a struct:
struct EventStruct {
var EventTitle: String?
var EventDescription: String?
var EventStamp: Int?
}
Then add the events to the array:
let title = thisWeekDict["title"] as! String
let desc = thisWeekDict["desc"] as! String
let stamp = thsWeekDict["stamp"] as! String
let anEvent = Event(title: title, desc: desc, stamp: stamp)
thisWeekArray.append(anEvent)
or leave it as a class and just pass the snapshot in and have the class assign the properties from the snapshot. Either way, please add error checking for nil's.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.