Cannot connect to firestore firebase in Python - python

I created a firebaseconfig.json file with my apikey, authodomain, databaseurl, projected, storagebucket, messagingsenderid, appid and measurementid. this comes standard in the SDK setup and configuration section of the yourapps section in project setting. but when I try running my python code.
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
import os
print(os.getcwd())
if not firebase_admin._apps:
cred = credentials.Certificate('src/firebaseconfig.json')
default_app = firebase_admin.initialize_app(cred)
db = firestore.client()
users_ref = db.collection(u'users')
docs = users_ref.stream()
for doc in docs:
print(f'{doc.id} => {doc.to_dict()}')
I get the Error: ValueError: Invalid service account certificate. Certificate must contain a "type" field set to "service_account".

The Firebase Admin SDK requires a service account for authentication, as opposed to a configuration file with the project keys (which is primarily used for web/iOS/Android clients).
If you have not used a service account, you need to generate a key file to use within your application through the Firebase console (Settings -> Service Accounts -> Generate New Private Key).
Afterwards, you can initialize the firestore client within your code as follows (relevant doc):
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
# Use the json key generated from the Firebase console
cred = credentials.Certificate('path/to/serviceAccount.json')
firebase_admin.initialize_app(cred)
db = firestore.client()
Let me know if this information was useful.

Related

How to access firebase database without having 'Realtime Database'?

Im trying to connect my python script to a Firebase database.
Here is the code:
import firebase_admin
from firebase_admin import credentials, db
cred = credentials.Certificate("irebase-adminsdk-ofcmd-bwd7fbcz2c.json")
firebase_admin.initialize_app(cred, {'databaseURL':'https://company.firebaseio.com/'})
ref = db.reference('/users').get()
The ERROR Im facing looks like this:
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://company.firebaseio.com/users.json
I did a lot of research and everyone says that I have to find the right URL in the 'Realtime Database' Section. I wonder if there is any way to access the Firebase db without having realtime one enabled.
if you are looking to access the Firebase Database without having the realtime one enabled, you can try the Cloud Firestore which is a different database service provided by Firebase which doesn't require realtime database to be enabled but you may need to change the way you are accessing the data
import firebase_admin
from firebase_admin import credentials, firestore
# Initialize the Firebase Admin SDK with your service account credentials
cred = credentials.Certificate("firebase-adminsdk-that-cred-file.json")
firebase_admin.initialize_app(cred)
# Create a reference to the Firestore database
db = firestore.client()
# Read data from a specific document in the 'users' collection
doc_ref = db.collection('users').document('user1')
doc = doc_ref.get()
# Print the data from the document
print(doc.to_dict())

firebase connect to database throwing invalid Database URL

I have a simply python app and I am trying to connect to Firebase, I downloaded my cert.json file and have a valid certificate that authenticates however when I try to create a reference to the database as according to the docs, it throws the following error:
File "C:\Python3\lib\site-packages\firebase_admin\db.py", line 69, in reference
client = service.get_client(url)
File "C:\Python3\lib\site-packages\firebase_admin\db.py", line 798, in get_client
raise ValueError(
ValueError: Invalid database URL: "None". Database URL must be a non-empty URL string.
I have added my code below:
import firebase_admin
import os
from firebase_admin import db
from firebase_admin import credentials
certfile = "firebase_cert.json"
credentials = credentials.Certificate(certfile)
database = firebase_admin.initialize_app(credentials)
ref = db.reference("/")
print(ref)
As the Firebase documentation for initializing the Admin SDK in Python shows, you will need to specify the URL for your document in your application code:
# Fetch the service account key JSON file contents
cred = credentials.Certificate('path/to/serviceAccountKey.json')
# Initialize the app with a service account, granting admin privileges
firebase_admin.initialize_app(cred, {
'databaseURL': 'https://databaseName.firebaseio.com' // 👈
})
ref = db.reference("/")

Firestore Emulator in Python

I'm trying to connect using python 3.8 to the firestore emulator 8.12. I'm having difficulty finding a way to connect. I've downloaded my key from Firestore in the cloud. But I'm trying to connect locally. What does local.json file look like to connect to the emulator locally?
import os
import firebase_admin
from firebase_admin import firestore
from firebase_admin import credentials
cred = credentials.ApplicationDefault()
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "local.json"
firebase_app = firebase_admin.initialize_app(cred)
db=firestore.client()
data = {
u'name': u'Los Angeles',
u'state': u'CA',
u'country': u'USA'
}
# Add a new doc in collection 'cities' with ID 'LA'
db.collection(u'cities').document(u'LA').set(data)
From this issue on the repo, it seems the Python Admin SDK also needs to the FIRESTORE_EMULATOR_HOST environment variable to be set.
os.environ["FIRESTORE_EMULATOR_HOST"] = "127.0.0.1:8080"
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "emulator_config.json"
docs = db.collection(u'insights/venues/queue').stream()
You can use anonymous credentials. From google-auth docs:
These are useful in the case of services that support anonymous access
or local service emulators that do not use credentials.
If you don't provide credentials, then it will use default credentials like you do and describet here
from google.auth import credentials
from google.cloud import firestore
client = firestore.Client(credentials=credentials.AnonymousCredentials())
FIRESTORE_EMULATOR_HOST needs to be set

Firebase Admin SDK: list_users() error INSUFFICIENT_PERMISSION

I'm using the Firebase Admin Python SDK to connect to our Firebase instance where are users are stored for a web application. I am attempting to create a job that queries Firebase every day and gets a count of users and then archives this off to our data warehouse to report on it going forward. I've successfully created service account credentials and made sure the credentials are valid by accessing the Google Cloud Platform (following these instructions):
import firebase_admin
creds = firebase_admin.credentials.Certificate("/Users/me/Downloads/service-account-146c01507e2b.json")
default_app = firebase_admin.initialize_app(creds)
However, the instructions are not clear on how I go about authenticating in order to pull back a list of all users. It just says to import the auth class and then run auth.list_users() but doesn't clarify how to authenticate using this class.
When I run firebase_admin.auth.list_users() I get the following error: InvalidArgumentError: Error while calling Auth service (INSUFFICIENT_PERMISSION).
Can anyone help me understand how/where I authenticate with my service account credentials? Thanks!
Firebase Service Account
The Firebase service account should be generated from:
Firebase Console > Project Settings > Service Accounts and clicking Generate new private key
Initialize Firebase SDK
import json
import firebase_admin
from firebase_admin import credentials
FIREBASE_CERT = "credentials/firebase-adminsdk-####-##########.json"
with open(FIREBASE_CERT) as json_file:
json_data = json.load(json_file)
DEFAULT_CRED = credentials.Certificate(json_data)
app_instance = firebase_admin.initialize_app(DEFAULT_CRED)
firebase_admin.auth.list_users()

Connecting aws backend to firebase database

I'm currently running python code in my aws server and trying to connect to my friend's firebase database. I read the documentation provided by firebase to connect to aws server.
https://firebase.google.com/docs/admin/setup
I have followed every step but I'm getting an error when I try to connect to my server. I have added google-service.json for credential.
Error that I get :
ValueError: Invalid service account certificate. Certificate must
contain a "type" field set to "service_account".
Do I need to modify the google-services.json ?
My code:
import firebase_admin
from firebase_admin import credentials
cred = credentials.Certificate('/home/ec2-user/google-services.json')
#default_app = firebase_admin.initialize_app(cred)
other_app = firebase_admin.initialize_app(cred, name='other')
ault_app = firebase_admin.initialize_app()
google-services.json is typically the name of an Android app configuration file. That's not the same as a service account. To get a hold of the credentials for a service account for your project, you'll need to generate one from the Firebase console from Project Settings -> Service Accounts. The documentation is here. Once you have this file, you can initialize the Admin SDK with it to begin accessing the data in your project.
Better way would be to store credentials on s3 (encrypted) with a IAM role attached to lambda function.
import os
import firebase_admin
from firebase_admin import credentials
import boto3
from settings.local_settings import AWS_REGION, ENVIRONMENT
import json
firebase_config_file = 'app-admin-config-{}.json'.format(ENVIRONMENT)
firebase_admin_creds_file = 'app-admin-sdk-{}.json'.format(ENVIRONMENT)
current_dir = os.path.abspath(os.path.dirname(__file__))
files = [f for f in os.listdir(current_dir) if os.path.isfile(f)]
if firebase_config_file not in files and firebase_admin_creds_file not in files:
s3 = boto3.resource('s3', region_name=AWS_REGION)
bucket = s3.Bucket('app-s3-secrets')
firebase_config = json.loads(
bucket.Object('app-admin-config-{}.json'.format(ENVIRONMENT)).get()['Body'].read())
firebase_admin_creds = json.loads(
bucket.Object('app-admin-sdk-{}.json'.format(ENVIRONMENT)).get()['Body'].read().decode())
class Firebase:
#staticmethod
def get_connection():
cred = credentials.Certificate(firebase_admin_creds)
return firebase_admin.initialize_app(cred, firebase_config)
app = Firebase.get_connection()

Categories