firebase在接收数据时能否自动重新排序数据?
以下是场景: 1) 我有一个移动应用程序,它有两个数据点:位置和主题标题 2) 我将这两点发送给firebase 3) 许多点从不同位置和不同主题的不同设备发送 4) 然后,移动设备请求特定位置的主题标题列表 我的问题是: firebase能否在将集合返回给调用者之前,在数据库中按字母顺序自动重新排列这些主题标题 本质上,我不希望移动设备重新排序任何内容,而只是直接显示数据集中的数据 我想这必须用javascript代码在服务器端完成,我只是不清楚在firebase中到底是如何完成的firebase在接收数据时能否自动重新排序数据?,firebase,Firebase,以下是场景: 1) 我有一个移动应用程序,它有两个数据点:位置和主题标题 2) 我将这两点发送给firebase 3) 许多点从不同位置和不同主题的不同设备发送 4) 然后,移动设备请求特定位置的主题标题列表 我的问题是: firebase能否在将集合返回给调用者之前,在数据库中按字母顺序自动重新排列这些主题标题 本质上,我不希望移动设备重新排序任何内容,而只是直接显示数据集中的数据 我想这必须用javascript代码在服务器端完成,我只是不清楚在firebase中到底是如何完成的 提前感谢看
提前感谢看起来您有一个非常好的用例,但我不会尝试为您将其转换为工作应用程序。相反,我将提供一些指向最重要部分的指针,这些部分与Firebase相关 数据结构 假设您将此结构用于您的兴趣点:
locations
-123981234cbdag
title: "White House"
latitude: 38.897676
longitude: -77.036528
-458614tajsla12
title: "Google San Francisco"
latitude: 37.789635
longitude: -122.390375
此代码段中位置的名称/键(“-123981234cbdag”和“-458614tajsla12”)的格式与Firebase在调用其push
方法时生成的格式相同
按特定顺序从Firebase检索数据
Firebase可以按任何顺序为您的应用程序提供位置:
按钮时也是按时间顺序排列的)
//我们调用下面的这个helper函数来打印位置
函数打印快照(位置){
位置。forEach(函数(快照){
console.log(snapshot.val().title);
});
}
var ref=新的Firebase('https://your.firebaseio.com/locations');
//1a。按子项的键顺序提供快照
参考on(“值”,打印快照);
//1b。相同的结果,但按键名称的顺序显式排序
参考('value',printSnapshot)上的orderByKey();
// 2. 按子对象的优先级顺序提供子对象的快照
参考('value',printSnapshot)上的orderByPriority();
//3a。按标题的顺序提供子项的快照
参考('value',printSnapshot)上的orderByChild('title');
//3b。按子对象的纬度顺序提供子对象的快照
参考orderByChild('latitude')。在('value',printSnapshot)上;
//3c。按子对象的经度顺序提供子对象的快照
参考orderByChild('longitude')。在('value',printSnapshot)上;
对数据进行排序后,还可以限制检索的内容
检索较少的可用位置
这段话将直接传回白宫:
ref.orderByChild('title').equalTo('White House').on('value', printSnapshot);
这段代码也将如此:
ref.orderByChild('title').limitToLast(1).on('value', printSnapshot);
但是,一旦您的一个用户访问了,最后一个可能会返回一个不同的位置。另外值得注意的是,最后一个代码段将自动接收可能出现在Firebase中的任何新值,因为Firebase会主动同步适合您查询的数据
因此,流程可能是:
var whereAmI = { latitude: 38.898042, longitude: -77.03326};
如果有人准确地添加了该用户所在的位置,我们可以像以前一样使用equalTo
。但考虑到全球定位系统(GPS)设备的精度参差不齐,这并不十分可靠。因此,我们应该检查附近的位置,以便在一定的纬度/经度范围内
我们可以使用Firebase的startAt
和endAt
方法:
ref
.orderByChild('latitude')
.startAt(whereAmI.latitude - 0.002)
.endAt(whereAmI.latitude + 0.002)
.on('value', printSnapshot);
此代码段将返回位于您所在位置以东或以西几百米范围内的位置,其中。。。猜猜看。。。只是我们样本数据集中的白宫
如果我们加上一个limitToFirst(1)
,它甚至会限制返回的位置的数量。但不幸的是,它会返回最东边的位置,而不一定是离我最近的位置。(我对纬度不太在行,它可能也是最西边的地方)此外,它只适合纬度;您还需要使用经度来查找位于您正北部或南部的位置
理想情况下,您可以在Firebase中执行以下操作:
// !!!THIS IS A NON-WORKING EXAMPLE!!!
ref
.orderByChild('latitude')
.startAt(whereAmI.latitude - 0.002)
.endAt(whereAmI.latitude + 0.002)
.orderByChild('longitude')
.startAt(whereAmI.longitude- 0.002)
.endAt(whereAmI.longitude+ 0.002)
.on('value', printSnapshot);
// !!!THIS IS A NON-WORKING EXAMPLE!!!
但不幸的是,Firebase目前只能对每个查询筛选一个子项。因此,要么我们必须检索整个地球纬度部分中的所有子对象,并在客户端进行过滤,要么我们必须找到一种方法,将纬度和经度填充到一个属性中,该属性还可以维护数字的“它可以很容易地排序”属性
输入“geohashs”和GeoFire
通过Geohash进行过滤(使用Geofire)
如果你去,你会看到一些非常接近你的用例的东西。它显示了在某一地区所有的Muni(旧金山公共交通)线。
手机屏幕截图,因为我在桌面界面上找不到(而且看起来很相似)
如果你等几秒钟(并且在营业时间访问),你甚至会看到车辆四处移动。它们显示的区域是一个圆,所以很明显,无论是谁编写了这个演示,都知道如何查询纬度和经度
他们使用的技巧称为地理哈希,并引用:
它是一种分层的空间数据结构,将空间细分为gr的桶