Python中Firebase实时数据库与Storage默认应用冲突问题求助
我同时使用Firebase实时数据库和Firebase Storage时遇到了默认应用相关问题:Storage命令会指向作为默认应用的数据库应用,导致无法找到所需数据。
原代码
!pip install pygsheets import pygsheets import pandas as pd from datetime import datetime import pytz from pydrive.auth import GoogleAuth from google.colab import drive from pydrive.drive import GoogleDrive from google.colab import auth from oauth2client.client import GoogleCredentials from firebase_admin import credentials, initialize_app, storage, db import matplotlib.pyplot as plt cred = credentials.Certificate('key.json') database = initialize_app(cred, {'databaseURL': "https://project-147196781260390231-default-rtdb.europe-west1.firebasedatabase.app/"}) imgStorage = initialize_app(cred, {'storageBucket': 'project-147196781260390231.appspot.com'}, name = 'bucket') dt = datetime.now(cairoTz) y = dt.year M = dt.month d = dt.day h = dt.hour m = dt.minute s = dt.second lhour = df.loc[(df['Hour'] == h) | ((df['Hour'] == h - 1) & (df['Minute'] >= m))] lday = df.loc[(df['Day'] == d)| ((df['Day'] == d - 1) & (df['Hour'] >= h))] lall = df tempHplt = plt.figure(figsize=(10, 3)) tempHplt_name = 'tempHplt.png' xTemph = lhour['Minute'].astype(int).astype(str) yTemph = lhour['Temperature'] plt.plot(xTemph, yTemph) plt.savefig('tempHplt.png') file_path = tempHplt_name bucket = storage.bucket() # storage bucket blob = bucket.blob(file_path) blob.upload_from_filename(file_path)
遇到的错误
尝试从初始化的App变量调用storage函数时,出现如下错误:
AttributeError: 'App' object has no attribute 'storage'
如果不使用该变量,直接调用则出现以下错误:
ValueError: Storage bucket name not specified. Specify the bucket name via the "storageBucket" option when initializing the App, or specify the bucket name explicitly when calling the storage.bucket() function.
解决方案
方案一:明确指定Storage对应的应用实例
问题出在storage.bucket()默认会使用第一个初始化的默认应用(也就是只配置了数据库的database实例),而这个实例没有Storage桶的配置。你需要在调用storage.bucket()时,传入专门配置了Storage的imgStorage实例:
修改代码中上传Storage的部分:
file_path = tempHplt_name # 明确传入配置了Storage桶的应用实例 bucket = storage.bucket(app=imgStorage) blob = bucket.blob(file_path) blob.upload_from_filename(file_path)
方案二:合并配置到单个默认应用(更简洁)
如果你的项目不需要多个Firebase应用实例,直接在初始化默认应用时同时配置数据库URL和Storage桶,这样后续调用storage.bucket()和db.reference()都不需要额外指定应用:
修改初始化应用的代码:
cred = credentials.Certificate('key.json') # 单个应用同时配置数据库和Storage default_app = initialize_app(cred, { 'databaseURL': "https://project-147196781260390231-default-rtdb.europe-west1.firebasedatabase.app/", 'storageBucket': 'project-147196781260390231.appspot.com' }) # 后续调用无需指定应用,直接使用默认实例 # 数据库操作示例 ref = db.reference('path/to/data') # Storage操作示例 bucket = storage.bucket()
核心原因
Firebase Admin SDK中,所有服务(storage、db等)默认都会绑定到第一个初始化的未命名应用。你第一个初始化的database应用只配置了数据库参数,没有Storage桶信息,所以直接调用storage.bucket()会提示缺少桶配置;而App对象本身并没有storage属性,所以直接调用imgStorage.storage会报错。
内容的提问来源于stack exchange,提问作者Mostafa Atef

