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

[Bug]: Firebase Realtime Database stream fails when token expires #25

Open
1 task done
dwatrous opened this issue Nov 8, 2023 · 3 comments
Open
1 task done
Labels
bug Something isn't working triage

Comments

@dwatrous
Copy link

dwatrous commented Nov 8, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Environment

-   OS: Windows/Linux
-   Python: 3.10.7

What happened?

When the idtoken expires, I'm required to kill my script and open a start it again to get a new token and create a new stream.

Code Snippet

When I create a stream, I provide it a valid idtoken. This token expires within an hour and needs to be refreshed. Right now my script is failing when this idtoken expires. Here is what I'm doing to create the stream

`self.my_stream = self.db.child("messages").stream(self.message_capture, token=self.idtoken)`

`self.idtoken` is defined in a way that it would always return a fresh token, but I noticed that URL caches the value of the token when the stream is created (https://github.com/AsifArmanRahman/firebase-rest-api/blob/cf2772a6549d47d6d5ee6750e9bb77f5f9c4f679/firebase/database/__init__.py#L583). This means that the stream can only ever live as long as the token it is given.

In the `Stream` class, I see that there is an instance of `KeepAuthSession` that is used to create the `ClosableSSEClient`, but this doesn't appear to be complete, or at least I can't figure out if this is supposed to be a way to refresh the token. It looks different.

Relevant log output

2023-11-08 10:27:36,303 DEBUG _new_conn(973) Starting new HTTPS connection (2): mosquitomax-364012-default-rtdb.firebaseio.com:443
2023-11-08 10:27:37,136 DEBUG _make_request(452) https://mosquitomax-364012-default-rtdb.firebaseio.com:443 "GET /messages.json?auth=eyJhbGciOiJSUzI1NiIsImtpZCI6ImQ0OWU0N2ZiZGQ0ZWUyNDE0Nzk2ZDhlMDhjZWY2YjU1ZDA3MDRlNGQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vbW9zcXVpdG9tYXgtMzY0MDEyIiwiYXVkIjoibW9zcXVpdG9tYXgtMzY0MDEyIiwiYXV0aF90aW1lIjoxNjk5NDU3MjU2LCJ1c2VyX2lkIjoiakxFMk9yUzI0TmVObkFHcXdHMTM5QWZlb0pQMiIsInN1YiI6ImpMRTJPclMyNE5lTm5BR3F3RzEzOUFmZW9KUDIiLCJpYXQiOjE2OTk0NTcyNTYsImV4cCI6MTY5OTQ2MDg1NiwiZW1haWwiOiIwMDAwMDAwMGQyOWY5NmRmQG1vc3F1aXRvbWF4LmNvbSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJlbWFpbCI6WyIwMDAwMDAwMGQyOWY5NmRmQG1vc3F1aXRvbWF4LmNvbSJdfSwic2lnbl9pbl9wcm92aWRlciI6InBhc3N3b3JkIn19.kIvcRCuG0TLu9MwiuR8lF7C7WOI1_jW37gMImoaiLWLyDzG216GKJiNwXvOr0thhTLRRESkQV9GeMiNAutyifZZhUGBG0TcqAx_mmwjENfvzF5NFltzSK6q1AHya1Q3X5xxty2oDCDpY7VZIZl6Z5TZ86y9R95vwTNWf4bbI7IQRsWVDeiioc_ZRRPQCqt4fGsSO0mUfLoQ5LfzdjKjvUJijQGILFlboWpOgjVHsCU9alHuXuRXOb0b5UNS7H1XJun8QQQvaj_BZu92uyCH1_xcrw01Mlw6kagGXX0W3Nw02MG-B3TFqX87lw4hOB-Jm3yIsWwAaC59V_otyhB7KNA HTTP/1.1" 401 21
Exception in thread Thread-4:
Traceback (most recent call last):
  File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.9/threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.9/dist-packages/firebase/database/_stream.py", line 48, in start_stream
    for msg in self.sse:
  File "/usr/local/lib/python3.9/dist-packages/firebase/database/_custom_sse_client.py", line 99, in __next__
    self._connect()
  File "/usr/local/lib/python3.9/dist-packages/firebase/database/_closable_sse_client.py", line 21, in _connect
    super(ClosableSSEClient, self)._connect()
  File "/usr/local/lib/python3.9/dist-packages/firebase/database/_custom_sse_client.py", line 67, in _connect
    self.resp.raise_for_status()
  File "/usr/local/lib/python3.9/dist-packages/requests/models.py", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://mosquitomax-364012-default-rtdb.firebaseio.com/messages.json?auth=eyJhbGciOiJSUzI1NiIsImtpZCI6ImQ0OWU0N2ZiZGQ0ZWUyNDE0Nzk2ZDhlMDhjZWY2YjU1ZDA3MDRlNGQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vbW9zcXVpdG9tYXgtMzY0MDEyIiwiYXVkIjoibW9zcXVpdG9tYXgtMzY0MDEyIiwiYXV0aF90aW1lIjoxNjk5NDU3MjU2LCJ1c2VyX2lkIjoiakxFMk9yUzI0TmVObkFHcXdHMTM5QWZlb0pQMiIsInN1YiI6ImpMRTJPclMyNE5lTm5BR3F3RzEzOUFmZW9KUDIiLCJpYXQiOjE2OTk0NTcyNTYsImV4cCI6MTY5OTQ2MDg1NiwiZW1haWwiOiIwMDAwMDAwMGQyOWY5NmRmQG1vc3F1aXRvbWF4LmNvbSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwiZmlyZWJhc2UiOnsiaWRlbnRpdGllcyI6eyJlbWFpbCI6WyIwMDAwMDAwMGQyOWY5NmRmQG1vc3F1aXRvbWF4LmNvbSJdfSwic2lnbl9pbl9wcm92aWRlciI6InBhc3N3b3JkIn19.kIvcRCuG0TLu9MwiuR8lF7C7WOI1_jW37gMImoaiLWLyDzG216GKJiNwXvOr0thhTLRRESkQV9GeMiNAutyifZZhUGBG0TcqAx_mmwjENfvzF5NFltzSK6q1AHya1Q3X5xxty2oDCDpY7VZIZl6Z5TZ86y9R95vwTNWf4bbI7IQRsWVDeiioc_ZRRPQCqt4fGsSO0mUfLoQ5LfzdjKjvUJijQGILFlboWpOgjVHsCU9alHuXuRXOb0b5UNS7H1XJun8QQQvaj_BZu92uyCH1_xcrw01Mlw6kagGXX0W3Nw02MG-B3TFqX87lw4hOB-Jm3yIsWwAaC59V_otyhB7KNA

Anything else?

2023-11-08 10:27:36,303 DEBUG _new_conn(973) Starting new HTTPS connection (2): myproject-rtdb.firebaseio.com:443
2023-11-08 10:27:37,136 DEBUG _make_request(452) https://myproject-rtdb.firebaseio.com:443 "GET /messages.json?auth=IDTOKEN HTTP/1.1" 401 21
Exception in thread Thread-4:
Traceback (most recent call last):
  File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.9/threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.9/dist-packages/firebase/database/_stream.py", line 48, in start_stream
    for msg in self.sse:
  File "/usr/local/lib/python3.9/dist-packages/firebase/database/_custom_sse_client.py", line 99, in __next__
    self._connect()
  File "/usr/local/lib/python3.9/dist-packages/firebase/database/_closable_sse_client.py", line 21, in _connect
    super(ClosableSSEClient, self)._connect()
  File "/usr/local/lib/python3.9/dist-packages/firebase/database/_custom_sse_client.py", line 67, in _connect
    self.resp.raise_for_status()
  File "/usr/local/lib/python3.9/dist-packages/requests/models.py", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://myproject-rtdb.firebaseio.com/messages.json?auth=IDTOKEN
@dwatrous dwatrous added bug Something isn't working triage labels Nov 8, 2023
@AsifArmanRahman
Copy link
Owner

or at least I can't figure out if this is supposed to be a way to refresh the token

Unfortunately, I'm not sure either. That part of the code was taken from Pyrebase.

@dwatrous
Copy link
Author

dwatrous commented Dec 8, 2023

I ended up moving to https://github.com/JelleZijlstra/aiohttp-sse-client2. That still doesn't support automatic refresh of the token, so I run in a loop that watches for the SSE "auth_revoked" and then I get a fresh token and start a new listener.

@AsifArmanRahman
Copy link
Owner

Maybe in future me or someone from the open source will figure it out. Until then, I'm glad you found a work through for your project and mentioning it here for future solution seekers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triage
Projects
None yet
Development

No branches or pull requests

2 participants