title: How to detect realtime listener errors in firebase firestore database?
body: <p>Firestore <a href="https://firebase.google.com/docs/firestore/query-data/listen" rel="nofollow noreferrer">listeners</a> will randomly close after some length of time (possibly due to inactivity), and in python there is no easy way of catching the errors they throw because they throw them in a separate thread. For my case, I want to maintain a long lasting listener that never closes due to inactivity or server side error.</p>
  
  <p>I've tried wrapping everything in a try - except, and then wrapping that all in the while(True) loop, but that doesn't catch the error because the error is thrown in a separate thread. </p>
  
  <p>The error occurs after 10 minutes - 24 hours of inactivity (I'm not sure inactivity is the case, it could be random, but the shortest interval I ever found was 10 minutes after starting it) on both Linux and windows devices. I haven't tried Mac or any other devices, but I doubt it's device specific.</p>
  
  <p>Looking at gRPC (the thing listeners use to communicate between client and server) spec, there is no default timeout for the python api (and a timeout wouldn't explain why it disconnects after different amounts of time), and no timeout it set anywhere in Firestores listener code.</p>
  
  <p>The specific error that occurs is:</p>
  
  <p>google.api_core.exceptions.InternalServerError: 500 Received RST_STREAM with error code 0</p>
  
  <p>and sometimes </p>
  
  <p>google.api_core.exceptions.InternalServerError: 500 Received RST_STREAM with error code 2</p>
  
  <p>Minimal code to show the problem (left running on a dummy collection called info that only has one document in it for a while):</p>
  
  <pre><code>class TestWatchInfo():
    def __init__(self):
      self.query_watch = db.collection(u'info').on_snapshot(self.on_snapshot)
  
    def on_snapshot(self, col_snapshot, changes, read_time):
      try:
        for change in changes:
          pass
      except Exception as err:
        print(err)
        print("Error occurred at " + str(time.ctime()))
        traceback.print_exc()
  
  if __name__ == '__main__':
    try:
      test_object = TestWatchInfo()
      while(True):
        time.sleep(60)
    except Exception as err:
      print(err)
      print("Error occurred at " + str(time.ctime()))
      traceback.print_exc()
  </code></pre>
  
  <p>Ideally, I would be able to catch the actual error that occurs in the main python thread, but as far as I can tell since I am not the one spawning the threads I have no way of adding thread/gRPC specific code to catch that error. Alternatively, I would like to be able to auto-restart the gRPC connection after it gets closed due to the server side.</p>
  
  <p>In actuality, the Firestore listener just raises an error in the thread it created and closes the listener.</p>