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

Firebase实时数据库:能否用set()写入API返回的JSON数据?

问题:Firebase实时数据库写入无效果,无法存储足球API数据

我正在开发一款展示足球实时数据的应用,后端从API获取JSON格式的足球数据,希望将其存入Firebase实时数据库以实现应用内的实时数据展示。数据库顶层需为固定时间区间的日期,每个日期下嵌套API返回的JSON数据。目前尝试使用set()方法写入数据,但没有任何效果,以下是我的代码实现及API请求方法:

import { initializeApp } from "firebase/app";
import { getDatabase, ref, set } from "firebase/database";
import { getDates } from './dates.js';
import { getDataApi, getCurrentSeason } from './api_manager.js';
import { idList } from '../data/data.js';

const firebaseConfig = {
...
};

const app = initializeApp(firebaseConfig);
const db = getDatabase();

function update() {
    var startDate = new Date();
    var season = getCurrentSeason().then(val => val);
    var datesArr = getDates(startDate, 7);

    datesArr.forEach(date => {
        idList.forEach(id => {
            const reference = ref(db, `${date}/${id}`);
            var data = getDataApi(date, id, season);
            set(reference, data);
        });
    });
}

update();

以下是从API获取数据的方法:

import fetch from 'node-fetch';

const options = {
  method: 'GET',
  headers: {
    ...
  }
};

export async function getDataApi(date, leagueId, season) {
    const url = `https://api-football-v1.p.rapidapi.com/v3/fixtures?date=${date}&league=${leagueId}&season=${season}`;

    try {
        let response = await fetch(url, options);
        let json = await response.json();
        return json['response'];
    } catch (error) {
        console.log("Error: " + error);
    }
}

export async function getCurrentSeason() {
    const url = 'https://api-football-v1.p.rapidapi.com/v3/leagues?id=39&current=true';
    try {
        let response = await fetch(url, options);
        let json = await response.json();
        return json['response'][0]['seasons'][0]['year'];
    } catch (error) {
        console.log("Error: " + error);
    }
}

问题分析与解决方案

核心问题

代码存在异步处理错误,导致set()方法未拿到有效数据就执行写入,同时循环未等待异步操作完成,引发一系列问题:

  • getCurrentSeason()是异步函数,直接赋值得到的是Promise对象,而非实际赛季年份,导致API请求参数错误;
  • getDataApi()返回Promise,直接传给set()会写入无效的Promise对象,而非API返回的JSON数据;
  • forEach不支持异步等待,所有请求和写入同时触发,可能触发限流或未正确处理结果。

修复后的代码

将update改为异步函数,用await处理所有异步操作,改用for...of循环支持异步等待:

import { initializeApp } from "firebase/app";
import { getDatabase, ref, set } from "firebase/database";
import { getDates } from './dates.js';
import { getDataApi, getCurrentSeason } from './api_manager.js';
import { idList } from '../data/data.js';

const firebaseConfig = {
...
};

const app = initializeApp(firebaseConfig);
const db = getDatabase();

async function update() {
    const startDate = new Date();
    // 等待获取真实的赛季年份
    const season = await getCurrentSeason();
    const datesArr = getDates(startDate, 7);

    // 使用for...of确保每一步异步操作完成后再执行下一步
    for (const date of datesArr) {
        for (const id of idList) {
            const reference = ref(db, `${date}/${id}`);
            // 等待API返回数据
            const data = await getDataApi(date, id, season);
            // 有数据才写入,避免空值
            if (data) {
                await set(reference, data);
                console.log(`成功写入:${date}/${id}`);
            } else {
                console.log(`无数据:${date}/${id}`);
            }
        }
    }
}

// 捕获整个流程的错误,便于排查
update().catch(error => {
    console.error("更新失败:", error);
});

额外优化建议

  • 权限检查:确认Firebase实时数据库的安全规则允许写入,测试阶段可临时设置开放规则(上线前必须修改为严格规则):
    {
      "rules": {
        ".read": true,
        ".write": true
      }
    }
    
  • 限流处理:若API或Firebase有请求频率限制,可在循环中添加延迟,避免触发限流:
    await new Promise(resolve => setTimeout(resolve, 1000)); // 每次请求间隔1秒
    
  • 参数验证:确保date格式为YYYY-MM-DD(符合API要求),idList中的联赛ID正确,避免API返回空数据。

内容的提问来源于stack exchange,提问作者bragi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 06:46:08