Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/105.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 多个Geofire查询和客户端过滤_Ios_Objective C_Firebase_Firebase Realtime Database_Geofire - Fatal编程技术网

Ios 多个Geofire查询和客户端过滤

Ios 多个Geofire查询和客户端过滤,ios,objective-c,firebase,firebase-realtime-database,geofire,Ios,Objective C,Firebase,Firebase Realtime Database,Geofire,几天来,我一直在引用这篇SO帖子: 我的问题是,对于我的iOS应用程序,我需要列出一个按凭据排序的附近用户的单一列表,例如:高级成员(最高和在列表顶部)、捐赠者(仅次于高级)、成员(基本/最低) 我在Firebase服务器中为GeoFire位置创建了3个条目,这些条目根据这些凭据分割用户,因此需要运行3个查询来检索它们 GeoFire* geoFirePremium = [[GeoFire alloc] initWithFirebaseRef:[[[FIRDatabase database]

几天来,我一直在引用这篇SO帖子:

我的问题是,对于我的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
        - …

使用这样的多个查询是一种好方法吗?我可能需要在将来添加更多凭据,但不知道我的方法是否能够很好地扩展。是否有更好的方法来实现我所需要的,而只使用一个查询?我非常感谢您的见解,您的想法没有任何问题。这可能过于复杂,因为有三个查询返回相同类型的数据,并在代码中组合数据,然后执行其他查询以获取其他用户数据

i、 代码中的三个查询返回一组用户id,然后您需要对这些id进行更多查询(例如)以查找各个用户名

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

userid_0
    name: "some name"
    user_type: "regular"
userid_1
    name: "another name"
    user_type: "donator"
然后执行GeoFire查询以返回指定半径内的所有用户

假设无论如何都必须查找用户的名称(作为示例),那么用户节点中将有剩余的数据,并且可以简单地将其读入、按用户类型(代码中)排序和显示

这就是说,如果您确实知道如何对它们进行排序,那么对结构进行简单的更改将很容易实现这一点

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是普通用户


然后,在代码排序时,按用户类型排序,保费将浮到顶部。

我们大多数人发现解析代码比解析描述代码的单词更容易。如果您对当前代码的结构有顾虑,请共享复制这些顾虑的最小代码。如果您随后还添加了JSON结构的一个片段(作为文本,请不要截图),您就更有可能得到一个有用的答案。@FrankvanPuffelen谢谢,我已经用相关代码进行了更新。我知道这种结构在哪里有用,但在大多数情况下,我至少会返回1000个结果。我想不惜一切代价避免客户端排序。多个查询似乎绕过了这个问题issue@codeflow1000个结果只需要少量数据,因此没有什么大不了的。另外,排序1000个结果不会占用太多的处理能力——也就是说,为什么要在代码中排序?如果您愿意,Firebase在检索数据时可以在查询中为您排序。你想按什么排序?此外,如果您想朝这个方向发展,也可以轻松地在此结构上执行多个查询。其思想是,它是非规范化的、可扩展的和可维护的,并且可以在代码中轻松实现。感谢@Jay,我不知道我可以使用Firebase对GeoFire查询进行排序?我还没有真正看到如何做到这一点。到目前为止,它在代码中还不容易接近,尽管我的数据已经相当非规范化了,但我还是希望say@codeflowGeoFire构建在Firebase上,但它维护自己的神奇数据集,因此它的查询基于特定的结构,因此它与Firebase查询“不同”。更多的数据被添加到你的问题中(谢谢),我一开始读错了,所以修改了我的答案以更好地解决它。谢谢你的建议。由于我最近意识到我的一个节点结构实际上需要与另外两个不同,所以仍然有一些变通方法需要尝试。至少现在我有点方向感了