如何在 Swift 的 Firebase 查询中应用多个过滤器? [英] How to apply multiple filter in Firebase query in Swift?

查看:18
本文介绍了如何在 Swift 的 Firebase 查询中应用多个过滤器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试开发一个应用程序,如出租车预订和在 Firebase 上存储数据.

I am trying developing an application like Taxi booking and storing data on Firebase.

但是,我在从 Firebase 查询 RideDetail(History) 数据时遇到了问题.

But, I am facing problem while querying data for RideDetail(History) from Firebase.

我想以分页形式获取特定customer_id"的ride_detail.

I want to fetch ride_detail for specific "customer_id" in pagination form.

我的 Firebase 数据结构:

My Firebase DataStructure:

{
  "ride_details": {
    "NuEoP2WNPwigsbY1FQy9M150131918189233": {
      "customer_id": "tstebwLlf4OCRdWhNKO9XCO08xY2",
      "destination_address": "New Ranip
New Ranip
Ahmedabad
Gujarat 380081
India",
      "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
Vastrapur
Ahmedabad
Gujarat
India",
      "source_lang": 72.5293244,
      "source_latg": 23.0350073,
      "tax": "10%"
    },
    "RH0oZ0Ypbkur3wJM3HMvM150147833457957": {
      "customer_id": "aYQFbwLlf4OCRdWhNKO9XCO08xY2",
      "destination_address": "Sarovar Park Plaza Hotels and Resorts Private Limted
No 1
Sector 10
CBD Belapur
Wadala West
Wadala
Mumbai
Maharashtra 400614
India",
      "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
Shop No. 2
3
Ground Floor
Abhiman II
Wadala West
Thane West
Mumbai
Maharashtra 400602
India",
      "source_lang": 72.8561644,
      "source_latg": 19.0176147,
      "tax": 0
    }
  }
}

这里的payment_time"是支付完成时的时间戳.

Here "payment_time" is timestamp when payment done.

我想要的回应是:

{
    "RH0oZ0Ypbkur3wJM3HMvM150147833457957": {
      "customer_id": "aYQFbwLlf4OCRdWhNKO9XCO08xY2",
      "destination_address": "Sarovar Park Plaza Hotels and Resorts Private Limted
No 1
Sector 10
CBD Belapur
Wadala West
Wadala
Mumbai
Maharashtra 400614
India",
      "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
Shop No. 2
3
Ground Floor
Abhiman II
Wadala West
Thane West
Mumbai
Maharashtra 400602
India",
      "source_lang": 72.8561644,
      "source_latg": 19.0176147,
      "tax": 0
    },
    "1trcf0Ypbkur3wJM3HMvM150147833457957": {
      "customer_id": "aYQFbwLlf4OCRdWhNKO9XCO08xY2",
      "destination_address": "Sarovar Park Plaza Hotels and Resorts Private Limted
No 1
Sector 10
CBD Belapur
Wadala West
Wadala
Mumbai
Maharashtra 400614
India",
      "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
Shop No. 2
3
Ground Floor
Abhiman II
Wadala West
Thane West
Mumbai
Maharashtra 400602
India",
      "source_lang": 72.8561644,
      "source_latg": 19.0176147,
      "tax": 0
    } 
}

我想要在查询orderedBypayment_time"中传递的特定customer_id"的前10条记录.我也想做同样的分页.即在第二次查询调用中,它必须返回 11-20 条记录,依此类推.

I want first 10 records for specific "customer_id" that I pass in query orderedBy "payment_time". Also I want to do pagination for the same. i.e. in second query call, it must return 11-20 records and so on.

推荐答案

问题和评论有一些不同的标准,但让我在高层次上解决它;

The question and comments have some different criteria but let me address it at a high level;

第一个答案是:Firebase 不能先查询一个孩子的值,然后再按另一个孩子排序.

The first answer is: Firebase cannot be queried for the value of one child and then ordered by another.

简单查询函数表示:

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

要完成该任务,请查询您想要的子数据,在本例中为所有客户 ID 为 4 的节点,然后在代码中进行排序.举个例子

To accomplish that task, query for the child data you want, in this case all customer id 4 nodes, and then order in code. Here's an example

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 数据源的骑行数组.

In this example, we create a RideClass which stores some info about the ride, and then an array of rides which could be used as a tableView dataSource.

然后查询所有属于 cust id 4 的游乐设施.我们有一个循环来显示未排序的检索内容,然后是这个小宝石

Then query for all rides that are for cust id 4. We have a loop to show what was retreived unsorted and then this little gem

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

按pay_time 对ride 数组进行排序,从而回答问题.

which sorts the ride array in place by pay_time, which answers the question.

不过,假设有 100,000 个乘坐子节点.加载所有这些数据并在代码中排序可能会在内存方面具有挑战性.你是做什么的?

Suppose though, there are 100,000 ride child nodes. Loading in all of that data and sorting in code could be challenging memory wise. What do you do?

我们利用复合价值;除了 cust_id 和 pay_time 的子节点,我们还包括 id_time.这是一个可能的结构:

We leverage a compound value; along with the child nodes of cust_id and pay_time, we also include id_time. Here's a possible structure:

  "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"
    }
  },

然后一些代码以正确的顺序读入 cust id 4 个节点

and then some code to read in the cust id 4 nodes in the correct order

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

注意两点:

必须迭代快照以维护子序列

The snapshot must be iterated over to maintain the child sequence

"uf8ff" 是 Unicode 中处于非常高代码级别的字符 - 因为它包含所有前面的字符.

"uf8ff" is a character at a very high code level in Unicode - because of that it encompasses all of the preceeding characters.

这篇关于如何在 Swift 的 Firebase 查询中应用多个过滤器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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