简体   繁体   English

如何更深入地阅读 Firebase Swift 3 快照?

[英]How to read deeper into a snapshot Firebase Swift 3?

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.通过当前的实现,我可以通过创建一个结构FireBaseData的实例来读取属于var uid的预订,该实例使用 Firebase 数据库中指定的值进行初始化。

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.我需要获取/Users节点下所有用户的所有预订,然后将它们分配给一个数组,以便我可以在 UITableVIew 中显示这些值。 I don't know how to read deeper into the snapshot.我不知道如何更深入地阅读快照。

Firebase Database Structure: Firebase 数据库结构:

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 = "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 = "b@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 = "bi@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根据@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 also suggested that to sort the array of objects retrieved from Firebase DB in code rather than using queryOrdered(by:_) method provided by Firebase. @Jay 还建议在代码中对从 Firebase DB 检索到的对象数组进行排序,而不是使用 Firebase 提供的queryOrdered(by:_)方法。 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. Read by .value 读取用户节点中的所有内容。

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.每个孩子内部是我们想要获得的键:值对,在这个例子中,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!)
        }      
      }
    }
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM