使用当前的实现,我可以通过创建结构 FireBaseData
的实例来读取属于 var uid
的预订,该结构使用 Firebase 数据库中指定的值进行初始化。
我需要获取 /Users
节点下所有用户的所有预订,然后将它们分配给一个数组,以便我可以在 UITableVIew 中显示这些值。我不知道如何深入了解快照。
Firebase 数据库结构:
// create a reference to Firebase
var dbRef:FIRDatabaseReference!
var uid = "lwrUjaDCcoOcx4K2gioO76JWp2i2"
// this array will hold all bookings for the logged in user
var bookingInfo = [FireBaseData]()
override func viewDidLoad() {
super.viewDidLoad()
dbRef = FIRDatabase.database().reference().child("Users")
startObservingDB() // observe the database for value changes
}
func startObservingDB() {
dbRef.child("lwrUjaDCcoOcx4K2gioO76JWp2i2").
observe(.value, with: { (snapshot: FIRDataSnapshot) in
// an instance of FireBaseData holding all bookings belonging to currentUid
var newBookingInfo = [FireBaseData]()
for booking in snapshot.children {
// after each iteration create an instance of FireBaseData with
// 'booking' for the current iteration & assign it to bookingItem
let bookingItem = FireBaseData(snapshot: booking as! FIRDataSnapshot)
// append the bookingItem after each iteration to newBookingInfo array
newBookingInfo.append(bookingItem)
}
//assign newBookingInfo to global variable bookingInfo so it can be used globally within the class
self.bookingInfo = newBookingInfo
}, withCancel: { (Error:Any) in
})
}
// use this struct to retrieve data from the snapshot received
struct FireBaseData {
var BookingAmount:String!
var BookingNumber:String!
.
.
... and so on
}
init(snapshot:FIRDataSnapshot){
if let BookingAmountContent = (snapshot.value! as? NSDictionary)?["BookingAmount"] as? String {
BookingAmount = BookingAmountContent
}
if let BookingNumberContent = (snapshot.value! as? NSDictionary)?["BookingNumber"] as? String {
BookingNumber = BookingNumberContent
.
.
.... and so on
}
snapshot.children_IS <FTransformedEnumerator: 0x60800023a380>
snapshot.value_IS({
lwrUjaDCcoOcx4K2gioO76JWp2i2 = {
718565122 = {
BookingAmount = 12;
BookingNumber = 718565122;
DateAndTime = "Mon, 26 Sep 2016 18:30";
EmailAddress = "[email protected]";
FlatNumber = 10;
FrequecyAmount = 48;
FrequencyName = Once;
FullName = "Michael ";
PhoneNumber = 25558882522;
PostCode = SE13TYY;
SelectedBathRow = 4;
SelectedBedRow = 3;
StreetAddress = "High Street";
SuppliesAmount = 5;
SuppliesName = "Bring cleaning supplies";
insideCabinets = 0;
insideFridge = 1;
insideOven = 0;
interiorWindows = 1;
laundryWash = 1;
};
890149009 = {
BookingAmount = 73;
BookingNumber = 890149009;
DateAndTime = "Sat, 01 Oct 2016 13:30";
EmailAddress = "[email protected]";
FlatNumber = 10;
FrequecyAmount = 48;
FrequencyName = Once;
FullName = "Michael ";
PhoneNumber = 25558882522;
PostCode = SE13TYY;
SelectedBathRow = 4;
SelectedBedRow = 3;
StreetAddress = "High Street";
SuppliesAmount = 5;
SuppliesName = "Bring cleaning supplies";
insideCabinets = 0;
insideFridge = 1;
insideOven = 0;
interiorWindows = 1;
laundryWash = 1;
};
};
xd5rwZzUqoRbfMp2rq5pTxuRB3s1 = {
116928124 = {
BookingAmount = 22;
BookingNumber = 116928124;
DateAndTime = "Fri, 16 Dec 2016 16:30";
EmailAddress = "[email protected]";
FlatNumber = 10;
FrequecyAmount = 22;
FrequencyName = "Every week";
FullName = Mi;
PhoneNumber = 28488824;
PostCode = RTRFHGT;
SelectedBathRow = 3;
SelectedBedRow = 1;
StreetAddress = "12 High St";
SuppliesAmount = 0;
SuppliesName = "I have cleaning supplies";
TimeStampBookingSavedInDB = 1481886718;
TimeStampDateAndTime = 1481905800;
insideCabinets = 0;
insideFridge = 0;
insideOven = 0;
interiorWindows = 0;
laundryWash = 0;
};
328241274 = {
BookingAmount = 22;
BookingNumber = 328241274;
DateAndTime = "Sun, 18 Dec 2016 16:30";
EmailAddress = "[email protected]";
FlatNumber = 10;
FrequecyAmount = 22;
FrequencyName = "Every week";
FullName = Mi;
PhoneNumber = 28488824;
PostCode = RTRFHGT;
SelectedBathRow = 3;
SelectedBedRow = 1;
StreetAddress = "12 High St";
SuppliesAmount = 0;
SuppliesName = "I have cleaning supplies";
TimeStampBookingSavedInDB = 1481888650;
TimeStampDateAndTime = 1482078600;
insideCabinets = 0;
insideFridge = 0;
insideOven = 0;
interiorWindows = 0;
laundryWash = 0;
};
};
})
根据@Jay 的建议更新了答案
*Problem : with this implementation `queryOrdered(byChild` has no effect.*
func startObservingDB() {
dbRef.queryOrdered(byChild: "TimeStampDateAndTime").observe(.value, with: { (snapshot: FIRDataSnapshot) in
// an instance of FireBaseData holding all bookings under currentUid
var newBookingInfo = [FireBaseData]()
//iterate over each user node child
for user_child in snapshot.children {
//user_snap is each user
let user_snap = user_child as! FIRDataSnapshot
//now iterate over each booking
for booking in user_snap.children {
// after each iteration through snapshot.children, create an instance of FireBaseData with 'booking' for the current iteration & assign it to bookingItem
let bookingItem = FireBaseData(snapshot: booking as! FIRDataSnapshot)
// append the bookingItem after each iteration to newBookingInfo array
newBookingInfo.append(bookingItem)
}
}
//assign newBookingInfo to global variable bookingInfo so it can be used globally within the class
self.bookingInfo = newBookingInfo
// reload the data every time FIRDataEventType is triggered by value changes in Database
self.tableView.reloadData()
}, withCancel: { (Error:Any) in
print("Huge \(Error)")
})
//Set the estimatedRowHeight of your table view
tableView.estimatedRowHeight = 44.0
// Set the rowHeight of your table view to UITableViewAutomaticDimension
tableView.rowHeight = UITableViewAutomaticDimension
} // end of startObservingDB()
@Jay 还建议在代码中对从 Firebase DB 检索到的对象数组进行排序,而不是使用 Firebase 提供的 queryOrdered(by:_)
方法。
这是我对数组进行排序和过滤的方式。
// sort the array in place so that the most recent date will appear first
self.bookingInfo.sort(by: {(DateAndTimeObject_1,DateAndTimeObject2) -> Bool in
DateAndTimeObject_1.TimeStampDateAndTime < DateAndTimeObject2.TimeStampDateAndTime
})
// filter each element in the array against the condition specified in the body of the closure
self.bookingInfo = self.bookingInfo.filter({(firstElementInArray) -> Bool in
firstElementInArray.TimeStampDateAndTime == 1483201800
})
所以你在这里之后是每个用户节点中的每个预订节点
模板如下所示:
users
uid_0
booking_0
booking_amount: "12"
booking_1
booking_amount: "14"
按 .value 读取,读取用户节点中的所有内容。
每个用户节点都有多个预订子节点,因此我们需要遍历这些子节点以获取它们的子节点值。
在每个 child 内部都有键:我们想要获取的值对,在这个例子中,booking_amount 和值。
let usersRef = myRootRef.child(byAppendingPath: "users")
usersRef?.observe(.value, with: { snapshot in
if ( snapshot!.value is NSNull ) {
print("not found")
} else {
for user_child in (snapshot?.children)! { //iterate over each user node child
//assign the user_child enumerator to a snapshot
let user_snap = user_child as! FDataSnapshot
for booking in user_snap.children { //now iterate over each booking
//booking is a enumerator so make it a snapshot
let bookingSnap = booking as! FDataSnapshot
let dict = bookingSnap.value as! [String: String]
let amount = dict["booking_amount"]
print(amount!)
}
}
}
})
关于ios - 如何更深入地阅读 Firebase Swift 3 快照?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41212468/
欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) | Powered by Discuz! X3.4 |