Python SDK and Android SDK have different start_at filtering methods
I am using Firebase for a project of mine. In Android I can do a query like this:
mDatabase.child(dbRoot).child("Order").orderByChild("user_id").startAt(user.getUid(), "the order id to start from").endAt(user.getUid()).limitToFirst(15)
In "Order" object, I keep all orders made from all users. The Query gives a user's orders with pagination (it brings them in groups of 15). The problem is that in Python SDK the start_at function doesn't support the second input of starting node, and there is no way to make a similar query as far as I can tell
I found a few problems with this issue:
- I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.
- This issue does not seem to follow the issue template. Make sure you provide all the required information.
I'm not sure if the underlying REST API supports that style of queries: https://firebase.google.com/docs/database/rest/retrieve-data
@yuchenshi do you know?
Note that the given Query works exactly as explained in Android SDK, and I hope for Python SDK to make it work as also
I tried to reverse engineer the code and stumbled upon the spec params that each SDK sends to decide how to filter the data.
Android spec:
{ "vf":"l", "i":"user_id", "sn":"-MMHKiXeYhzZVSc-ryDP","ep":"OiesWhnrJqaiX7ScUoMDvpE8aSq2","l":1,"sp":"OiesWhnrJqaiX7ScUoMDvpE8aSq2"}
Python spec:
{'endAt': '"OiesWhnrJqaiX7ScUoMDvpE8aSq2"', 'limitToFirst': 1, 'orderBy': '"user_id"', 'startAt': '"OiesWhnrJqaiX7ScUoMDvpE8aSq2"'}
It seems like both SDKs use the same pattern, where sp = startAt ep = endAt i = orderBy l = limitToFirst
What seems to do the trick is the "sn" parameter, which is missing in Python SDK
@hiranya911 I don't work on RTDB any more, but I've got some help from @puf who figured it out:
Basically you can pass the starting node in startAt using the format "value","key", like https://stackoverflow.firebaseio.com/64961237.json?orderBy="vendor"&startAt="a","1"
In Python code, that is: params["startAt"] = valueAsJson + ',"' + key + '"'. Hope that helps.
Yep seems to be working just fine. I monkey patched it in any case someone has the same issue as me.
def custom_start_at(self, start, key=None):
if start is None:
raise ValueError('Start value must not be None.')
if key != None:
self._params['startAt'] = json.dumps(start) + ',"' + key + '"'
else:
self._params['startAt'] = json.dumps(start)
return self
db.Query.start_at = custom_start_at
@ETsagkaris Would you consider opening a PR against this repository with your patch? That would help more folks in need and you may be able to remove the monkey-patch in the long run.