2017-08-01 90 views
1

我正在開發一個應用程序,如出租車預訂和在Firebase上存儲數據。如何在Swift中的Firebase查詢中應用多個過濾器?

但是,在從Firebase查詢RideDetail(History)的數據時,我面臨問題。

我想爲分頁形式的特定「customer_id」獲取ride_detail。

我的火力地堡數據結構:

{ 
    "ride_details": { 
    "NuEoP2WNPwigsbY1FQy9M150131918189233": { 
     "customer_id": "tstebwLlf4OCRdWhNKO9XCO08xY2", 
     "destination_address": "New Ranip\nNew Ranip\nAhmedabad\nGujarat 380081\nIndia", 
     "destination_lang": 72.55924470000001, 
     "destination_latg": 23.0930152, 
     "discount": "10%", 
     "driver_id": "cIyZQIJ7tsdvF1a9KpRrKucF2o62", 
     "drop_time": "2017-07-29 09:12:21 +0000", 
     "fare": "13.16 Rs.", 
     "payment_time": 150149034812771, 
     "pickup_time": "2017-07-29 09:10:38 +0000", 
     "priceperkm": "10.00 Rs.", 
     "ride_confirm_time": "2017-07-29 09:06:21 +0000", 
     "source_address": "Vastrapur\nVastrapur\nAhmedabad\nGujarat\nIndia", 
     "source_lang": 72.5293244, 
     "source_latg": 23.0350073, 
     "tax": "10%" 
    }, 
    "RH0oZ0Ypbkur3wJM3HMvM150147833457957": { 
     "customer_id": "aYQFbwLlf4OCRdWhNKO9XCO08xY2", 
     "destination_address": "Sarovar Park Plaza Hotels and Resorts Private Limted\nNo 1\nSector 10\nCBD Belapur\nWadala West\nWadala\nMumbai\nMaharashtra 400614\nIndia", 
     "destination_lang": 72.8561644, 
     "destination_latg": 19.0176147, 
     "discount": 0, 
     "driver_id": "cIyZQIJ7tsdvF1a9KpRrKucF2o62", 
     "drop_time": "", 
     "fare": 0, 
     "payment_time": 150149034812772, 
     "pickup_time": "", 
     "priceperkm": 0, 
     "ride_confirm_time": "2017-07-31 05:18:54 +0000", 
     "source_address": "Smokin Joe's Fresh Pizza\nShop No. 2\n3\nGround Floor\nAbhiman II\nWadala West\nThane West\nMumbai\nMaharashtra 400602\nIndia", 
     "source_lang": 72.8561644, 
     "source_latg": 19.0176147, 
     "tax": 0 
    } 
    } 
} 

這裏的 「payment_time」 是時間戳時支付完成的。

而且我想要的響應有點像:

{ 
    "RH0oZ0Ypbkur3wJM3HMvM150147833457957": { 
     "customer_id": "aYQFbwLlf4OCRdWhNKO9XCO08xY2", 
     "destination_address": "Sarovar Park Plaza Hotels and Resorts Private Limted\nNo 1\nSector 10\nCBD Belapur\nWadala West\nWadala\nMumbai\nMaharashtra 400614\nIndia", 
     "destination_lang": 72.8561644, 
     "destination_latg": 19.0176147, 
     "discount": 0, 
     "driver_id": "cIyZQIJ7tsdvF1a9KpRrKucF2o62", 
     "drop_time": "", 
     "fare": 0, 
     "payment_type": 150149034812772, 
     "pickup_time": "", 
     "priceperkm": 0, 
     "ride_confirm_time": "2017-07-31 05:18:54 +0000", 
     "source_address": "Smokin Joe's Fresh Pizza\nShop No. 2\n3\nGround Floor\nAbhiman II\nWadala West\nThane West\nMumbai\nMaharashtra 400602\nIndia", 
     "source_lang": 72.8561644, 
     "source_latg": 19.0176147, 
     "tax": 0 
    }, 
    "1trcf0Ypbkur3wJM3HMvM150147833457957": { 
     "customer_id": "aYQFbwLlf4OCRdWhNKO9XCO08xY2", 
     "destination_address": "Sarovar Park Plaza Hotels and Resorts Private Limted\nNo 1\nSector 10\nCBD Belapur\nWadala West\nWadala\nMumbai\nMaharashtra 400614\nIndia", 
     "destination_lang": 72.8561644, 
     "destination_latg": 19.0176147, 
     "discount": 0, 
     "driver_id": "cIyZQIJ7tsdvF1a9KpRrKucF2o62", 
     "drop_time": "", 
     "fare": 0, 
     "payment_type": 150149034812778, 
     "pickup_time": "", 
     "priceperkm": 0, 
     "ride_confirm_time": "2017-07-31 05:18:54 +0000", 
     "source_address": "Smokin Joe's Fresh Pizza\nShop No. 2\n3\nGround Floor\nAbhiman II\nWadala West\nThane West\nMumbai\nMaharashtra 400602\nIndia", 
     "source_lang": 72.8561644, 
     "source_latg": 19.0176147, 
     "tax": 0 
    } 
} 

我想第一個10條具體的「CUSTOMER_ID」我通過查詢orderedBy「payment_time」。我也想做同樣的分頁。即在第二個查詢調用中,它必須返回11-20條記錄等等。

+0

請將您的firebase結構作爲文本發佈,而不是圖片。圖像不可搜索,如果我們需要在答案中使用它,必須重新輸入。你能澄清你的查詢嗎?你的預期結果是什麼? – Jay

+0

@Jay請再次檢查我已編輯的問題。 – DJ1

+0

這個問題還不清楚;是您希望特定客戶擁有特定付款類型的X個記錄的數據集?如果這是正確的,那麼您的'我想要的'響應不匹配,因爲它是同一個客戶的兩種不同的付款類型。也許這是別的嗎? * OrderBy「payment_time」和「customer_id」等於「value」。*不清楚。您是否希望按pay_type排序返回的值,並且要返回的值是customer_id = value? – Jay

回答

1

問題和意見有一些不同的標準,但讓我以高級別解決它;

第一個答案是:Firebase不能被查詢一個孩子的價值,然後被另一個孩子訂購。

簡單的查詢功能表達了:

let query = ridesRef.queryOrdered(byChild: "cust_id").queryEqual(toValue: "cust id 4") 

爲了完成這個任務,查詢你想要的子數據,在這種情況下,所有的客戶ID 4個節點,然後順序碼。這裏有一個例子

class RideClass { 
    var key = "" 
    var cust_id = "" 
    var pay_time = "" 

    init(key: String, cust_id: String, pay_time: String) { 
     self.key = key 
     self.cust_id = cust_id 
     self.pay_time = pay_time 
    } 
} 

var rideArray = [RideClass]() 

func populateRideArray() { 
    let usersRef = self.ref.child("ride_details") 
    let query = usersRef.queryOrdered(byChild: "cust_id").queryEqual(toValue: "cust id 4") 
    query.observeSingleEvent(of: .value, with: { snapshot in 
     for child in snapshot.children { 
      let snap = child as! DataSnapshot 
      let dict = snap.value as! [String: Any] 
      let key = snap.key 
      let custId = dict["cust_id"] as! String 
      let payTime = dict["pay_time"] as! String 
      let ride = RideClass(key: key, cust_id: custId, pay_time: payTime) 
      self.rideArray.append(ride) 
     } 

     for ride in self.rideArray { //unsorted example 
      print(ride.pay_time) 
     } 

     self.rideArray.sort { $0.pay_time < $1.pay_time } //sort 

     for ride in self.rideArray { //sorted example 
      print(ride.pay_time) 
     } 
    }) 
} 

在這個例子中,我們創建了一個RideClass存儲關於乘坐一些信息,然後它可以作爲一個數據源的tableView乘坐的數組。

然後查詢所有用於cust id 4的遊樂設施。我們有一個循環來顯示什麼retreived無序,然後這個小寶石

self.rideArray.sort { $0.pay_time < $1.pay_time } 

這種種到位乘坐陣列由pay_time,它回答了這個問題。

假設儘管有100,000個騎乘子節點。加載所有這些數據並在代碼中進行排序可能會使記憶更具挑戰性。你是做什麼?

我們利用複合值;以及cust_id和pay_time的子節點,我們還包含id_time。這裏是一個可能的結構:

"ride_details" : { 
    "ride_0" : { 
     "cust_id" : "cust id 4", 
     "id_time" : "cust id 4_172200", 
     "pay_time" : "172200" 
    }, 
    "ride_1" : { 
     "cust_id" : "cust id 2", 
     "id_time" : "cust id 2_165500", 
     "pay_time" : "165500" 
    }, 
    "ride_2" : { 
     "cust_id" : "cust id 1", 
     "id_time" : "cust id 1_182300", 
     "pay_time" : "182300" 
    }, 
    "ride_3" : { 
     "cust_id" : "cust id 3", 
     "id_time" : "cust id 3_131800", 
     "pay_time" : "131800" 
    }, 
    "ride_4" : { 
     "cust_id" : "cust id 4", 
     "id_time" : "cust id 4_132200", 
     "pay_time" : "132200" 
    } 
    }, 

,然後一些代碼在卡斯特ID讀取4個節點按照正確的順序

let ridesRef = self.ref.child("ride_details") 
    let query = ridesRef.queryOrdered(byChild: "id_time") 
         .queryStarting(atValue: "cust id 4_") 
         .queryEnding(atValue: "cust id 4_\\uf8ff") 
    query.observeSingleEvent(of: .value, with: { snapshot in 
     for child in snapshot.children { 
      let snap = child as! DataSnapshot 
      let dict = snap.value as! [String: Any] 
      let key = snap.key 
      let custId = dict["cust_id"] as! String 
      let payTime = dict["pay_time"] as! String 
      let ride = RideClass(key: key, cust_id: custId, pay_time: payTime) 
      self.rideArray.append(ride) 
     } 

     for ride in self.rideArray { //unsorted example 
      print(ride.pay_time) 
     } 
    }) 

有兩點需要注意:

快照必須遍歷維護子序列

「\ uf8ff」是Unicode中非常高代碼級的字符 - 因爲它包含所有前面的字符。

+0

謝謝。您的解決方案適用於我。非常感謝您的幫助。 – DJ1

0

有兩種可能對你的要求工作的基本方法:

  1. 構造查詢,通過payment_time訂單,限制爲僅包含前10條記錄,然後持有到10日記錄,以便參考您可以使用queryStartingAtValue過濾器進行後續分頁呼叫。

  2. 使用數據庫觸發器設置Firebase雲端函數,並監聽payment_time節點,這樣每當您用數據庫中的某個值更新空數據庫時,就會轉換數據以便它以這種方式進行組織在這裏消費滿足您的需求微不足道。例如 - 我將以如下方式組織新數據:customer_ride_details/{{customer_id}}/{{ride_id}}。並且,由於您在使用時間戳替換payment_time空字符串時觸發了該功能。鑰匙應該已經訂購,供您消費。您仍然需要像處理選項1一樣管理分頁。

+0

您能否詳細解釋結構或查詢。 – DJ1

相關問題