Firebase Cloud Functions部署报错:无法更新Firestore用户checkoutTotal字段
Firebase Cloud Functions部署报错及修复方案
需求说明
Firestore中存在Users集合,每个用户文档下包含Checkout子集合。需要实现一个Cloud Function:
- 函数名:
update_total_value - 触发时机:当
Checkout子集合内的文档发生增删改操作时 - 功能:遍历子集合内所有商品,计算
price * quantity的总和,更新对应用户文档的checkoutTotal字段
原代码(main.py)
import firebase_admin import firebase_functions def initialize_app(): """Initializes the Firebase Admin SDK.""" firebase_admin.initialize_app() def update_total_value(event, context): """Updates the totalValue field in the users database with the multiplication of price and quantity of each item in the checkout and then adds all the values inside the checkout, in order to give the total value of all checkout items of each user.""" # Get the user ID from the event context. user_id = context.params["user_id"] # Get a reference to the checkout subcollection of the user document. checkout_ref = firestore.client().collection("users").document(user_id).collection("checkout") # Get a list of all documents in the checkout subcollection. checkout_docs = checkout_ref.get() # Calculate the total value of the user's checkout by summing the price * quantity fields of all documents in the checkout subcollection. total_value = 0 for doc in checkout_docs: total_value += doc.data()["price"] * doc.data()["quantity"] # Update the user document in the users collection with the total value of the checkout. user_ref = firebase_admin.firestore.client().collection("users").document(user_id) user_ref.update({"checkoutTotal": total_value}) # Initialize the Firebase Admin SDK. initialize_app() # Deploy the Cloud Function. firebase_admin.functions.on_firestore_write(update_total_value)
错误信息
[2023-11-02 14:40:09,933] ERROR in app: Exception on /__/functions.yaml [GET] Traceback (most recent call last): File "C:\Users\guilh\myproject\functions\venv\Lib\site-packages\flask\app.py", line 2190, in wsgi_app response = self.full_dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\guilh\myproject\functions\venv\Lib\site-packages\flask\app.py", line 1486, in full_dispatch_request rv = self.handle_user_exception(e) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\guilh\myproject\functions\venv\Lib\site-packages\flask\app.py", line 1484, in full_dispatch_request rv = self.dispatch_request() ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\guilh\myproject\functions\venv\Lib\site-packages\flask\app.py", line 1469, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\guilh\myproject\functions\venv\Lib\site-packages\firebase_functions\private\serving.py", line 122, in get_functions_yaml functions = get_functions() ^^^^^^^^^^^^^^^ File "C:\Users\guilh\myproject\functions\venv\Lib\site-packages\firebase_functions\private\serving.py", line 40, in get_functions spec.loader.exec_module(module) File "<frozen importlib._bootstrap_external>", line 940, in exec_module File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed File "C:\Users\guilh\myproject\functions\main.py", line 34, in <module> firebase_admin.functions.on_firestore_write(update_total_value) ^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: module 'firebase_admin' has no attribute 'functions' 127.0.0.1 - - [02/Nov/2023 14:40:09] "GET /__/functions.yaml HTTP/1.1" 500 - 127.0.0.1 - - [02/Nov/2023 14:40:09] "GET /__/quitquitquit HTTP/1.1" 200 - Error: Functions codebase could not be analyzed successfully. It may have a syntax or runtime error
问题分析与修复方案
核心错误点
- 触发函数调用错误:
firebase_admin模块没有functions属性,Firestore触发器属于firebase_functions模块,且触发逻辑不能放在函数内部,必须用装饰器语法定义在函数外部。 - Admin SDK初始化错误:初始化逻辑被封装在函数内且在函数执行时调用,正确做法是在模块最外层初始化一次即可。
- 缺少Firestore导入:代码中直接使用
firestore.client()但未导入对应模块,会导致运行时错误。 - 触发器路径未指定:需要明确指定触发的Firestore路径,包含用户ID通配符以匹配所有用户的Checkout子集合。
修复后的完整代码
import firebase_admin from firebase_admin import firestore import firebase_functions # 初始化Firebase Admin SDK,在模块最外层执行一次 firebase_admin.initialize_app() @firebase_functions.firestore.document("users/{user_id}/checkout/{item_id}") def update_total_value(event, context): """计算用户Checkout子集合商品总价,更新用户文档的checkoutTotal字段""" user_id = context.params["user_id"] # 获取用户Checkout子集合引用 checkout_ref = firestore.client().collection("users").document(user_id).collection("checkout") checkout_docs = checkout_ref.stream() total_value = 0 for doc in checkout_docs: data = doc.data() # 兼容字段缺失的情况,避免报错 total_value += data.get("price", 0) * data.get("quantity", 0) # 更新用户文档的checkoutTotal字段 user_ref = firestore.client().collection("users").document(user_id) user_ref.update({"checkoutTotal": total_value})
关键修复说明
- 使用
@firebase_functions.firestore.document()装饰器指定触发路径,{user_id}和{item_id}是通配符,匹配任意用户的Checkout子集合内的任意文档。 - 将Admin SDK初始化移到模块最外层,确保只执行一次。
- 导入
firestore模块并正确使用firestore.client()。 - 添加
data.get()方法处理字段缺失的情况,避免函数因数据异常崩溃。
内容的提问来源于stack exchange,提问作者Guilherme Teixeira
相关产品推荐
相关产品推荐

