Hello there,
Background
We are developing a multi user application and use Firestore from Firebase as our database. We have developed a quite extensive Server and Client Side wrapper for Python now and they work fine. (We essentially eliminated any loading time by that)
However we now wanted to switch “keep server running” on, but our current implementation does not allow that.
Current Implementation (What we have tried)
- In short, each user has its own collection in the database
- When the server starts we store the reference to the collection on a global variable.
- Each method then uses this reference to access the database
Why it failed:
- We have had cases where the user got data from another user when “keep server running” was activated.
(Which is fatal in our case) I guess because the global variables are truly global
Questions :
- If we stored the database reference in the Session – would this ensure that each user can only access his part of the database?
- Does anyone have experience with “keep server running”?
Any advice is greatly appreciated!
Mark
My apps are all running with “keep server running” and never use global variables.
One solution could be to make your global variable a dictionary that uses the user’s email or the session id as a key to get the user’s globals. I have never used this solution, I don’t use global variables.
A better approach is to use an Anvil table rather than a global dictionary to store user data. You could create a Globals
class that uses the Anvil user as a key to get a row from a table, then pass it around. The “pass it around” part could be a little annoying, but when you get used to it, it doesn’t hurt much. And it’s the right thing to do. Usually I pass it to the constructor of each class, so each object has access to all the globals without passing them to each method.
The table could be as simple as a 2 columns, one with the user and one with a Simple Object with all the info you need. Or you could even add one Simple Object column to the user table itself.
3 Likes
Hi @stefano.menci,
thank you very much for your experiences!
I’m looking into your implementation and try to rebuild some parts of the code👍
The current way I’m testing right now it is using Anvil Docs | Sessions and Cookies the session object where I store a reference to the users part of the database.
Greetings,
Mark
For transient (per-session) per-user data, I usually “file” a session entry in a user-specific dict
. This is probably overkill for a transient server instance, but if I ever decide to make it a persistent instance, then separation of per-user data is already accomplished.
@p.colbert,
thank you for your response, that does sound interesting!
Are you able to briefly demonstrate how how you implemented your solution?
Thank you in advance,
Mark
The code is likely proprietary, but the basic ideas are as follows:
-
anvil.server.session
is effectively a server-side dict
that lives as long as the browser’s connection (or longer, for a persistent server).
- A
dict
can use a database row, e.g., the result from anvil.users.get_user()
, as a key. That is, you can, using standard Python features, see whether the current (calling) user has an entry in the session.
- The value at that key can itself be a
dict
. Thus, you can “file” many distinct details under that user’s key.
I’d be inclined to wrap those tests and code in a few well-written functions, so that the caller need only be concerned about “setting” and “getting” named values for the (implicit) “current” user.