gpt4 book ai didi

ios - 具有相同子值的 firebase 中的分页

转载 作者:行者123 更新时间:2023-11-28 12:19:39 25 4
gpt4 key购买 nike

我的数据结构如下:

 users: 
user1:
-carModel: evo x
-username: importguy
-region: north east
user2:
-carModel: evo x
-username: evoguy
-region: north east
user3:
-carModel: mustang gt
-username: muscleguy
-region: south east

我希望用户能够搜索汽车,比如 evo,并显示拥有这些特定汽车的用户的结果。我需要为我的应用程序对这些结果进行分页。问题是我不知道如何正确查询这个。这是我到目前为止所拥有的。

  func fetchUsersBy(car: String) {

if self.carCurrentKey == nil {

let ref = USER_REF.queryOrdered(byChild: "carModel").queryStarting(atValue: car).queryLimited(toFirst: 3)

ref.observeSingleEvent(of: .value, with: { (snapshot) in

guard let snap = snapshot.children.allObjects as? [FIRDataSnapshot] else { return }
guard let last = snapshot.children.allObjects.last as? FIRDataSnapshot else { return }

snap.forEach({ (snapshot) in

guard let userDict = snapshot.value as? Dictionary<String, AnyObject> else { return }
guard let carModel = userDict["carModel"] as? String else { return }

if carModel.contains(car) {
print(snapshot)
}
})
self.carCurrentKey = last.key
self.carCurrentValue = last.childSnapshot(forPath: "carModel").value as? String
})
} else {
// where to start next query?
let ref = USER_REF.queryOrder(byChild: "carModel").queryStarting(atValue: self.carCurrentValue)
}
}

我必须按 carModel 对查询进行排序,以便在快照中将具有该特定汽车类型的所有用户分组在一起。由于所有车型的值都相同,所以我不知道从哪里开始或结束下一个分页查询。使用我在 else block 中的引用在与上面的 block 相同的位置开始查询。任何帮助或建议将不胜感激。

我考虑过扇出,并为汽车类型制作一个单独的结构。不过这会很困难。

最佳答案

对于 startAt() 和 endAt(),您可以传递第二个值,childKey,如图所示 here .

所以你的查询看起来像这样:

let ref = USER_REF.queryOrdered(byChild: "carModel").queryStarting(atValue: self.carCurrentValue, childKey: self.carCurrentKey).queryLimited(toFirst: 3+1)

请注意,我使用了 toFirst: 3+1。这是因为,令人讨厌的是,startAt() 是包容性的,并且没有办法跳过第一条记录。因此,由于我们是从上一页中检索到的最后一条记录开始的,因此您需要查询一条额外的记录并丢弃第一条结果。

这是一个更完整的 JavaScript 示例。不够熟悉,无法将其转换为 Swift,但它应该为您提供完整的算法。

class Cursor {
constructor(baseRef, pageSize) {
this.baseRef = baseRef;
this.lastKey = null;
this.lastValue = null;
this.pageSize = pageSize;
}

next() {
let ref = this.baseRef;

if( this.lastValue !== null ) {
// a previous page has been loaded so get the next one using the previous value/key
// we have to start from the current cursor so add one to page size
ref = ref.startAt(this.lastValue, this.lastKey).limitToFirst(this.pageSize+1);
}
else {
// this is the first page
ref = ref.limitToFirst(this.pageSize);
}

return ref.once('value').then(snap => {
const keys = [];
const data = []; // store data in array so it's ordered

snap.forEach(ss => {
data.push(ss.val());
keys.push(ss.key);
});

if( this.lastValue !== null ) {
// skip the first value, which is actually the cursor
keys.shift();
data.shift();
}

// store the last loaded record
if( data.length ) {
const last = data.length - 1;
this.lastKey = keys[last];
this.lastValue = data[last].author;
}

return data;
});
}
}

here's a working fiddle .

请记住,这是实时数据流。所以分页很棘手。通常只做无限滚动比尝试在移动数据集上保持真实的光标更容易(记录可以在数据更改、删除、在中间添加等时重新排序)。

关于ios - 具有相同子值的 firebase 中的分页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45312800/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com