Search code examples
pythonfirebasegoogle-cloud-firestorefirebase-admin

Google Firebase: Get, update or create documents using Python


I am not able to get, update or create the documents in Google Firebase (Cloud Firestore) database using Python.

What I have:

A) The database with a collection and documents (inserted manually on the web):enter image description here

B) Credential JSON file saved as test.json (it is called often path/to/serviceKey.json in the documentation), which looks like this (redacted):

{
  "type": "service_account",
  "project_id": "test-6f02d",
  "private_key_id": "fffca ... 5b7",
  "private_key": "-----BEGIN PRIVATE KEY-----\n ... 1IHE=\n-----END PRIVATE KEY-----\n",
  "client_email": "test-admin@test-6f02d.iam.gserviceaccount.com",
  "client_id": "112 ... 060",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/ ... .gserviceaccount.com"
}

This user has a role Owner.

C) firebase_admin installed (using virtualenv, pip), I can do:

import firebase_admin
from firebase_admin import credentials, firestore
databaseURL = {'databaseURL': "https://test-6f02d.firebaseio.com"}
cred = credentials.Certificate("test.json")
firebase_admin.initialize_app(cred, databaseURL)
<firebase_admin.App object at 0x7f20056534e0>

The following is working:

db = firestore.client()
for k in db.collection('items').get():
    print(k)

I am getting the 3 documents, I can access the id of the documents

<google.cloud.firestore_v1beta1.document.DocumentSnapshot object at 0x7f2003bebc18>
<google.cloud.firestore_v1beta1.document.DocumentSnapshot object at 0x7f2003bebdd8>
<google.cloud.firestore_v1beta1.document.DocumentSnapshot object at 0x7f2003bebcf8>
print(k.id)
a3BxcpWpavHmuz6DpZH3

However, it is the max I can get.

1) I do not know how to access the values of the document. Something like this:

from firebase_admin import db
ref = db.reference('items')
print(ref)
<firebase_admin.db.Reference object at 0x7f20013b2828>
# GET?
ref.get()
# empty

2) I do not know how to access the values directly (e.g., using browser or requests), something like:

https://test-6f02d.firebaseio.com/items.json

returns

{
  "error" : "Permission denied"
}

3) I do not know how to update an existing document or create a new one in the collection items.

# UPDATE?
# PUSH?

I tried to follow this blog and the documentation (but it does not have examples) and several answers here on SO, but without any success.

Thanks in advance.


Solution

  • Another night and I can answer myself (thanks to Doug for the hint in the discussion):

    The problem for me was that there are two similar documentations (for Python part, the 2nd one is more extensive than just Python). I found the first one more helpful, but sometimes I needed to use part of the second one, too:

    1) Accessing the documents:

    import firebase_admin
    from firebase_admin import credentials, firestore
    databaseURL = {
         'databaseURL': "https://test-6f02d.firebaseio.com"
    }
    cred = credentials.Certificate("test.json")
    firebase_admin.initialize_app(cred, databaseURL)
    
    database = firestore.client()
    col_ref = database.collection('items') # col_ref is CollectionReference
    results = col_ref.where('name', '==', 'Pepa').get() # one way to query
    results = col_ref.order_by('date',direction='DESCENDING').limit(1).get() # another way - get the last document by date
    for item in results:
        print(item.to_dict())
        print(item.id)
    # item is DocumentSnapshot
    # note: the documentation says get() is depreciated in favour of stream(), however stream() did not work for me
    

    2) Still do not know, but I do not need it as 1) works ok.

    3) Update or create document:

    # Continuing from 1)
    
    # Udpdate:
    doc = col_ref.document(item.id) # doc is DocumentReference
    field_updates = {"description": "Updated description"}
    doc.update(field_updates)
    
    # Create:
    import datetime
    new_values = {
        "name": "Newbie",
        "description": "Shiny New Document",
        "date": datetime.datetime.now()
    }
    col_ref.document().create(new_values)