python firebase realtime listener
Asked Answered
R

6

8

Hi there I'm new in python. I would like to implement the listener on my Firebase DB. When I change one or more parameters on the DB my Python code have to do something. How can I do it? Thank a lot

my db is like simple list of data from 001 to 200:

"remote-controller"
001 -> 000
002 -> 020
003 -> 230

my code is:

from firebase import firebase
firebase = firebase.FirebaseApplication('https://remote-controller.firebaseio.com/', None)
result = firebase.get('003', None)
print result
Rycca answered 16/4, 2018 at 18:9 Comment(0)
S
22

It looks like this is supported now (october 2018): although it's not documented in the 'Retrieving Data' guide, you can find the needed functionality in the API reference. I tested it and it works like this:

def listener(event):
    print(event.event_type)  # can be 'put' or 'patch'
    print(event.path)  # relative to the reference, it seems
    print(event.data)  # new data at /reference/event.path. None if deleted

firebase_admin.db.reference('my/data/path').listen(listener)
Squinch answered 27/10, 2018 at 9:28 Comment(6)
Works great. I noticed however that the first time I run my python script the event gets triggered despite anything having changed. Is there a way to prevent this from happening?Chitter
Didn't notice this when I was experimenting, maybe they changed it or I was just inattentive. In any case, I don't think there's any functionality in the API at this time to prevent the initial call when registering. You should probably try to deal with 'extra' calls like this, since events can be triggered multiple times for the same data anyway, if I'm not mistaken. Alternatively use something like this: pastebin.com/W2diZnCMSquinch
It works, but it has a bug: It also fires every hour and dumps the entire database even when there is no change. causes the cost to go up when your database is big.Mohr
@Mohr As I said before, Firebase expects your code to be robust against superfluous updates like that, if I'm not mistaken.Squinch
@Marein My code can handle duplicates. the problem is that I get charged for the spurious downloaded data. contacted firebase. It's a known issue w/ the python API and no plan to change it.Mohr
Note: According to the documentation linked in this answer , and as of the time of writing, This is an experimental feature.Flamethrower
D
2

Python Firebase Realtime Listener Full Code :

import firebase_admin
from firebase_admin import credentials
from firebase_admin import db

def listener(event):
    print(event.event_type)  # can be 'put' or 'patch'
    print(event.path)  # relative to the reference, it seems
    print(event.data)  # new data at /reference/event.path. None if deleted
    
json_path = r'E:\Projectz\FYP\FreshOnes\Python\PastLocations\fyp-healthapp-project-firebase-adminsdk-40qfo-f8fc938674.json'
my_app_name = 'fyp-healthapp-project'
xyz = {'databaseURL': 'https://{}.firebaseio.com'.format(my_app_name),'storageBucket': '{}.appspot.com'.format(my_app_name)}

cred = credentials.Certificate(json_path)        
obj = firebase_admin.initialize_app(cred,xyz , name=my_app_name)

db.reference('PatientMonitoring', app= obj).listen(listener)

Output:

put
/
{'n0': '40', 'n1': '71'} # for first time its gonna fetch the data from path whether data is changed or not

put # On data changed 
/n1  
725

put # On data changed 
/n0
401
Denominationalism answered 2/12, 2020 at 13:33 Comment(1)
Thank you for posting a complete example showing how all the pieces fit together.Ordinance
G
1

As Peter Haddad suggested, you should use Pyrebase for achieving something like that given that the python SDK still does not support realtime event listeners.

import pyrebase

config = {
    "apiKey": "apiKey",
    "authDomain": "projectId.firebaseapp.com",
    "databaseURL": "https://databaseName.firebaseio.com",
    "storageBucket": "projectId.appspot.com"
}

firebase = pyrebase.initialize_app(config)

db = firebase.database()

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


my_stream = db.child("posts").stream(stream_handler)
Grandfatherly answered 22/7, 2018 at 3:26 Comment(0)
D
1

If Anybody wants to create multiple listener using same listener function and want to get more info about triggered node, One can do like this.

Normal Listener function will get a Event object it has only Data, Node Name, Event type. If you add multiple listener and You want to differentiate between the data change. You can write your own class and add some info to it while creating object.

class ListenerClass:
    def __init__(self, appname):
        self.appname = appname

    def listener(self, event):
        print(event.event_type)  # can be 'put' or 'patch'
        print(event.path)  # relative to the reference, it seems
        print(event.data)  # new data at /reference/event.path. None if deleted
        print(self.appname) # Extra data related to change add your own member variable

Creating Objects:

listenerObject = ListenerClass(my_app_name + '1')
db.reference('PatientMonitoring', app= obj).listen(listenerObject.listener)

listenerObject = ListenerClass(my_app_name + '2')
db.reference('SomeOtherPath', app= obj).listen(listenerObject.listener)

Full Code:

import firebase_admin
from firebase_admin import credentials
from firebase_admin import db

# Initialising Database with credentials
json_path = r'E:\Projectz\FYP\FreshOnes\Python\PastLocations\fyp-healthapp-project-firebase-adminsdk-40qfo-f8fc938674.json'
my_app_name = 'fyp-healthapp-project'
xyz = {'databaseURL': 'https://{}.firebaseio.com'.format(my_app_name),'storageBucket': '{}.appspot.com'.format(my_app_name)}

cred = credentials.Certificate(json_path)        
obj = firebase_admin.initialize_app(cred,xyz , name=my_app_name)

# Create Objects Here, You can use loops and create many listener, But listener will create thread per every listener, Don't create irrelevant listeners. It won't work if you are running on machine with thread constraint

listenerObject = ListenerClass(my_app_name + '1') # Decide your own parameters, How you want to differentiate. Depends on you
db.reference('PatientMonitoring', app= obj).listen(listenerObject.listener)

listenerObject = ListenerClass(my_app_name + '2')
db.reference('SomeOtherPath', app= obj).listen(listenerObject.listener)
Denominationalism answered 3/12, 2020 at 3:4 Comment(0)
V
0

As you can see on the per-language feature chart on the Firebase Admin SDK home page, Python and Go currently don't have realtime event listeners. If you need that on your backend, you'll have to use the node.js or Java SDKs.

Vietnamese answered 16/4, 2018 at 18:13 Comment(2)
can you send me some example or redirect me to a webpage??Rycca
I already linked you to the page for the Firebase Admin SDK. Start there.Vietnamese
R
0

You can use Pyrebase, which is a python wrapper for the Firebase API.

more info here:

https://github.com/thisbejim/Pyrebase

To retrieve data you need to use val(), example:

users = db.child("users").get()
print(users.val())
Rustice answered 16/4, 2018 at 18:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.