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

Calls to firebase_auth.get_user() can add 100-200ms to request time #28

Open
keeth opened this issue Mar 19, 2021 · 5 comments
Open

Calls to firebase_auth.get_user() can add 100-200ms to request time #28

keeth opened this issue Mar 19, 2021 · 5 comments
Assignees
Labels
enhancement New feature or request question Further information is requested

Comments

@keeth
Copy link

keeth commented Mar 19, 2021

Hi,

Just reviewing my web API performance and found high latency whenever firebase_auth.get_user() is called, since it sends a blocking HTTP request to the Firebase Auth API.

I've read a few different Python Firebase Auth tutorials and they all just use the decoded JWT to supply user data, they do not make a call out to the Firebase web API. This makes sense since a synchronous HTTP call is bad for performance.

If FIREBASE_CHECK_JWT_REVOKED is enabled, the get_user() call is made twice per request cycle. One of these calls is surely redundant.

Apart from revocation is there a reason to fetch the user rather than using the properties that are already embedded in the JWT?

Thanks!

@garyburgmann
Copy link
Owner

Hi @keeth ,

I will have to get my head into the context to be able to answer the why properly (and do be honest, remember what I did). I have a couple of weeks off over Easter, will look into it then. Watch this space ;)

Cheers

@garyburgmann garyburgmann self-assigned this Mar 30, 2021
@garyburgmann garyburgmann added enhancement New feature or request question Further information is requested labels Mar 30, 2021
@Longwelwind
Copy link

I've looked a bit into this question, here are the result of my investigation, so that if someone is interested in solving this, s.he can have more info on this. At the moment, when a request is received by Django, FirebaseAuthentication:

  • Decodes the uid out of the JWT token
  • Fetches the Firebase user data based on the uid (including the email)
  • Check if a local user already exists with this email
    • If no, create a local user associated with this mail
  • Return the local user (either fetch or created)

The step in bold includes a request to Firebase.

What it truly should be doing is:

  • Decodes the uid and the email out of the JWT token
  • Check if a local user already exists with this email
    • If no, fetch the Firebase user data, create a local user associated with this mail based on the firebase user data.
  • Return the local user (either fetch or created)

That way, a trip to Firebase is only needed during local user creation. In case the local user creation doesn't require data from the firebase user, a request to Firebase is not even needed.

I'll try to create a PR if I get the time to do this.

@keeth
Copy link
Author

keeth commented May 6, 2021

My solution was to always just use the token. For my purposes it has enough info even for account creation..

    def authenticate_token(self, decoded_token):
        return UserRecord(
            dict(
                localId=decoded_token["uid"],
                display_name=decoded_token.get("name"),
                email=decoded_token.get("email"),
                photo_url=decoded_token.get("picture"),
            )
        )

@Longwelwind
Copy link

Longwelwind commented May 7, 2021

The best would to let it the user choose whether they need to fetch the firebase user. firebase_auth.get_user() could never be called and api_settings.FIREBASE_USERNAME_MAPPING_FUNC(firebase_user) could be changed to only give the decoded_token as parameter. That way, the developer could choose themselves to call firebase_auth.get_user() if they need to.

@garyburgmann
Copy link
Owner

garyburgmann commented May 7, 2021

Hey guys this is still on my radar, just need to find time to get my head into it. Thanks for the feedback so far!

If there is some sort of consensus re: best way forward and I haven't gotten to it yet, feel free to make a pull req.

Have opened a ticket in Trello to track this, feel free to add code snippets/screenshots/more info

https://trello.com/c/RlMcBCmi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants