Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python SDK and Android SDK have different start_at filtering methods #502

Open
ETsagkaris opened this issue Nov 23, 2020 · 7 comments · May be fixed by #504
Open

Python SDK and Android SDK have different start_at filtering methods #502

ETsagkaris opened this issue Nov 23, 2020 · 7 comments · May be fixed by #504
Assignees

Comments

@ETsagkaris
Copy link

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

@google-oss-bot
Copy link

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.

@hiranya911
Copy link
Contributor

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?

@ETsagkaris
Copy link
Author

Note that the given Query works exactly as explained in Android SDK, and I hope for Python SDK to make it work as also

@ETsagkaris
Copy link
Author

ETsagkaris commented Nov 23, 2020

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

@yuchenshi
Copy link
Member

@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.

@yuchenshi yuchenshi assigned hiranya911 and unassigned yuchenshi Nov 25, 2020
@ETsagkaris
Copy link
Author

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

@yuchenshi
Copy link
Member

@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.

@ETsagkaris ETsagkaris linked a pull request Nov 26, 2020 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants