6

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.

Michal Skop
  • 1,349
  • 1
  • 15
  • 23
  • Please limit yourself to a single question per post. It seems like a lot of your questions could be addressed by reading the Firestore documentation. – Doug Stevenson Feb 27 '19 at 05:05
  • @DougStevenson I spent the last day reading the documentation and trying to manipulate the data, trust me. But I was not able even to read/get the data using python (I was able to do it using js). But I understand your comment about multiple questions (however, it can still be called as s single problem: "I am not able to manipulate the data in python"). – Michal Skop Feb 27 '19 at 05:19
  • I don't think anyone will be able to add anything that's not already in the documentation. Your starting point will be to actually try one simple thing, and if that doesn't work the way you expect, post with the results of your one experiment, and indicate what doesn't work the way you expect. – Doug Stevenson Feb 27 '19 at 05:24
  • I will refer you specifically to the API docs for DocumentSnapshot (search for it in the page), as that seems to be something you missed. https://googleapis.github.io/google-cloud-python/latest/firestore/document.html – Doug Stevenson Feb 27 '19 at 05:35
  • Thanks a lot! You pointed me to the right direction and solved the 1st problem (the 2nd was a possible workaround, so that one de facto too). I will update the question with this answer. – Michal Skop Feb 27 '19 at 05:42
  • As I said, you asked multiple questions in this post. Please search thoroughly and post your specific issues as you encounter them. – Doug Stevenson Feb 27 '19 at 05:44
  • The questions are really very connected. But it seems to me now that `google-cloud-firestore` is the way to go (and not `firebase_admin` that I was convinced that it was the right tool). Anyway, I will investigate more and update it here. – Michal Skop Feb 27 '19 at 06:02
  • Firestore admin just wraps the cloud API. They are basically the same thing, but in a different package. – Doug Stevenson Feb 27 '19 at 06:03
  • Can OP tell me where can I find the `path/to/serviceKey.json`? – asn Mar 30 '19 at 14:58
  • 1
    @jay serviceKey.json is a credintial JSON file, you can generate it at `https://console.cloud.google.com/iam-admin/serviceaccounts?authuser=0&project=YOUR_PROJECT_NAME` under `Actions`->`Create Key`. This creates a JSON file, you save it to someplace (e.g. `/home/jay/project/test/testServiceKey.json`) and this is what the manuals refer to with `path/to/serviceKey.json`. See step B) in the question above for an example of such file. – Michal Skop Mar 31 '19 at 23:57

3 Answers3

16

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)
Michal Skop
  • 1,349
  • 1
  • 15
  • 23
0
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore

cred = credentials.Certificate("serviceAccountKey.json")
firebase_admin.initialize_app(cred)

db = firestore.client()
docs = db.collection("persons").where("Province","==",cprovince.get()).get()
for doc in docs:
     print(doc.to_dict())
toku-sa-n
  • 798
  • 1
  • 8
  • 27
0

pip install --upgrade google-cloud-firestore

Then use

# Import
from google.cloud import firestore

# Create your Firebase client
firebase = firestore.Client(project="your project name")

# Define the collection you're working in
collection = firebase.collection("myCollection")

# Filter for docs, get their ref's, grab the first, and convert it back to a dict
collection.where(...).get()[0].to_dict()

# Add a doc (by ID)
doc_explicit_ref = collection.document("my unique doc ID")
doc_explicit_ref.add({"my data":"is here"})

# Add an implicit doc (auto generated ID)
collection.add({"my cool":"data"})

This follows the same convention of pretty much any other python lib that GCP has - ensure your GOOGLE_APPLICATION_CREDENTIALS env var points to your svc account json

geudrik
  • 666
  • 8
  • 22