Using firestore in colab with python - python

i'm trying to use firebase in colab with Python. But there is unsolvable error,
so i need some help.
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
cred = credentials.Certificate('/content/myKey.json')
firebase_admin.initialize_app(cred) # error in this line
db = firestore.client()
ValueError: : The default Firebase app already exists. This means you called initialize_app() more than once without providing an app name as the second argument. In most cases you only need to call initialize_app() once. But if you do want to initialize multiple apps, pass a second argument to initialize_app() to give each app a unique name.
What can i do for solving this problem?
i also found similar answer with this, so i tried some many tips in there, like below.
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
if not firebase_admin._apps:
cred = credentials.Certificate('/content/foodle-94e80-firebase-adminsdk-zr21t- f02504e9fb.json')
firebase_admin.initialize_app(cred)
else:
app = firebase_admin.get_app()
db = firestore.client(app) # new error in this line
but new error is confusing me.
DefaultCredentialsError: Could not automatically determine credentials. Please set GOOGLE_APPLICATION_CREDENTIALS or explicitly create credentials and re-run the application. For more information, please see https://cloud.google.com/docs/authentication/getting-started
What can i do?

Looks like there's a default instance of the Firebase app getting initialized somewhere. When the default instance gets created, it uses GOOGLE_APPLICATION_CREDENTIALS instead of the credentials you pass in manually.
You can either provide GOOGLE_APPLICATION_CREDENTIALS to the script, or ignore the default instance of the firebase app and create an explicitly named one.
To create an explicitly named app, change your code to provide a name:
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
cred = credentials.Certificate('/content/myKey.json')
firebase_admin.initialize_app(credential=cred, name='myApp')
db = firestore.client()
To provide GOOGLE_APPLICATION_CREDENTIALS and use the default app:
If you're running your python script from the console, you can provide a value for that by running
export GOOGLE_APPLICATION_CREDENTIALS='/content/myKey.json'
In colab, you need to add this to your script:
import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="/content/myKey.json"
After this you can run your second example.
(To get the credentials JSON go to this page, select your firebase-adminsdk service account, click 'ADD KEY', 'Create new key', select JSON as your option and download the resulting file.)

In my case it worked with
cred = credentials.Certificate("/content/drive/My Drive/Colab Notebooks/LALALA.json")
firebase_admin.initialize_app(cred)

Related

Why does VSCode Python code completion not work for my firestore client variable?

I have the following python snippet...
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
cred = credentials.Certificate("./cert.json")
firebase_admin.initialize_app(cred)
client = firestore.client()
client.
When I type the dot on the last line, no code completion options come up. On the 'firestore' variable, there are code completion options that come up.
I have the Python and Pylance extensions installed in VSCode. Is this a configuration issue, or is there something about what the client() method is returning, that it is not possible to infer its type?
Turns out there was already an open issue for this on the github repo, which also included a temporary (poor) workaround.
from firebase_admin import firestore
from google.cloud.firestore import Client as FirestoreClient # importing the return type of firestore.client()
db: FirestoreClient = firestore.client() # Adding an annotation to my db variable, to enable completion and syntax checking

Firestore SDK hangs in production

I'm using the Firebase Admin Python SDK to read/write data to Firestore. I've created a service account with the necessary permissions and saved the credentials .json file in the source code (I know this isn't the most secure, but I want to get the thing running before fixing security issues). When testing the integration locally, it works flawlessly. But after deploying to GCP, where our service is hosted, calls to Firestore don't work properly and retry for a while before throwing 503 Deadline Exceeded errors. However, SSHing into a GKE pod and calling the SDK manually works without issues. It's just when the SDK is used in code flow that causes problems.
Our service runs in Google Kubernetes Engine in one project (call it Project A), but the Firestore database is in another project (call it project B). The service account that I'm trying to use is owned by Project B, so it should still be able to access the database even when it is being initialized from inside Project A.
Here's how I'm initiating the SDK:
from firebase_admin import get_app
from firebase_admin import initialize_app
from firebase_admin.credentials import Certificate
from firebase_admin.firestore import client
from google.api_core.exceptions import AlreadyExists
credentials = Certificate("/path/to/credentials.json")
try:
app = initialize_app(credential=credentials, name="app_name")
except ValueError:
app = get_app(name="app_name")
client = client(app=app)
Another wrinkle is that another part of our code is able to successfully use the same service account to produce Firebase Access Tokens. The successful code is:
import firebase_admin
from firebase_admin import auth as firebase_admin_auth
if "app_name" in firebase_admin._apps:
# Already initialized
app = firebase_admin.get_app(name="app_name")
else:
# Initialize
credentials = firebase_admin.credentials.Certificate("/path/to/credentials.json")
app = firebase_admin.initialize_app(credential=credentials, name="app_name")
firebase_token = firebase_admin_auth.create_custom_token(
uid="id-of-user",
developer_claims={"admin": is_admin, "site_slugs": read_write_site_slugs},
app=app,
)
Any help appreciated.
Turns out that the problem here was a conflict between gunicorn's gevents and the SDK's use of gRCP. Something related to websockets. I found the solution here. I added the following code to our Django app's settings:
import grpc.experimental.gevent as grpc_gevent
grpc_gevent.init_gevent()

Why I get this error on python firebase-admin initialize_app()?

when I was trying to connect google firebase real time database, I got this error:
ValueError: The default Firebase app already exists. This means you called
initialize_app() more than once without providing an app name as the second argument. In
most cases you only need to call initialize_app() once. But if you do want to initialize
multiple apps, pass a second argument to initialize_app() to give each app a unique name.
Here is my code:
import firebase_admin
from firebase_admin import credentials
from firebase_admin import db
cred = credentials.Certificate('firebase-sdk.json')
firebase_admin.initialize_app(cred, {
'databaseURL': 'https://test-139a6-default-rtdb.firebaseio.com/'
})
You only need to initialize (create) the app once. When you have created the app, use get_app instead:
# The default app's name is "[DEFAULT]"
firebase_admin.get_app(name='[DEFAULT]')
You need to initialize the Admin SDK only once. You can check if the Admin SDK is already initialized using this if statement:
if not firebase_admin._apps:
firebase_admin.initialize_app(cred, {
'databaseURL': 'https://test-139a6-default-rtdb.firebaseio.com/'
})

"No such file or directory" with firebase_admin python library

I want to retrieve some data by a firebase database with using the official library for python (firebase_admin) instead of pyrebase or python-firebase.
I try to execute the following lines of code:
from firebase_admin import db
from firebase_admin import credentials
import firebase_admin
cred = credentials.Certificate('https://project_name.firebaseio.com/.json')
firebase_admin.initialize_app(cred)
result = db.Query.get()
but then I get the following error:
FileNotFoundError: [Errno 2] No such file or directory: 'https://project_name.firebaseio.com/.json'
even though when I enter this url on my browser (with project_name replaced with my real project name) I am getting the json of data from the database.
How can I fix this error?
The Certificate should point to a local file with your credentials/certificate. You are instead pointing it to your database URL, which is not a local file, so the library throws an error.
From the documentation on initializing the Python SDK:
import firebase_admin
from firebase_admin import credentials
from firebase_admin import db
# 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'
})
# As an admin, the app has access to read and write all data, regardless of Security Rules
ref = db.reference('restricted_access/secret_document')
print(ref.get())
Try this ,this works for me
import os
from firebase_admin import credentials, firestore, initialize_app
# Initialize Firestore DB
data = os.path.abspath(os.path.dirname(__file__)) + "/serviceAccountKey.json"
cred = credentials.Certificate(data)
default_app = initialize_app(cred)
db = firestore.client()

Python - Firebase DB reference error

I need to update certain node in my Firebase DB, so this is what I'm doing:
from firebase_admin import db
def update_data_in_firebase(gid, account_id, location_id, data_to_update):
firebase_url = 'saved_locations/{}/accounts/{}/locations/{}'.format(gid, account_id, location_id)
ref = db.reference(path=firebase_url)
ref.update(data_to_update)
So, the code above is what I'm trying to do to update the data in the Firebase node, but I'm getting this error:
Invalid databaseURL option: "None". databaseURL must be a non-empty URL string.
Of course, I checked out the firebase URL and it matches, so the problem is not the URL, or, I'm missing something with the path, I mean, should I use absolute insted of relative path.
As mentioned in the comments of the question, the databaseURL was not defined.
Answer:
cred = credentials.Certificate('your_config.json')
firebase_admin = firebase_admin.initialize_app(cred, {'databaseURL': 'https://your-firebase-db'})
In the main docs of Firebase, I couldn't find the error on my app initialization:
Firebase Admin Docs
But in the Realtime Database - Admin (Get Started), there is a snippet where they initialize the Firebase App defining the databaseURL

Categories

Resources