ForyszeP
ForyszeP

Reputation: 163

Pyrebase stream. Retrived data access

I'm trying to use stream on my pyrebase but it seems the only thing I can do with retrived data is to print them on the console. I need to update a global table or pass these data to other functions but when I try to call other function or instantiate variable pycharm says's "unresolved refrence". Is there a way to use the stream to update variables, tables etc? Below you will find the function I use:

 def requestHandler(message):

    print("message type", type(message))
    print("message", message)
    print("event",message["event"])  # put
    print("path", message["path"])  # /-K7yGTTEp7O549EzTYtI
    print("data", message["data"])  # {'title': 'Pyrebase', "body": "etc..."}


requests_tab = db.child("Data")).stream(requestHandler)

And below you will find what it prints:

message type <class 'dict'>
message {'path': '/', 'data': {'start': '', 'site': '', 'end': '', 'km': '', 'task': '', 'action': '', 'date': '23.02.2019'}, 'event': 'put'}
event put
path /
data {'start': '', 'site': '', 'end': '', 'km': '', 'task': '', 'action': '', 'date': '23.02.2019'}

It seems to work fine but can I use use strem to something else than just print?


I've printed types of variables before stream and after and before any changes happend to the stream.

def printRequestTab(self):
    print("request_tab_type_stream - ", type(self.requests_tab))
    print("request_tab_stream - ", self.requests_tab)

def requestHandler(message):
    pass

requests_tab = db.child("Branch")).stream(requestHandler)

print("request_tab_type - ", type(requests_tab))
print("request_tab - ",requests_tab)
print('printRequestTab', printRequestTab)

And that's the resoults before changes:

request_tab_type -  <class 'pyrebase.pyrebase.Stream'>
request_tab -  <pyrebase.pyrebase.Stream object at 0x02654F90>
printRequestTab <function RequestScreen.printRequestTab at 0x04B3E7C8>

And after I call the printRequestTab - requests_tab became empty.

request_tab_type_stream -  <class 'kivy.properties.ObservableList'>
request_tab_stream -  []

I give up now. Really need some help.

Upvotes: 0

Views: 1942

Answers (1)

kuza
kuza

Reputation: 3031

Sure you can use stream handler for anything. Just remember that you pass a callback to Pyrebase and it will be triggered by the Pyrebase when it detects a change on the registered path.

I am sorry but your code snippet is unclear or is not complete.

Try example below, adapt it for your needs:

class MyStuffTracker(object):
    """Tracks changes of my stuff in Firebase"""
    _db = pyrebase.initialize_app({
        "apiKey": "YOUR-apiKey",
        "authDomain": "YOUR-authDomain",
        "databaseURL": "YOUR-databaseURL",
        "storageBucket": "YOUR-storageBucket",
        "serviceAccount": "YOUR-serviceAccount",
    }).database()

    my_stuff: List[dict] = None  # In my example my data is a list of some dictionaries

    @property
    def is_ready(self) -> bool:
        """
        Returns:
            bool: True if my stuff is ready for use
        """
        return self.my_stuff is not None

    def stream_handler(self, message):
        print("Got some update from the Firebase")
        # We only care if something changed
        if message["event"] in ("put", "patch"):
            print("Something changed")
            if message["path"] == "/":
                print("Seems like a fresh data or everything have changed, just grab it!")
                self.my_stuff: List[dict] = message["data"]
            else:
                print("Something updated somewhere, I dont't care I just want the latest snapshot of my stuff")
                # Just get whole-data of my stuff and list (second) item of the pyres (that I expect to be a dict)
                self.my_stuff: List[dict] = list(it.item[1] for it in self._db.child("my_stuff").get().pyres)

    def __init__(self) -> None:
        """Start tracking my stuff changes in Firebase"""
        super().__init__()
        self._db.child("my_stuff").stream(self.stream_handler)


tracker = MyStuffTracker()

while not tracker.is_ready:
    pass  # Just wait until the first snapshot of my stuff will be ready

print(f"My stuff is: {tracker.my_stuff}")

In this example MyStuffTracker have a private _db an initialized Firebase DB a method stream_handler that just stores fresh data or pull it again if some nested changes occurred inside the data and a primitive example on how to start and use it after the first snapshot of your data becomes available (to avoid accessing it before it is initialized.)

Hope it works for you.

Upvotes: 2

Related Questions