Firebase Admin SDK: list_users() error INSUFFICIENT_PERMISSION - python

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

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

Cannot connect to firestore firebase in 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.

Azure App Registration is used for Authorization when securing a Python Http trigger Function App

I have a requirement where I will create a azure Http trigger using python function app.
For this function app I need to provide Authorization by using client Id or client Secret. Where the http link has to approved only with the client secret
I couldn't found any reference in python.
If any one has done this method can u show ur code for reference or guide me to solve this
Here's Microsoft documentation that you can use to get an idea of how to implement Azure AD Authentication into your Python Function App via code.
It includes other authentication methods also like Authentication with service principals, user credentials, AzureCliCredential or Managed Identity and DefaultAzureCredential.
Instead of facing difficulties in accessing the Client Id or Secret from Azure AD if you do not have access to it, you can store them in Azure Key Vault and access through Python Code in the same Azure Function App:
import os from azure.identity
import DefaultAzureCredential from azure.keyvault.secrets
import SecretClient
vault_url = os.environ["KEY_VAULT_URL"]
credential = DefaultAzureCredential()
secret_client = SecretClient(vault_url=vault_url, credential=credential)
retrieved_secret = secret_client.get_secret("secret-name-01")
And this Microsoft Blog Article presents you to register the Azure Python Function App with Azure AD using Azure CLI Commands and access the HTTP Trigger URL secured with the Client Id.

google.cloud.bigquery.Client() ignoring provided scopes, resulting in Permission denied while getting Drive credentials

I am trying to query data stored in Drive via the google.cloud.bigquery Python library.
I've followed Google's guide for Querying Drive Data.
Thus, my code looks like this:
import google.auth
from google.cloud import bigquery
credentials, project = google.auth.default(
scopes=[
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/bigquery",
]
)
client = bigquery.Client(project, credentials)
query = client.query("""MY SQL HERE""")
query_results = query.result()
The issue is: The credentials object and bigquery client ignores the provided scopes, resulting in google.api_core.exceptions.Forbidden: 403 Access Denied: BigQuery BigQuery: Permission denied while getting Drive credentials. To clarify, neither credentials nor client include the drive scope provided.
What can I do to properly pass the drive scope to my bigquery client?
My application default credentials for my local environment is my authorized user, which is the owner of the project.
Once you've set your application default credentials as an authorized user, you cannot request additional scopes.
To request additional scopes, do so during activation of your authorized user.
More plainly, when you run gcloud auth application-default login, provide the --scopes option, followed by your desired scopes. For me, that was gcloud auth application-default login --scopes=openid,https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/drive,https://www.googleapis.com/auth/bigquery
You should share the spreadsheet to the service account email, which you are trying to reach by.

Use Google API with a token [Django & AllAuth]

I am using AllAuth on my Django app to manage user authentication. With that my users can connect their Google accounts and i get a google API token (with appropriate scopes).
I would like to use that token to access google APIs (Calendar v3 in my case) with that token, as my user already used OAuth2 to sign-in on my website, and gave me access to the calendar API.
Google only gives the full process on their website (from auth to api), is there a way to build my idea, or is it simply impossible?
i have tries drive = build('calendar', 'v3', credentials=credentials) as said here but "credentials" needs to be part of an oauth2client and not just a simple string token.
Thank you for your precious time.
Simon
I know its an older question but I finally found something that worked for me. After a successful authentication with allauth, I did this to get the client token and then build the service.
from googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
from allauth.socialaccount.models import SocialToken, SocialApp
...
# request is the HttpRequest object
token = SocialToken.objects.get(account__user=request.user, account__provider='google')
credentials = Credentials(
token=token.token,
refresh_token=token.token_secret,
token_uri='https://oauth2.googleapis.com/token',
client_id='client-id', # replace with yours
client_secret='client-secret') # replace with yours
service = build('calendar', 'v3', credentials=credentials)

Categories