Awesome
micropython-firebase-firestore
Firebase Firestore implementation for Micropython.
Firebase implementation based on REST API, based on micropython-firebase-realtime-database from ckoever.
Installation
You can use uPip to install library from PyPi
import upip
upip.install("micropython-firebase-firestore")
or you can just upload ufirestore/ufirestore.py
to your microcontroller:
python pyboard.py -d PORT -f cp ufirestore.py :
Commands that are implemented
- set_project_id
- set_access_token
- patch
- create
- get
- getfile
- delete
- list
- list_collection_ids
- run_query
Required modules
ujson, urequests, _thread
Connect to Wifi
import time
import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
wlan.connect("ssid", "pass")
print("Waiting for Wi-Fi connection", end="...")
while not wlan.isconnected():
print(".", end="")
time.sleep(1)
print()
Example Usage
Reads a field from a stored document
import ufirestore
ufirestore.set_project_id("INSERT_PROJECT_ID")
ufirestore.set_access_token("INSERT_ACCESS_TOKEN")
raw_doc = ufirestore.get("DOCUMENT_PATH")
doc = FirebaseJson.from_raw(raw_doc)
if doc["fields"].exists("FIELD"):
print("The field value is: %s" % doc["fields"].get("FIELD"))
The project ID is required, read about it here
or you can find it at Project Settings > General
in your project's console
The access token is obtained from the Firebase Auth API, which can be harnessed with my auth library, or reading can be done here
Functions
set_project_id
ufirestore.set_project_id("INSERT_PROJECT_ID")
Set the ID of your Firebase project
set_access_token
ufirestore.set_access_token("INSERT_ACCESS_TOKEN")
Sets the access token to use for authentication
patch
ufirestore.patch(PATH, DOC, update_mask=[], bg=True, cb=None)
Updates or inserts a document DOC
at the location PATH
- Set the fields to update with
update_mask
- Optional run in the background with
bg
- Set a callback function after getting data with
cb
Example
doc = FirebaseJson()
doc.set("age/integerValue", 21)
response = ufirestore.patch("users/234", doc, ["age"], False)
print(response)
create
ufirestore.create(PATH, DOC, document_id=None, bg=True, cb=None)
Creates a new document DOC
at the collection at location PATH
document_id
- The document ID to use for the document. If not specified, an ID will be generated- Optional run in the background with
bg
- Set a callback function after getting data with
cb
Example
doc = FirebaseJson()
doc.set("name/stringValue", "Jane Doe")
doc.set("age/integerValue", 25)
doc.set("height/integerValue", 165)
response = ufirestore.create("users", doc, bg=False)
print(response)
get
ufirestore.get(PATH, mask=None, bg=True, cb=None)
Gets a single document at location PATH
document_id
- The document ID to use for the document. If not specified, an ID will be generatedmask
- The fields to return- Optional run in the background with
bg
- Set a callback function after getting data with
cb
Example
response = ufirestore.get("users/129", bg=False)
doc = FirebaseJson.from_raw(response)
if doc.exists("fields/name"):
print("Hello, %s" % doc.get("fields/name"))
getfile
ufirestore.getfile(PATH, FILENAME, mask=None, bg=True, cb=None)
Gets a single document at location PATH
and writes it to file FILENAME
document_id
- The document ID to use for the document. If not specified, an ID will be generatedmask
- The fields to return- Optional run in the background with
bg
- Set a callback function after getting data with
cb
Example
ufirestore.getfile("users/129", "user.json")
delete
ufirestore.delete(PATH, bg=True, cb=None)
Deletes a document at location PATH
- Optional run in the background with
bg
- Set a callback function after getting data with
cb
Example
success = ufirestore.delete("users/129")
if success:
print("User data successfully deleted.")
list
ufirestore.list(PATH, page_size=None, page_token=None, order_by=None, mask=None, show_missing=None, bg=True, cb=None)
Lists documents at location PATH
page_size
- The number of documents to returnpage_token
- Thenext_page_token
returned from a previouslist
optionorder_by
- The order to sort results by. For example:priority desc, name
mask
- The fields to return. If not set, return all fieldsshow_missing
- If the list should show missing documents- Optional run in the background with
bg
- Set a callback function after getting data with
cb
Example
documents, next_page_token = ufirestore.list("users", bg=False)
for document in documents:
doc = FirebaseJson.from_raw(document)
if doc.exists("fields/age"):
print("Age: %s" % doc.get("fields/age"))
list_collection_ids
ufirestore.list_collection_ids(PATH, page_size=None, page_token=None, bg=True, cb=None)
Lists all the collection IDs underneath a document at PATH
page_size
- The maximum number of results to returnpage_token
- A page token- Optional run in the background with
bg
- Set a callback function after getting data with
cb
Example
collection_ids, next_page_token = ufirestore.list_collection_ids("rooms/28", bg=False)
for collection_id in collection_ids:
print("ID: %s" % collection_id)
run_query
ufirestore.run_query(PATH, query, bg=True, cb=None)
Runs a query at location PATH
- Optional run in the background with
bg
- Set a callback function after getting data with
cb
Example
from ufirestore.json import FirebaseJson, Query
query = Query().from_("users").where("age", ">=", 18)
raw_doc = ufirestore.run_query("", query, bg=False)
doc = FirebaseJson.from_raw(raw_doc)
if doc.exists("fields/name"):
print("Resulted with user named %s" % doc.get("fields/name"))
FirebaseJson
A simple helper class for Firebase document JSON data
set
doc.set(path, value, with_type=False)
Edit, overwrite or create new node at the specified path
with_type
- If set toTrue
, the value's type will be inferred and applied accordingly, as per a Firestore Document Value
get
doc.get(path, default=None)
Get the node value at a given path, returning default
if the path does not exist
add
doc.add(path, name, value)
Add a new node at the path, with name name
and contents value
add_item
doc.add_item(path, value)
Adds an array item to the node at the path
remove
doc.remove(path)
Removes the node at the path
exists
doc.exists(path)
Checks whether a node exists at the path
process
doc.process(resource_name)
Processes json instance into a dict
for usage with Firestore API
NOTE: All the functions in this library that require a document actually require the FirebaseJon
instance and runs process
behind the scenes
FirebaseJson.from_raw
FirebaseJson.from_raw(raw_doc)
Parses a raw document object from the Firestore API into a FirebaseJson
instance
Extra methods
FirebaseJson.to_value_type
FirebaseJson.to_value_type(value)
Infers the type of value
and returns a dict
in the format of a Firestore Document Value
Example
value = 35
data = FirebaseJson.to_value_type(value)
print(data) # Returns {"integerValue": "35"}
FirebaseJson.from_value_type
FirebaseJson.from_value_type(value)
Takes a Firestore Document Value object and returns its value, casted to the correct type
Example
# Example data from API
data = {
"arrayValue": {
"values": [
{"stringValue": "a"},
{"stringValue": "b"},
{"integerValue": "3"}
]
}
}
print(value) # Returns ["a", "b", 3]
Query
Wrapper over FirebaseJson
to easily create document queries
Extends all FirebaseJson
methods
from_
query.from_(collection_id, all_descendants=False)
collection_id
- When set, selects only collections with this IDall_descendants
- WhenTrue
, selects all descendant collections, whenFalse
, selects collections that are immediate children of theparent
the query will be run on
select
query.select(field)
Adds a document field to return
order_by
query.order_by(field, direction="DESCENDING")
field
- The field to order bydirection
- The direction to order by (ASCENDING
orDESCENDING
)
limit
query.limit(value)
The maximum number of results to return, value
must be >= 0
where
query.where(field, op, value)
Applies a filter on a specific field.
field
- The field to filter byop
- The operation to filter by, is one of<
,<=
,>
,>=
,==
,!=
,array-contains
,in
,array-contains-any
,not-in
value
- The value to compare to, type is inferred withFirebaseJson.to_value_type
process
query.process()
Returns dict
data of query for use with Firestore API
NOTE: This function is already used in the run_query
function