You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将结构化JSON对象数组正确上传至Firestore并解决文档覆盖问题?

问题分析与解决方案

你的代码主要有两个核心问题导致数据被覆盖:

  1. 错误处理了原始JSON结构:你用groupby处理加载后的JSON字典,但sorted(contents)只会排序字典的键(比如object1、object2),而不是遍历每个object下的数据数组,导致后续的数据分组逻辑完全错误。
  2. 文档引用重复创建与覆盖:你在每个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)

关键修正点说明

  1. 正确遍历原始JSON:
    原始JSON是一个字典,键为object1、object2,对应的值是数据数组。用contents.items()直接遍历每个object名称及其对应的数据数组,无需额外分组。

  2. 为每条数据创建独立文档:
    将文档ID的生成逻辑移到数据条目的循环内部,这样每条数据都会生成一个新的上传时间戳,避免文档被重复覆盖。如果希望用数据自带的date作为文档ID,只需将upload_timestamp替换为:

    # 替换date中的/为-,符合Firestore文档ID的规则
    doc_id = item['date'].replace('/', '-')
    
  3. 正确写入数据:
    调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 17:07:47