⬇️
Cloud FunctionsによるAPI結果の取得と保存
この記事では、Firebase Cloud Functionsを使用して、APIからフィクスチャ(試合)の統計データを取得し、Firestoreに保存する方法を紹介します。以下のコードは、指定された年と月のフィクスチャIDを取得し、それぞれのフィクスチャIDに対して統計データをAPIから取得してFirestoreに保存するものです。
前提条件
- Firebaseプロジェクトが設定されていること。
- Firestoreが有効化されていること。
- RapidAPIのAPIキーが取得されていること。
-
firebase-admin
とfirebase-functions
パッケージがインストールされていること。
コードの説明
以下がCloud Functionsのコードです。
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const fetch = require('node-fetch');
admin.initializeApp();
exports.fetchAndSaveFixtureStatistics = functions.https.onRequest(async (req, res) => {
// リクエストから年と月を取得
const year = req.query.year;
const month = req.query.month;
if (!year || !month) {
return res.status(400).send('Year and month are required.');
}
// Firestoreからすべてのfixtureデータを取得
const docRef = admin.firestore().collection('matchResults').doc("39");
const doc = await docRef.get();
if (!doc.exists) {
return res.status(404).send('No document found.');
} else {
const data = doc.data();
const fixtureInfos = data["2023_2024"]; // 2023-2024 シーズンのデータを取得
const selectedYearMonth = `${year}-${month.padStart(2, '0')}`; // YYYY-MM 形式
const fixtureIds = fixtureInfos.filter(f => f.kickoffTime.startsWith(selectedYearMonth)).map(f => f.id);
if (fixtureIds.length === 0) {
return res.status(404).send('No fixtures found for the specified year and month.');
}
console.info(fixtureIds);
for (let fixtureId of fixtureIds) {
fixtureId = String(fixtureId);
const url = `https://api-football-v1.p.rapidapi.com/v3/fixtures/statistics?fixture=${fixtureId}`;
const options = {
method: 'GET',
headers: {
'X-RapidAPI-Key': 'YOUR_RAPIDAPI_KEY',
'X-RapidAPI-Host': 'api-football-v1.p.rapidapi.com'
}
};
try {
const response = await fetch(url, options);
const result = await response.json();
if (!result.response || result.response.length === 0) {
throw new Error('No statistics data found for fixture ID: ' + fixtureId);
}
const statisticsInfos = result.response.map(teamStat => {
if (!teamStat.team || !teamStat.statistics) {
throw new Error('Invalid data structure for team statistics');
}
return {
teamId: teamStat.team.id,
teamName: teamStat.team.name,
teamLogo: teamStat.team.logo,
statistics: teamStat.statistics.map(stat => ({
type: stat.type,
value: stat.value !== null ? stat.value : "N/A" // Handling null values
}))
};
});
await admin.firestore().collection('fixtureStatistics').doc(fixtureId).set({ teams: statisticsInfos });
} catch (error) {
console.error('Error fetching or processing data for fixture:', fixtureId, error);
return res.status(500).send('Error processing fixture ID ' + fixtureId + ': ' + error.message);
}
}
res.status(200).send('All fixture statistics fetched and saved successfully!');
}
});
コードの詳細
firebase-admin
の設定と初期化
firebase-admin
は、Firebaseプロジェクトとやり取りするための管理SDKです。これにより、Firebase Authentication、Firestore、Realtime Databaseなどのサービスにアクセスできます。以下は、firebase-admin
の初期化部分です。
const admin = require('firebase-admin');
admin.initializeApp();
このコードは、デフォルトのアプリケーション認証情報を使用して、Firebase Admin SDKを初期化します。これにより、Firebaseのサービスにアクセスできるようになります。
リクエストから年と月を取得
リクエストのクエリパラメータからyear
とmonth
を取得します。これらが存在しない場合は、400エラーを返します。
const year = req.query.year;
const month = req.query.month;
if (!year || !month) {
return res.status(400).send('Year and month are required.');
}
Firestoreからデータを取得
matchResults
コレクションのドキュメントを取得します。この例ではドキュメントIDは"39"です。
const docRef = admin.firestore().collection('matchResults').doc("39");
const doc = await docRef.get();
if (!doc.exists) {
return res.status(404).send('No document found.');
}
フィクスチャIDをフィルタリング
取得したデータから指定された年と月に一致するフィクスチャIDを抽出します。
const data = doc.data();
const fixtureInfos = data["2023_2024"]; // 2023-2024 シーズンのデータを取得
const selectedYearMonth = `${year}-${month.padStart(2, '0')}`; // YYYY-MM 形式
const fixtureIds = fixtureInfos.filter(f => f.kickoffTime.startsWith(selectedYearMonth)).map(f => f.id);
if (fixtureIds.length === 0) {
return res.status(404).send('No fixtures found for the specified year and month.');
}
統計データの取得と保存
各フィクスチャIDに対してAPIから統計データを取得し、fixtureStatistics
コレクションに保存します。
for (let fixtureId of fixtureIds) {
fixtureId = String(fixtureId);
const url = `https://api-football-v1.p.rapidapi.com/v3/fixtures/statistics?fixture=${fixtureId}`;
const options = {
method: 'GET',
headers: {
'X-RapidAPI-Key': 'YOUR_RAPIDAPI_KEY',
'X-RapidAPI-Host': 'api-football-v1.p.rapidapi.com'
}
};
try {
const response = await fetch(url, options);
const result = await response.json();
if (!result.response || result.response.length === 0) {
throw new Error('No statistics data found for fixture ID: ' + fixtureId);
}
const statisticsInfos = result.response.map(teamStat => {
if (!teamStat.team || !teamStat.statistics) {
throw new Error('Invalid data structure for team statistics');
}
return {
teamId: teamStat.team.id,
teamName: teamStat.team.name,
teamLogo: teamStat.team.logo,
statistics: teamStat.statistics.map(stat => ({
type: stat.type,
value: stat.value !== null ? stat.value : "N/A" // Handling null values
}))
};
});
await admin.firestore().collection('fixtureStatistics').doc(fixtureId).set({ teams: statisticsInfos });
} catch (error) {
console.error('Error fetching or processing data for fixture:', fixtureId, error);
return res.status(500).send('Error processing fixture ID ' + fixtureId + ': ' + error.message);
}
}
res.status(200).send('All fixture statistics fetched and saved successfully!');
注意点
- APIキーはセキュアな場所に保管し、環境変数などを使用してコード内で参照することを推奨します。
- エラーハンドリングを適切に行い、ユーザーに対して適切なエラーメッセージを返すようにします。
このコードを実装することで、指定された年と月のフィクスチャ統計データを効率的に取得し、Firestoreに保存することができます。
Discussion