如何将结构化JSON对象数组正确上传至Firestore并解决文档覆盖问题?
问题分析与解决方案
你的代码主要有两个核心问题导致数据被覆盖:
- 错误处理了原始JSON结构:你用
groupby处理加载后的JSON字典,但sorted(contents)只会排序字典的键(比如object1、object2),而不是遍历每个object下的数据数组,导致后续的数据分组逻辑完全错误。 - 文档引用重复创建与覆盖:你在每个object的循环外只生成一次上传时间戳作为文档ID,然后在遍历数据时反复调用
set()覆盖同一个文档,最终只保留了最后一条数据。
修正后的完整代码
import firebase_admin from firebase_admin import credentials from firebase_admin import firestore import json import datetime from datetime import date # 初始化Firebase cred = credentials.Certificate("myAppCreds.json") firebase_admin.initialize_app(cred, { 'projectId': "MyProjectID", }) db = firestore.client() # 加载JSON数据 json_file_path = "./myfile.json" with open(json_file_path, 'r') as j: contents = json.loads(j.read()) # 获取今日日期作为集合名称 today = date.today() d1 = today.strftime("%d.%m.%Y") # 遍历外层的每个Object(object1、object2等) for object_name, data_items in contents.items(): # 遍历当前Object下的每一条数据 for item in data_items: # 为每条数据生成唯一的上传时间戳作为文档ID(或用item['date']替换,注意格式转换) upload_timestamp = str(datetime.datetime.now()) # 构建Firestore路径:Objects/{object_name}/{今日日期}/{上传时间戳} doc_ref = db.collection('Objects').document(object_name).collection(d1).document(upload_timestamp) # 将当前数据写入文档 doc_ref.set(item)
关键修正点说明
正确遍历原始JSON:
原始JSON是一个字典,键为object1、object2,对应的值是数据数组。用contents.items()直接遍历每个object名称及其对应的数据数组,无需额外分组。为每条数据创建独立文档:
将文档ID的生成逻辑移到数据条目的循环内部,这样每条数据都会生成一个新的上传时间戳,避免文档被重复覆盖。如果希望用数据自带的date作为文档ID,只需将upload_timestamp替换为:# 替换date中的/为-,符合Firestore文档ID的规则 doc_id = item['date'].replace('/', '-')正确写入数据:
调用doc_ref.set(item)将整条数据对象写入文档,而不是错误地传入keys参数。
可选优化
- 如果希望文档ID更简洁或避免重复,可以使用Firestore的自动生成ID:
# 不指定文档ID,让Firestore自动生成 doc_ref = db.collection('Objects').document(object_name).collection(d1).document() doc_ref.set(item) - 批量写入:如果数据量很大,使用Firestore的批量写入可以提升效率,避免频繁的网络请求:
batch = db.batch() for object_name, data_items in contents.items(): for item in data_items: doc_ref = db.collection('Objects').document(object_name).collection(d1).document() batch.set(doc_ref, item) batch.commit()
内容的提问来源于stack exchange,提问作者Leonardo Felix da Silva
相关产品推荐
相关产品推荐

