ios - Pagination in firebase with identical child values -
my data structure follows:
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
i want user able search car, evo, , display results of users own particular cars. need paginate these results app. problem can't figure out how query this. here have far.
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 { // start next query? let ref = user_ref.queryorder(bychild: "carmodel").querystarting(atvalue: self.carcurrentvalue) } }
i have order query carmodel, in order group of users particular car type in snapshot. since car models same value, cannot figure out start or end next query pagination. using reference have in else block starts query @ same place block above. or advice appreciated.
i considered doing fan out, , making separate structure car types. difficult though.
for both startat() , endat(), can pass second value, childkey
shown here.
so query this:
let ref = user_ref.queryordered(bychild: "carmodel").querystarting(atvalue: self.carcurrentvalue, childkey: self.carcurrentkey).querylimited(tofirst: 3+1)
note used tofirst: 3+1
. that's because, annoyingly, startat() inclusive , there's no way skip first record. so, since started last record retrieved on previous page, want query 1 record , discard first result.
here's more complete example in javascript. not familiar enough translate swift, should give algorithm in completion.
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 ) { // previous page has been loaded next 1 using previous value/key // have start current cursor add 1 page size ref = ref.startat(this.lastvalue, this.lastkey).limittofirst(this.pagesize+1); } else { // first page ref = ref.limittofirst(this.pagesize); } return ref.once('value').then(snap => { const keys = []; const data = []; // store data in array it's ordered snap.foreach(ss => { data.push(ss.val()); keys.push(ss.key); }); if( this.lastvalue !== null ) { // skip first value, cursor keys.shift(); data.shift(); } // store last loaded record if( data.length ) { const last = data.length - 1; this.lastkey = keys[last]; this.lastvalue = data[last].author; } return data; }); } }
keep in mind realtime data stream. pagination tricky. it's easier infinite scroll try , maintain realistic cursor on moving data set (records can reorder when data changes, deleted, added in middle, etc).
Comments
Post a Comment