菜鸟教程小白 发表于 2022-12-12 12:34:33

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


                                            <p><p>使用当前的实现,我可以通过创建结构 <code>FireBaseData</code> 的实例来读取属于 <code>var uid</code> 的预订,该结构使用 Firebase 数据库中指定的值进行初始化。 </p>
<p>我需要获取 <code>/Users</code> 节点下所有用户的所有预订,然后将它们分配给一个数组,以便我可以在 UITableVIew 中显示这些值。我不知道如何深入了解快照。</p>
<p>Firebase 数据库结构:</p>
<p> <a href="/image/itQey.png" rel="noreferrer noopener nofollow"><img src="/image/itQey.png" alt="Firebase Tree"/></a> </p>
<pre><code>// create a reference to Firebase
var dbRef:FIRDatabaseReference!
var uid = &#34;lwrUjaDCcoOcx4K2gioO76JWp2i2&#34;

// this array will hold all bookings for the logged in user
      var bookingInfo = ()

override func viewDidLoad() {
   super.viewDidLoad()
      dbRef = FIRDatabase.database().reference().child(&#34;Users&#34;)
             startObservingDB() // observe the database for value changes
}

func startObservingDB() {
    dbRef.child(&#34;lwrUjaDCcoOcx4K2gioO76JWp2i2&#34;).
       observe(.value, with: { (snapshot: FIRDataSnapshot) in

// an instance of FireBaseData holding all bookings belonging to currentUid
      var newBookingInfo = ()
   
      for booking in snapshot.children {
            
         // after each iteration create an instance of FireBaseData with
         //   &#39;booking&#39; for the current iteration &amp; 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)?[&#34;BookingAmount&#34;] as? String {
      BookingAmount = BookingAmountContent
      }
    if let BookingNumberContent = (snapshot.value! as? NSDictionary)?[&#34;BookingNumber&#34;] as? String {
      BookingNumber = BookingNumberContent
.
.
.... and so on
      }

snapshot.children_IS &lt;FTransformedEnumerator: 0x60800023a380&gt;
snapshot.value_IS({
    lwrUjaDCcoOcx4K2gioO76JWp2i2 =   {
       718565122 =         {
      BookingAmount = 12;
      BookingNumber = 718565122;
      DateAndTime = &#34;Mon, 26 Sep 2016 18:30&#34;;
      EmailAddress = &#34;[email protected]&#34;;
      FlatNumber = 10;
      FrequecyAmount = 48;
      FrequencyName = Once;
      FullName = &#34;Michael &#34;;
      PhoneNumber = 25558882522;
      PostCode = SE13TYY;
      SelectedBathRow = 4;
      SelectedBedRow = 3;
      StreetAddress = &#34;High Street&#34;;
      SuppliesAmount = 5;
      SuppliesName = &#34;Bring cleaning supplies&#34;;
      insideCabinets = 0;
      insideFridge = 1;
      insideOven = 0;
      interiorWindows = 1;
      laundryWash = 1;
    };
    890149009 =         {
      BookingAmount = 73;
      BookingNumber = 890149009;
      DateAndTime = &#34;Sat, 01 Oct 2016 13:30&#34;;
      EmailAddress = &#34;[email protected]&#34;;
      FlatNumber = 10;
      FrequecyAmount = 48;
      FrequencyName = Once;
      FullName = &#34;Michael &#34;;
      PhoneNumber = 25558882522;
      PostCode = SE13TYY;
      SelectedBathRow = 4;
      SelectedBedRow = 3;
      StreetAddress = &#34;High Street&#34;;
      SuppliesAmount = 5;
      SuppliesName = &#34;Bring cleaning supplies&#34;;
      insideCabinets = 0;
      insideFridge = 1;
      insideOven = 0;
      interiorWindows = 1;
      laundryWash = 1;
    };
};
   xd5rwZzUqoRbfMp2rq5pTxuRB3s1 =   {
    116928124 =         {
      BookingAmount = 22;
      BookingNumber = 116928124;
      DateAndTime = &#34;Fri, 16 Dec 2016 16:30&#34;;
      EmailAddress = &#34;[email protected]&#34;;
      FlatNumber = 10;
      FrequecyAmount = 22;
      FrequencyName = &#34;Every week&#34;;
      FullName = Mi;
      PhoneNumber = 28488824;
      PostCode = RTRFHGT;
      SelectedBathRow = 3;
      SelectedBedRow = 1;
      StreetAddress = &#34;12 High St&#34;;
      SuppliesAmount = 0;
      SuppliesName = &#34;I have cleaning supplies&#34;;
      TimeStampBookingSavedInDB = 1481886718;
      TimeStampDateAndTime = 1481905800;
      insideCabinets = 0;
      insideFridge = 0;
      insideOven = 0;
      interiorWindows = 0;
      laundryWash = 0;
    };
    328241274 =         {
      BookingAmount = 22;
      BookingNumber = 328241274;
      DateAndTime = &#34;Sun, 18 Dec 2016 16:30&#34;;
      EmailAddress = &#34;[email protected]&#34;;
      FlatNumber = 10;
      FrequecyAmount = 22;
      FrequencyName = &#34;Every week&#34;;
      FullName = Mi;
      PhoneNumber = 28488824;
      PostCode = RTRFHGT;
      SelectedBathRow = 3;
      SelectedBedRow = 1;
      StreetAddress = &#34;12 High St&#34;;
      SuppliesAmount = 0;
      SuppliesName = &#34;I have cleaning supplies&#34;;
      TimeStampBookingSavedInDB = 1481888650;
      TimeStampDateAndTime = 1482078600;
      insideCabinets = 0;
      insideFridge = 0;
      insideOven = 0;
      interiorWindows = 0;
      laundryWash = 0;
    };
    };
})
</code></pre>
<p><strong>根据@Jay 的建议更新了答案</strong></p>
<pre><code>*Problem : with this implementation `queryOrdered(byChild:)` has no effect.*
func startObservingDB() {
dbRef.queryOrdered(byChild: &#34;TimeStampDateAndTime&#34;).observe(.value, with: { (snapshot: FIRDataSnapshot) in
   
    // an instance of FireBaseData holding all bookings under currentUid
    var newBookingInfo = ()
   
    //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&#39;booking&#39; for the current iteration &amp; 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(&#34;Huge \(Error)&#34;)
    })
   
    //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()
</code></pre>
<p> <a href="/image/XZLA0.png" rel="noreferrer noopener nofollow"><img src="/image/XZLA0.png" alt="bookings are not ordered in ascending order"/></a> </p>
<p><strong>@Jay 还建议在代码中对从 Firebase DB 检索到的对象数组进行排序,而不是使用 Firebase 提供的 <code>queryOrdered(by:_)</code> 方法。</strong>
这是我对数组进行排序和过滤的方式。</p>
<pre><code>   // sort the array in place so that the most recent date will appear first
   self.bookingInfo.sort(by: {(DateAndTimeObject_1,DateAndTimeObject2) -&gt; Bool in
            
       DateAndTimeObject_1.TimeStampDateAndTime &lt; DateAndTimeObject2.TimeStampDateAndTime
   })
   
    // filter each element in the array against the condition specified in the body of the closure
    self.bookingInfo = self.bookingInfo.filter({(firstElementInArray) -&gt; Bool in      
      firstElementInArray.TimeStampDateAndTime == 1483201800
   })
   
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>所以你在这里之后是每个用户节点中的每个预订节点</p>

<p>模板如下所示:</p>

<pre><code>users
uid_0
   booking_0
   booking_amount: &#34;12&#34;
   booking_1
   booking_amount: &#34;14&#34;
</code></pre>

<p>按 .value 读取,读取用户节点中的所有内容。</p>

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

<p>在每个 child 内部都有键:我们想要获取的值对,在这个例子中,booking_amount 和值。</p>

<pre><code>let usersRef = myRootRef.child(byAppendingPath: &#34;users&#34;)

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

    if ( snapshot!.value is NSNull ) {
      print(&#34;not found&#34;)
   } 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!
          let amount = dict[&#34;booking_amount&#34;]

          print(amount!)
      }      
      }
    }
})
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 如何更深入地阅读 Firebase Swift 3 快照?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/41212468/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/41212468/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 如何更深入地阅读 Firebase Swift 3 快照?