多个Geofire查询和客户端过滤

时间:2017-01-18 14:48:19

标签: ios objective-c firebase firebase-realtime-database geofire

我几天来一直在提到这篇SO帖子: Filtering results with Geofire + Firebase

我的问题是,对于我的iOS应用,我需要制作一份按凭证排序的附近用户的单一列表,例如:高级会员(最高和列表顶部),捐赠者(保费后次高),会员(基本/最低)。

我已在Firebase服务器中为GeoFire位置创建了3个条目,这些条目根据这些凭据拆分用户,因此需要运行3个查询来检索它们。

GeoFire* geoFirePremium = [[GeoFire alloc] initWithFirebaseRef:[[[FIRDatabase database] reference] child:@"geofire-premium-members"]];
GeoFire* geoFireDonator = [[GeoFire alloc] initWithFirebaseRef:[[[FIRDatabase database] reference] child:@"geofire-donator-members"]];
GeoFire* geoFireRegular = [[GeoFire alloc] initWithFirebaseRef:[[[FIRDatabase database] reference] child:@"geofire-regular-members"]];
NSMutableDictionary* query1Items = [[NSMutableDictionary alloc] init];
NSMutableDictionary* query2Items = [[NSMutableDictionary alloc] init];
NSMutableDictionary* query3Items = [[NSMutableDictionary alloc] init];

CLLocation* coord = [[CLLocation alloc] initWithLatitude:34.2499 longitude:-85.4399]; // Test location
long searchDistance = 8;
float mile2Kilo = 1.60934;
float kilo2mile = 0.62137;
GFCircleQuery* query1 = [geoFirePremium queryAtLocation:coord withRadius:(CGFloat)(searchDistance * mile2Kilo)]; // Miles to Kilometers
[query1 observeEventType:GFEventTypeKeyEntered withBlock:^(NSString* key, CLLocation* location)
{
    // Store results in query1Items
}];
GFCircleQuery* query2 = [geoFireDonator queryAtLocation:coord withRadius:(CGFloat)(searchDistance * mile2Kilo)];
[query2 observeEventType:GFEventTypeKeyEntered withBlock:^(NSString* key, CLLocation* location)
{
    // Store results in query2Items
}];
GFCircleQuery* query3 = [geoFireRegular queryAtLocation:coord withRadius:(CGFloat)(searchDistance * mile2Kilo)];
[query3 observeEventType:GFEventTypeKeyEntered withBlock:^(NSString* key, CLLocation* location)
{
    // Store results in query3Items
}];

我的想法是添加一些代码,用于识别所有3个查询何时完成,然后将它们合并到1个列表中。

NSMutableDictionary* mergedItems = [[NSMutableDictionary alloc] init];
// For example:  { query1Items[], query2Items[], query3Items[], ... }

[query1 observeReadyWithBlock:^{
    NSLog(@"Query 1 is finished");
    // Check for queries 2 & 3 completion
    // Perform merge if all are completed
}];
[query2 observeReadyWithBlock:^{
    NSLog(@"Query 2 is finished");
    // Check for queries 1 & 3 completion
    // Perform merge if all are completed
}];
[query3 observeReadyWithBlock:^{
    NSLog(@"Query 3 is finished");
    // Check for queries 1 & 2 completion
    // Perform merge if all are completed
}];

所有Firebase / GeoFire参考的JSON结构如下:

- geofire-premium-members
    - userid
        - g: geohash
        - l
            - 0: lat
            - 1: lon

- geofire-donator-members   //same format

- geofire-regular-members   //same format

- users
    - userid
        - …

使用像这样的多个查询是一种好方法吗?我可能需要在将来添加更多凭据,并且不知道我的方法是否可以很好地扩展。有没有更好的方法来实现我需要的东西,也许只使用一个查询?我非常感谢任何见解

1 个答案:

答案 0 :(得分:0)

你的概念没有错。它可能过于复杂,因为有三个查询返回相同类型的数据,并在代码中组合数据并执行其他查询以获取其他用户数据。

即。代码中的三个查询返回一堆用户ID,然后您需要对其进行更多查询(例如)查找单个用户名

只要users节点中的所有成员具有相同的结构,您就可以将它们放在一个节点中并使用子属性来指示它们是什么类型的用户

userid_0
    name: "some name"
    user_type: "regular"
userid_1
    name: "another name"
    user_type: "donator"

然后GeoFire查询返回指定半径内的所有用户。

假设用户必须要查找其名称(作为示例),您将在用户节点中拥有其余数据,并且可以简单地读取它们,按user_type(在代码中)排序并显示。

话虽如此,如果您确定如何对它们进行排序,那么对结构进行简单的更改就可以轻松实现。

userid_0
    name: "some premium name"
    user_type: 0
userid_1
    name: "a donator name"
    user_type: 1
user_id_2
    name: "regular name"
    user_type: 2

其中0 =高级用户,1 =捐赠者用户,2是普通用户。

然后在代码中排序时,按user_type排序,溢价将浮动到顶部。