如何更深入地阅读Firebase Swift 3的快照? [英] How to read deeper into a snapshot Firebase Swift 3?

查看:176
本文介绍了如何更深入地阅读Firebase Swift 3的快照?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在当前实现中,我可以通过创建一个结构 FireBaseData 的实例来读取属于 var uid 的预订。这是使用Firebase数据库中指定的值初始化的。

我需要为 / Users 节点下的所有用户预订所有的预订,然后将它们分配给一个数组,我可以在UITableVIew中显示值。我不知道如何更深入地阅读快照。

Firebase数据库结构:

  //创建对Firebase的引用
var dbRef:FIRDatabaseReference!
var uid =lwrUjaDCcoOcx4K2gioO76JWp2i2

//这个数组将保存所有登录用户的预订
var bookingInfo = [FireBaseData]()

)重写func viewDidLoad(){
super.viewDidLoad()
dbRef = FIRDatabase.database()。reference()。child(Users)
startObservingDB()//观察数据库对于值变化


func startObservingDB(){
dbRef.child(lwrUjaDCcoOcx4K2gioO76JWp2i2)。


中观察(.value,其中:{(snapshot:FIRDataSnapshot)){FireBaseData的一个实例,包含属于currentUid的所有预订
var newBookingInfo = [FireBaseData]

用于在snapshot.children中预订{

//在每次迭代之后,为当前迭代& assign分配一个带有
//booking的FireBaseData实例它到bookingItem
let bookingItem = FireBaseData(snapshot:booking as!FIRDataSnapshot)

//在每次迭代后追加bookingItem到newBookingInfo数组
newBookingInfo.append(bookingItem)


//将newBookingInfo赋值给全局变量bookingInfo,因此可以在类中全局使用
self.bookingInfo = newBookingInfo

,withCancel:{ (错误:任何)
})

}

//使用此结构从接收到的快照中检索数据
struct FireBaseData {
var BookingAmount:String!
var BookingNumber:String!


...等等
}

init(snapshot:FIRDataSnapshot){

如果让BookingAmountContent =(snapshot.value!as?NSDictionary )?[BookingAmount]为? String {
BookingAmount = BookingAmountContent
}
如果让BookingNumberContent =(snapshot.value!as?NSDictionary)?[BookingNumber]为?字符串{
BookingNumber = BookingNumberContent


....等等
}

snapshot.children_IS< FTransformedEnumerator:0x60800023a380>
snapshot.value_IS({
lwrUjaDCcoOcx4K2gioO76JWp2i2 = {
718565122 = {
BookingAmount = 12;
BookingNumber = 718565122;
DateAndTime =Mon,26 Sep 2016 18:30;
EmailAddress =1@gmail.com;
FlatNumber = 10;
FrequecyAmount = 48;
FrequencyName = Once;
FullName = Michael;
PhoneNumber = 25558882522;
PostCode = SE13TYY;
SelectedBathRow = 4;
SelectedBedRow = 3;
StreetAddress =High Street;
SuppliesAmount = 5;
SuppliesName =携带清洁用品;
insideCabinets = 0;
insideFridge = 1;
insideOven = 0;
interiorWindows = 1;
laundryWash = 1;
};
890149009 = {
BookingAmount = 73;
BookingNumber = 890149009;
DateAndTime =2016年10月1日13:30\" ;
EmailAddress =1@gmail.com;
FlatNumber = 10;
FrequecyAmount = 48;
FrequencyName =一次;
FullName =Michael;
PhoneNumber = 25558882522;
PostCode = SE13TYY;
SelectedBathRow = 4;
SelectedBedRow = 3;
StreetAddress =高街;
SuppliesAmount = 5;
SuppliesName =携带清洁用品;
insideCabinets = 0;
insideFridge = 1;
insideOven = 0;
interiorWindows = 1;
laundryWash = 1;
};
};
xd5rwZzUqoRbfMp2rq5pTxuRB3s1 = {
116928124 = {
BookingAmount = 22;
BookingNumber = 116928124;
DateAndTime =2016年12月16日星期五16:30;
EmailAddress =bibscy@gmail.com;
FlatNumber = 10;
FrequecyAmount = 22;
FrequencyName =每周;
FullName = Mi;
PhoneNumber = 28488824;
PostCode = RTRFHGT;
SelectedBathRow = 3;
SelectedBedRow = 1;
StreetAddress =12 High St;
SuppliesAmount = 0;
SuppliesName =我有清洁用品;
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 =bibscy@gmail.com;
FlatNumber = 10;
FrequecyAmount = 22;
FrequencyName =每周;
FullName = Mi;
PhoneNumber = 28488824;
PostCode = RTRFHGT;
SelectedBathRow = 3;
SelectedBedRow = 1;
StreetAddress =12 High St;
SuppliesAmount = 0;
SuppliesName =我有清洁用品;
TimeStampBookingSavedInDB = 1481888650;
TimeStampDateAndTime = 1482078600;
insideCabinets = 0;
insideFridge = 0;
insideOven = 0;
interiorWindows = 0;
laundryWash = 0;
};
};
})

根据@Jay建议更新答案

  *问题:在这个实现中queryOrdered(byChild:)`没有效果。 
dbRef.queryOrdered(byChild:TimeStampDateAndTime)。在
$ b中观察(.value,{:snapshot:FIRDataSnapshot)b $ b //在currentUid下保存所有预订的FireBaseData实例
var newBookingInfo = [FireBaseData]()

//迭代每个用户节点child
用于snapshot.children中的user_child {

// user_snap是user
let user_snap = user_child as!FIRDataSnapshot
//现在遍历每个预订
预订user_snap.children {

// //在每次迭代之后通过快照。儿童,为当前迭代创建一个带有预订的FireBaseData实例并将其分配给bookingItem
let bookingItem = FireBaseData(快照:预订为! FIRDataSnapshot)

//将每个迭代后的bookingItem附加到newBookingInfo数组
newBookingInfo.append(bookingItem)



$

//将newBookingInfo指定给全局变量bookingInfo,因此可以在类中全局使用
self.bookingInfo = newBookingInfo
//每次重新加载数据FIRDataEventType由值更改触发in
print(Huge \(Error))
self.tableView.reloadData()
} withCancel:{(Error:Any)
})

//设置您的表视图的estimatedRowHeight
tableView.estimatedRowHeight = 44.0
//将表视图的rowHeight设置为UITableViewAutomaticDimension
tableView.rowHeight = UITableViewAutomaticDimension
} //结束startObservingDB()



<@> jay还建议在代码中对从Firebase DB检索到的对象数组进行排序,而不是使用 queryOrdered(by:_) Firebase。
这是我对数组进行排序和过滤的方式。

  //将数组排序,使最近的日期首先出现
self.bookingInfo.sort通过:{(DateAndTimeObject_1,DateAndTimeObject2) - > Bool in

DateAndTimeObject_1.TimeStampDateAndTime< DateAndTimeObject2.TimeStampDateAndTime
})

//过滤每个元素数组与封闭体中指定的条件
self.bookingInfo = self.bookingInfo.filter({(firstElementInArray) - > Bool in
firstElementInArray.TimeStampDateAndTime == 1483201800
})


解决方案

用户节点



模板看起来像:

 用户
uid_0
booking_0
booking_amount:12
booking_1
booking_amount:14

通过读取所有内容的.value进行读取在用户节点中。

每个用户节点都有多个预订子节点,因此我们需要遍历这些节点以获取其子节点值。






pre $ p $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ code> let usersRef = myRootRef.child(byAppendingPath:users)

usersRef?.observe(.value,with:{snapshot in

if(snapshot! .value是NSNull){
print(not found)
} else {

for user_child in(snapshot?.children)! {//遍历每个用户节点的子节点
//将user_child枚举器分配给一个快照
let user_snap = user_child as! FDataSnapshot

用于预订user_snap.children {//现在迭代每个预订
//预订是一个枚举因此使它成为快照
让bookingSnap = booking as! FDataSnapshot
让dict = bookingSnap.value为! (String:String]
let amount = dict [booking_amount]

print(amount!)
}
}
}
})


With the current implementation I can read the bookings belonging to var uid by creating an instance of a structure FireBaseData which is initialized with the values specified in the Firebase Database.

I need to get all bookings for all users under /Users node and then assign them to an array so that I can display the values in a UITableVIew. I don't know how to read deeper into the snapshot.

Firebase Database Structure:

// 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 = "1@gmail.com";
        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 = "1@gmail.com";
        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 = "bibscy@gmail.com";
        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 = "bibscy@gmail.com";
        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;
    };
    };
 })

Updated Answer according to @Jay suggestion

*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 also suggested that to sort the array of objects retrieved from Firebase DB in code rather than using queryOrdered(by:_) method provided by Firebase. Here is how I am sorting and filtering the array.

     // 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
   })

解决方案

So what you after here is each booking node within each users node

A template would look like:

users
  uid_0
   booking_0
     booking_amount: "12"
   booking_1
     booking_amount: "14"

Read by .value which reads in everything in the users node.

Each user node has multiple booking children so we will then need to iterate over those to get their child values.

Inside each child is the key: value pairs we want to get, in this example, booking_amount and the value.

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!)
        }      
      }
    }
})

这篇关于如何更深入地阅读Firebase Swift 3的快照?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆