TypeScript & React & Firebase で何かつくってみる5 Functions 2
書きやすい今のうちに 5日連続投稿のバッチをもらっておくか.
しかしこのバッチ,最大で365日連続投稿まであるのか... 絶対無理だな.
Functions で Firestore を操作する
これができなきゃ話にならない.
firebase-admin というパッケージを使えばいいらしい. 上記サイトでは 個別にインストールしているが, 既に入っていた. おそらく `firebase init functions` のタイミングで入ったのだろう.
これを使って前回のトランプ52枚をシャッフルするAPIを作ってみた. シャッフルの実装はこちらのコードをコピペ.
トランプの束があり,これをシャッフルしたいとしましょう.束の中からランダムに 1 枚ずつ選び,束の隣に新しい束(シャッフル済の束)として重ねていきます.これが Fisher–Yates シャッフルです.
まさにそのものズバリ. ・・・スワップのやり方ちょっとカッコいいな.
index.ts
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp();
const fireStore = admin.firestore();
type Card = {
name: string,
color: string,
}
type Deck = {
cards: Card[],
}
// https://chooblarin.github.io/post/array-shuffle
const shuffleArray = ([...arr]) => {
let m = arr.length;
while (m) {
const i = Math.floor(Math.random() * m--);
[arr[m], arr[i]] = [arr[i], arr[m]];
}
return arr;
};
export const shuffle = functions.https.onRequest((request, response) => {
const deckRef = fireStore.collection('fields').doc('deck');
deckRef.get().then(snapshot => {
const deck = snapshot.data() as Deck;
return deckRef.update({ cards: shuffleArray(deck.cards) });
}).then(snapshot => {
response.send('success');
}).catch(err => {
response.status(404).send('not found');
});
});
参考記事では admin にクライアント同様 API キー を渡しているようだったが, 本家のドキュメントを見る限り必要なさそうだ. さすが admin.
あとはこの Function URL にリクエストを出すボタンを UI におけばいいはず.
ちなみにこの関数はHTTPメソッドを見ていない. おそらくどのメソッドを投げてもシャッフルするのだろう.
GETメソッドで関数実行なんて行儀悪い? まぁそういうのは後で考える.
Console エラー
Chromeのコンソールにエラーが出ている.
Access to fetch at 'https://XXXX' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
CORSの問題か.
CORSは厳密に言えば「通信を不許可」にしているのではなく, JavaScript がHTTPレスポンスにアクセスすることを禁止するだけだ.
つまり命令はサーバに届いている. だからクロスドメインでも関数が実行できているというわけだ.
ちゃんとしたサービスならセキュリティホールだな.
まさか localhost からのアクセスを許可するわけにもいかんし, Firebase Hosting 上に置いてしまえば発生しないだろうし, ひとまずほっとくことにする.
この記事が気に入ったらサポートをしてみませんか?