This is the first time, i am testing Firebase Admin SDK using Python. I have written programs using NodeJS. Since, i am into learning Python recently wanted to try Firebase and Python. What really interested me is
Python and Go Admin SDKs, all write methods are blocking. That is, the write methods do not return until the writes are committed to the database.
This seriously reduces my code a lot. Earlier i used to write a ton of code to make things synchronous, yeah, NodeJS/Javascript is not for that but at that time, it was the only option i had for things i was working on. I am very much happy reading this.
Lets divide this post into two parts,
-
Adding/Updating data to firebase
-
Querying data
Adding/Updating data to firebase
This is a simple Python Firebase Program to add data to realtime database, its taken from the sample Google Firebase documentation only.
Console Output
Below is the output when you run it.
Things to notice in the above program,
-
Service Account Specification, there are two ways
- First method is as mentioned in the program pointing to the secret json file
- Second is updating the environment variable GOOGLE_APPLICATION_CREDENTIALS ( more details on this after the below program )
-
.set()
will replace the data in that node path, if data already exists. So, you need to be careful with that. -
When adding data, either you can add it individually like below or combine them as in the program,
-
Multi-path updates is the one i prefer, but you got to do a bit of planning for it.
-
Push keys
new_post_ref = posts_ref.push()
. They generate a unique key which contains an encoded timestamp value. So when you are generating it and add to firebase database, they are sort of chronologically sorted as these push-keys contain current time. The keys are also designed to be unguessable (they contain 72 random bits of entropy). -
Deletes an entire node
Application Default Credentials (ADC)
Google Cloud Client Libraries use a library called Application Default Credentials (ADC) to automatically find your service account credentials. ADC looks for service account credentials in the following order:
If the environment variable GOOGLE_APPLICATION_CREDENTIALS is set, ADC uses the service account key or configuration file that the variable points to.
If the environment variable GOOGLE_APPLICATION_CREDENTIALS isn’t set, ADC uses the service account that is attached to the resource that is running your code.
This service account might be a default service account provided by Compute Engine, Google Kubernetes Engine, App Engine, Cloud Run, or Cloud Functions. It might also be a user-managed service account that you created.
Using the above technique, ADC can automatically find your credentials. Its recommended using ADC because it requires less code and your code is portable in different environments.
Basically run the below command to set the environment variable
Any GCP Client will look for GOOGLE_APPLICATION_CREDENTIALS
, if its set it will use it and no need any code related to pointing to the secret json file. See below firebase admin initialization there is no mention of cred
which is mentioned in above program. Also take at look below querying example it uses ADC.
firebase_admin.initialize_app(options={
'databaseURL': "https://api-project-testing.firebaseio.com"
})
Querying data
Below running the below program SET the environment variable set GOOGLE_APPLICATION_CREDENTIALS
Sorting the data
First lets see order_by_child()
, here length is the child of node dinosaurs
If you don’t add .indexOn to rules, you will get below error
Make the changes and publish
Now if you run, you will get result like below,
Next, we will see order_by_value()
, setting up data.
Here we are trying to sort by value of the scores. There is nothing nested like sub-nodes, so try to keep things this simple.
Before running this program, you should update the updates the rules to index the score.
{
"rules": {
".read": "auth.uid != null",
".write": "auth.uid != null",
"python-testing":{
"dinosaurs": {
".indexOn": ["height", "length"]
},
"leader-board":{
"scores": {
".indexOn": ".value"
}
}
}
}
}
After updating the index, if you execute, you will get output like below,
Next, we will see order_by_key()
and there is no need to define index explicitly as node’s key is indexed automatically
Output is
Order is always ascending, there is no function to get it descending, you have to do that in client side.
Both the above reverse techniques work. Now the output is,
Checking if data exists
This should have been the first in querying section, but here it is
Thank you for reading