Awesome
micropython-firebase-realtime-database
Firebase implementation based on REST API optimized for the ESP32 version of Micropython based on firebase-micropython-esp32 from vishal-android-freak. It shouldn't be a problem to run it on other Micropython platforms. A board with SPIRAM is recommended.
Commands that are implemented
- get (equal GET)
- getfile (equal GET)*
- put (equal PUT)
- patch (equal PATCH)
- addto (equal POST)
- delete (equal DELETE)
*getfile writes the data to a file to avoid RAM overflow
Required modules
ujson, usocket, ussl, _thread, time
Preparations YouTube Tutorial
- Create a Firebase Realtime Database. (Console>Add Project>Realtime Database>Create Database)
In the end it should look something like this:
- Set rules to public * (from now the data can be read and changed by everyone ⚠️) *
{
"rules": {
".read": true,
".write": true
}
}
- Note the URL of the database
https://[PROJECT_ID].firebaseio.com/
Connect to Wifi
import os
import network
wlan = network.WLAN(network.STA_IF)
if not wlan.active() or not wlan.isconnected():
wlan.active(True)
wlan.connect("SSID", "PASSWD")
while not wlan.isconnected():
pass
Set the URL of the database
import ufirebase as firebase
firebase.setURL("https://[PROJECT_ID].firebaseio.com/")
Functions
setURL --- do this first!
firebase.setURL(URL)
Set the current Firebase URL.
get --------------------------------------
firebase.get(PATH, DUMP, bg=False, id=0, cb=None, limit=False)
Takes the given storage location PATH
, gets the data from there and stores it as DUMP
. The data can later be read out by firebase.[DUMP]
.
-
Optional run in the background with the keyword
bg
. -
Set socket id with the keyword
id
. This makes it possible to establish multiple connections to the server instead of just one. Make sure the command runs in the background. -
Set an callback function after getting the
DATA
.- Example:
def hereweare(name, id, varname): print("\nname: "+str(name)+", id: "+str(id)+", value: "+str(eval("firebase."+varname))) firebase.get("testtag1", "VAR1", bg=True, id=0, cb=(hereweare, ("testtag1", "0", "VAR1"))) firebase.get("testtag2", "VAR2", bg=True, id=1, cb=(hereweare, ("testtag2", "1", "VAR2"))) #runs at the same time
-
Limit the depth of the data to 1 with
limit
⚠️ ONLY USE True/False (not 1/0).- Example:
firebase.get("a", "VAR1") print(firebase.VAR1) #returns {'testlarge2': 'KJIHGFEDCBA', 'lol': 'ok', 'a': {'-MY_ntFnAhiTYygcraC6': [2, 2], '-MY_novcmzHOyexwij8B': '2', '-MY_nlKoV7jcYbTJMpzT': '2'}, 'testlarge1': 'ABCDEFGHIJK', 'testtag1': 1, 'testtag2': 2} firebase.get("a", "VAR2", limit=True) print(firebase.VAR2) #returns {'testlarge2': True, 'lol': True, 'testtag2': True, 'testlarge1': True, 'testtag1': True, 'a': True}
getfile --------------------------------------
firebase.getfile(PATH, FILE, bg=False, id=0, cb=None, limit=False)
Takes the given storage location PATH
, gets the data from there and stores it as file at the location FILE
. Recommeded to download larger amounts of data to avoid ram overflow.
- Optional run in the background with the keyword
bg
. - Set socket id with the keyword
id
. This makes it possible to establish multiple connections to the server instead of just one. Make sure the command runs in the background. - Set an callback function after getting the
DATA
.- Example:
def herewefile(name, id, filename): LOCAL_FILE=open(str(filename)) print("\nname: "+str(name)+", id: "+str(id)+", value: "+str(LOCAL_FILE.read())) LOCAL_FILE.close() firebase.getfile("testlarge1", "FILE1.txt", id=0, bg=1, cb=(herewefile, ("testlarge1", "0", "FILE1.txt"))) firebase.getfile("testlarge2", "FILE2.txt", id=1, bg=1, cb=(herewefile, ("testlarge2", "1", "FILE2.txt"))) #runs at the same time
- Limit the depth of the data to 1 with
limit
⚠️ ONLY USE True/False (not 1/0).
put --------------------------------------
firebase.put(PATH, DATA, bg=True, id=0, cb=None)
Takes the given storage location PATH
and uploads the given value DATA
there.
- Optional run in the background with the keyword
bg
. - Set socket id with the keyword
id
. This makes it possible to establish multiple connections to the server instead of just one. Make sure the command runs in the background. (Example at get) - Set an callback function after getting the
DATA
.- Example:
firebase.put("testtag1", "1", id=0) firebase.put("testtag2", "2", id=1) #runs at the same time
patch --------------------------------------
firebase.patch(PATH, DATATAG, bg=True, id=0, cb=None)
Takes the given storage location PATH
and patches the given key DATATAG
there, without touching any other tag in the Database.
- Example:
firebase.put("teststruct", {"tag1": "val1", "tag2": "val2"})
firebase.patch("teststruct", {"tag1": "new1"}) #only tag 1 will be changed
- Optional run in the background with the keyword
bg
. - Set socket id with the keyword
id
. This makes it possible to establish multiple connections to the server instead of just one. Make sure the command runs in the background. (Example at get) - Set an callback function after patching the
DATA
.
addto --------------------------------------
firebase.addto(PATH, DATA, DUMP=None, bg=True, id=0, cb=None)
Takes the given storage location PATH
and adds the given value DATA
there, the randomly generated tag can be optionally stored in the DUMP variable.
- Example:
firebase.addto("testsensor", 128)
firebase.addto("testsensor", 124)
firebase.addto("testsensor", 120, DUMP="tagname")
print(firebase.tagname) #returns '-MY7GTy4pp2LSpQp5775' (example)
- Optional run in the background with the keyword
bg
. - Set socket id with the keyword
id
. This makes it possible to establish multiple connections to the server instead of just one. Make sure the command runs in the background. (Example at get) - Retuns the tag under which the data was saved.
- Set an callback function after adding the
DATA
.
delete --------------------------------------
firebase.delete(PATH, bg=True, id=0, cb=None)
Takes the given storage location PATH
deletes the data there.
- Optional run in the background with the keyword
bg
. - Set socket id with the keyword
id
. This makes it possible to establish multiple connections to the server instead of just one. Make sure the command runs in the background. (Example at get) - Set an callback function after deleting the
DATA
.
Constants
FIREBASE_GLOBAL_VAR.GLOBAL_URL
firebase.FIREBASE_GLOBAL_VAR.GLOBAL_URL
Returns the current URL as string, do not change directly insted use firebase.setURL(URL)
FIREBASE_GLOBAL_VAR.GLOBAL_URL_ADINFO --------------------------------------
firebase.FIREBASE_GLOBAL_VAR.GLOBAL_URL_ADINFO
Additional information needed by usocket as list.
FIREBASE_GLOBAL_VAR.SLIST --------------------------------------
firebase.FIREBASE_GLOBAL_VAR.SLIST
Dict of sokets for background process.
Simple examples
Get data from the database
firebase.get("testtag", "DATAvariable")
print(firebase.DATAvariable) #None if no data found
firebase.getfile("testtag", "DATAfile.txt")
myfile=open("DATAfile.txt")
print(myfile.read())
myfile.close()
Upload data to the database --------------------------------------
firebase.put("testtag", "testtdata")
firebase.put("testtag", {"tag1": "data1", "tag2": "data2"})
firebase.addto("testtag", "data1")
Delete data from the database --------------------------------------
firebase.delete("testtag")
Functionality
A thread is created for each command* entered. There is a kind of waiting loop for these commands, so only one connection can be executed at a time per id.
If you make 4 get commands, id=0, these are processed one after the other, which means that the last command is executed much later.
If you make 4 get commands, half id=0, half id=1, these are processed 2*one after the other, which means that the last command is executed a bit earlier.
<meta name="google-site-verification" content="FTs6IR_lrQ_1XqCMMtQI_AUInQqW3qCF3H7TV1QgqUY" />*exception if bg = False