How to Initialize Firebase Admin SDK in Cloud Function (Python) - python

I found a similar question on here, but it was for JavaScript and I am using Python. I'm trying to use the Firebase-Admin SDK so I can verify Firebase Authentication id_tokens in my cloud function. In my requirements.txt I have included firebase-admin, and my main.py file looks like this:
from firebase_admin import auth
from firebase_admin import credentials
def returnSQLresponse(request):
default_app = firebase_admin.initialize_app()
headers = request.headers
if headers and 'Authorization' in headers:
id_token = headers['Authorization']
decoded_token = auth.verify_id_token(id_token)
uid = decoded_token['uid']
There are probably other problems with the above code, but my main issue is I am getting the error "in returnSQLresponse default_app = firebase_admin.initialize_app() NameError: name 'firebase_admin' is not defined". How do I initialize the Firebase Admin SDK in Python so I can verify this token? I tried following the guide here: https://firebase.google.com/docs/auth/admin/verify-id-tokens#verify_id_tokens_using_the_firebase_admin_sdk. This guide lead me to where I am at now.

Notice that your are importing the auth and credentials modules only and failing to import the firebase_admin module itself and therefore you get the:
NameError: name 'firebase_admin' is not defined
when trying to initialize the app by calling:
...
default_app = firebase_admin.initialize_app()
...
Making sure that firebase-admin is added within your requirements.txt file and making the imports in the following way:
import firebase_admin
import firebase_admin.auth as auth
import firebase_admin.credentials as credentials
def returnSQLresponse(request):
default_app = firebase_admin.initialize_app()
...
should clear the NameError error message.

Related

Using firestore in colab with 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)

How do I authenticate to Azure using a Service Principal and the Python SDK?

I am currently attempting to authenticate to Azure using the azure-mgmt-support MicrosoftSupport client and am receiving the following error:
AdalError: Get Token request returned http error: 400 and server response: {"error":"unauthorized_client","error_description":"AADSTS700016: Application with identifier 'xxx' was not found in the directory 'management.core.windows.net'. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the wrong tenant.
I have double checked and am definitely using the correct client_id and tenant_id. What am I missing here? My code below:
from azure.mgmt.support import MicrosoftSupport
from msrestazure.azure_active_directory import ServicePrincipalCredentials
sub_id = 'xxx'
sp_creds = ServicePrincipalCredentials(client_id='xxx', secret='xxx')
SupportClient = MicrosoftSupport(sp_creds, sub_id)
After a short walk and another look at the documentation, and I spotted my error - I was missing the tenant_id from the ServicePrincipalCredentials object. It's not obvious from the SDK specification or error message that this is what was missing as the only required variables are client_id and secret, however when I looked at this example in the documentation I realised it was missing (pasting code below for posterity, in case docs page changes).
import os
from azure.mgmt.resource import SubscriptionClient
from azure.common.credentials import ServicePrincipalCredentials
# Retrieve the IDs and secret to use with ServicePrincipalCredentials
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]
tenant_id = os.environ["AZURE_TENANT_ID"]
client_id = os.environ["AZURE_CLIENT_ID"]
client_secret = os.environ["AZURE_CLIENT_SECRET"]
credential = ServicePrincipalCredentials(tenant=tenant_id, client_id=client_id, secret=client_secret)
subscription_client = SubscriptionClient(credential)
subscription = next(subscription_client.subscriptions.list())
print(subscription.subscription_id)

How to access Firebase Firestore from GCP Cloud Function

I am trying to access a Firebase Firestore DB from a GCP Cloud Function - the function is not part of the Firebase project - so two separate projects. When I config/init the DB I get a permissions error
def hello_world(request):
import firebase_admin
import flask
import json
from flask import request
from firebase_admin import credentials
from firebase_admin import firestore
try:
firebase_admin.initialize_app(options={
'apiKey': '<appkey>',
'authDomain': '<authdomain>',
'databaseURL': '<url>',
'projectId': '<projID>',
'storageBucket': '<bucket>',
'messagingSenderId': '<id>',
'appId': '<app ID>'
})
except:
print("DB already init")
#end db init
db = firestore.client()
# end db setup
I expect/want the result to be to initialize the DB so I can read/write to it, but I get an error:
Error: function crashed. Details:
403 Missing or insufficient permissions.
You seem to be using the app init settings for web, you need to use the sdk key instead. Go to Settings -> Services Account -> and generate your key.
Include the json file instead of those parameters. Hope this helps!

"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()

"Credentials from google.auth specified, but httplib2 needs to be installed" - Already installed

I am trying to set up OAuth2 login with Python/App Engine and had it working briefly until it suddenly stopped working. Log is showing the following:
'Credentials from google.auth specified, but '
ValueError: Credentials from google.auth specified, but google-api-python-client is unable to use these credentials unless google-auth-httplib2 is installed. Please install google-auth-httplib2.
I have httplib2 in my project's lib folder. I also tried installing with pip install google-auth-httplib2 but the error is still there.
Here is my login code:
import logging
import jinja2
import os
import webapp2
import httplib2
from apiclient.discovery import build
from oauth2client.contrib.appengine import OAuth2Decorator
from google.appengine.api import users
decorator = OAuth2Decorator(
client_id='REMOVED',
client_secret='REMOVED',
scope='https://www.googleapis.com/auth/plus.login')
service = build('plus', 'v1')
class MainHandler(webapp2.RequestHandler):
#decorator.oauth_aware
def get(self):
if decorator.has_credentials():
response = service.people().get(userId="me").execute(http=decorator.http())
# Write the profile data
self.response.write(unicode(response))
else:
url = decorator.authorize_url()
self.response.write('You must login : Go')
application = webapp2.WSGIApplication(
[
('/', MainHandler),
(decorator.callback_path, decorator.callback_handler())
],
debug=True) #remove debug=true before final
I could reproduce your case by mis configuring the requirements.txt [1]. I started the tests from this sample [2] about big query and modified to your scope. Here the ClientId and ClientSecret are in a json file. You can get the contents from that json from [3]. You need to create an OAuth Credential and copy the json content to your client_secret.json.
In the sample you can see a requirements.txt that lists the dependencies for the appengine application. Run the next command inside the folder where the sample lives to install all the dependencies on a local lib folder in the same path:
pip install -r requirements.txt -t lib/
My requirements.txt looks like:
google-api-python-client==1.6.4
google-auth==1.2.0
google-auth-httplib2==0.0.2
Then you can browse the dependencies for your project on that lib/ folder. In the root of the program, where the main.py habits, there is a file named appengine_config.py that loads the lib folder into your GAE Application and make you able to import those libraries on your Python program. The appengine_config.py looks like:
from google.appengine.ext import vendor
# Add any libraries installed in the "lib" folder.
vendor.add('lib')
Also, there is the client_secrets.json, where you need to place the contents about your clientId and your clientSecret.
Deploy your app with the same imports as the bigquery sample and you should get it to work.
gcloud app deploy
I’m sharing the modified code here. Hope it helps:
import json
import os
import googleapiclient.discovery
from oauth2client.contrib.appengine import
OAuth2DecoratorFromClientSecrets
import webapp2
# The project id whose datasets you'd like to list
PROJECTID = 'Your-project-id'
# Create the method decorator for oauth.
decorator = OAuth2DecoratorFromClientSecrets(os.path.join(os.path.dirname(__file__), 'client_secrets.json'),scope='https://www.googleapis.com/auth/bigquery')
#decorator = OAuth2DecoratorFromClientSecrets(os.path.join(os.path.dirname(__file__), 'client_secrets.json'),scope='https://www.googleapis.com/auth/plus.login')
# Create the bigquery api client
service = googleapiclient.discovery.build('bigquery', 'v2')
class MainPage(webapp2.RequestHandler):
# oauth_required ensures that the user goes through the OAuth2
# authorization flow before reaching this handler.
#decorator.oauth_required
def get(self):
# This is an httplib2.Http instance that is signed with the user's
# credentials. This allows you to access the BigQuery API on behalf
# of the user.
http = decorator.http()
response = service.datasets().list(projectId=PROJECTID).execute(http)
self.response.out.write('<h3>Datasets.list raw response:</h3>')
self.response.out.write('<pre>%s</pre>' % json.dumps(response, sort_keys=True, indent=4,separators=(',', ': ')))
class MainAware(webapp2.RequestHandler):
# credentials. This allows you to access the BigQuery API on behalf
# oauth_required ensures that the user goes through the OAuth2
# authorization flow before reaching this handler.
#decorator.oauth_aware
def get(self):
# This is an httplib2.Http instance that is signed with the user's
# credentials. This allows you to access the BigQuery API on behalf
# of the user.
if decorator.has_credentials():
http = decorator.http()
response = service.datasets().list(projectId=PROJECTID).execute(http)
self.response.out.write('<h3>Datasets.list raw response:</h3>')
self.response.out.write('<pre>%s</pre>' % json.dumps(response, sort_keys=True, indent=4,separators=(',', ': ')))
else:
url = decorator.authorize_url()
# Write a page explaining why authorization is needed,
# and provide the user with a link to the url to proceed.
# When the user authorizes, they get redirected back to this path,
# and has_credentials() returns True.
self.response.out.write(url)
app = webapp2.WSGIApplication([
('/', MainPage),
('/aware', MainAware),
# Create the endpoint to receive oauth flow callbacks
(decorator.callback_path, decorator.callback_handler())
], debug=True)
# [END all]
[1] https://cloud.google.com/appengine/docs/standard/python/getting-started/python-standard-env#setting_up_libraries_to_enable_development
[2] https://github.com/GoogleCloudPlatform/python-docs-samples/tree/master/appengine/standard/bigquery
[3] https://console.cloud.google.com/apis/credentials?project=your-project-id

Categories

Resources