Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
518 views
in Technique[技术] by (71.8m points)

ios - 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.

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:

Firebase Tree

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

*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()

bookings are not ordered in ascending order

@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
   })
    
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...