Firebase初始化报错:默认应用已存在问题求助
Firebase默认应用重复初始化错误解决
问题详情
代码中每次处理接口请求时都会初始化Firebase应用,导致触发以下错误:
ERROR 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.
涉及代码:
@event_routes.route('/scanner/events', methods=['GET'], cors=True) def get_scanner_events() -> Response: try: id_token = event_routes.current_request.headers["IdToken"] except KeyError: return Response(body={"message": "missing id token for authentication"}, status_code=400, headers={"Content-Type": "application/json"}) # add json content (dict) try: GOOGLE_APPLICATION_CREDENTIALS = json.loads(os.getenv("GOOGLE_APPLICATION_CREDENTIALS", "")) TEST_GOOGLE_PRIVATE_KEY = os.getenv("TEST_GOOGLE_PRIVATE_KEY", "").replace(r'\n', '\n') GOOGLE_APPLICATION_CREDENTIALS['private_key'] = TEST_GOOGLE_PRIVATE_KEY cred = firebase_admin.credentials.Certificate(GOOGLE_APPLICATION_CREDENTIALS) firebase_app = firebase_admin.initialize_app(credential=cred) value = firebase_admin.auth.verify_id_token(id_token) # print("made it here") print(firebase_app.project_id) except auth.InvalidIdTokenError as e: print("InvalidIdTokenError") return Response(body={"message": "invalid id token"}, status_code=400, headers={"Content-Type": "application/json"})
解决方案
核心原因
Firebase默认应用只能初始化一次,你的代码在每次接口请求时都会调用initialize_app(),重复执行就会触发该错误。
修复方案1:启动时一次性初始化(推荐)
把Firebase应用初始化逻辑移到接口函数外部,在服务启动时仅执行一次:
# 放在文件顶部,服务启动时执行 import firebase_admin from firebase_admin import credentials, auth import json import os # 初始化Firebase应用 GOOGLE_APPLICATION_CREDENTIALS = json.loads(os.getenv("GOOGLE_APPLICATION_CREDENTIALS", "")) TEST_GOOGLE_PRIVATE_KEY = os.getenv("TEST_GOOGLE_PRIVATE_KEY", "").replace(r'\n', '\n') GOOGLE_APPLICATION_CREDENTIALS['private_key'] = TEST_GOOGLE_PRIVATE_KEY cred = credentials.Certificate(GOOGLE_APPLICATION_CREDENTIALS) # 检查是否已有初始化的应用,避免重复创建 if not firebase_admin._apps: firebase_admin.initialize_app(cred) # 接口函数保持原有逻辑,移除内部初始化代码 @event_routes.route('/scanner/events', methods=['GET'], cors=True) def get_scanner_events() -> Response: try: id_token = event_routes.current_request.headers["IdToken"] except KeyError: return Response(body={"message": "missing id token for authentication"}, status_code=400, headers={"Content-Type": "application/json"}) try: value = auth.verify_id_token(id_token) # 获取已初始化的默认应用实例 print(firebase_admin.get_app().project_id) except auth.InvalidIdTokenError as e: print("InvalidIdTokenError") return Response(body={"message": "invalid id token"}, status_code=400, headers={"Content-Type": "application/json"})
修复方案2:函数内检查应用是否存在
如果必须在接口函数内处理初始化,先判断默认应用是否已创建:
@event_routes.route('/scanner/events', methods=['GET'], cors=True) def get_scanner_events() -> Response: try: id_token = event_routes.current_request.headers["IdToken"] except KeyError: return Response(body={"message": "missing id token for authentication"}, status_code=400, headers={"Content-Type": "application/json"}) try: GOOGLE_APPLICATION_CREDENTIALS = json.loads(os.getenv("GOOGLE_APPLICATION_CREDENTIALS", "")) TEST_GOOGLE_PRIVATE_KEY = os.getenv("TEST_GOOGLE_PRIVATE_KEY", "").replace(r'\n', '\n') GOOGLE_APPLICATION_CREDENTIALS['private_key'] = TEST_GOOGLE_PRIVATE_KEY cred = firebase_admin.credentials.Certificate(GOOGLE_APPLICATION_CREDENTIALS) # 检查默认应用是否存在,不存在才初始化 if not firebase_admin._apps: firebase_app = firebase_admin.initialize_app(cred) else: firebase_app = firebase_admin.get_app() value = firebase_admin.auth.verify_id_token(id_token) print(firebase_app.project_id) except auth.InvalidIdTokenError as e: print("InvalidIdTokenError") return Response(body={"message": "invalid id token"}, status_code=400, headers={"Content-Type": "application/json"})
关键说明
- 方案1性能更优,因为初始化是耗时操作,无需每次请求重复执行。
firebase_admin._apps是Firebase内部存储所有应用实例的集合,通过它可以快速判断是否已有初始化的应用。- 只有在需要同时连接多个Firebase项目时,才需要给
initialize_app()传入唯一名称作为第二个参数(如initialize_app(cred, name="secondary-app")),常规场景使用默认应用即可。
内容的提问来源于stack exchange,提问作者guiguilecodeur
相关产品推荐
相关产品推荐

