発生したエラー
Access to fetch at 'https://us-central1-twohundred-dcb3e.cloudfunctions.net/createMeetings' from origin 'https://twohundred-dcb3e.web.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
POST https://us-central1-twohundred-dcb3e.cloudfunctions.net/createMeetings net::ERR_FAILED
Error: internal
at new e (3b338370d3d4d0f079e3.js:2)
at 3b338370d3d4d0f079e3.js:2
at t.<anonymous> (3b338370d3d4d0f079e3.js:2)
at 3b338370d3d4d0f079e3.js:2
at Object.next (3b338370d3d4d0f079e3.js:2)
at c (3b338370d3d4d0f079e3.js:2)
やったこと
Nuxt+Vueでwebアプリを作るとき、firebase functionsをAPIとして利用した。
API
functions/index.js
exports.createMeetings = functions
.region('asia-northeast1')
.https.onCall(async (data, context) => {
// 省略
} catch (e) {
console.error(new Error(e));
return new functions.https.HttpsError('internal', e.message);
}
});
クライアント
store/index.js
async ADD_MEETING_URL({ commit }, { lunch }) {
const store = firebase.firestore();
// 正しくない
// const functions = firebase.functions();
// 正しい
const functions = firebase.app().functions('asia-northeast1');
const response = await functions.httpsCallable('createMeetings')(body);
await store
.collection('Lunches')
.doc(lunch.id)
.set(
{
startURL,
joinURL
},
{ merge: true }
);
},
エラー原因
- API側ではregionをnortheastに設定した
- にもかかわらずクライアント側でfunctionsのregionを指定してなかった
- デフォルトのus-centralにアクセスされてしまいCORSになった
公式ドキュメントにちゃんと注意書きされてた。。。
https://firebase.google.com/docs/functions/locations?hl=ja
勘違いポイント
「functions cors」とぐぐるとこういう記事が出てくる
https://qiita.com/qrusadorz/items/40234ac0b5c5c2315cad
FirebaseのCloud Functionsには2つの関数があります。
- functions.https.onCall
- functions.https.onRequest
1はSDKが用意されているAndroid,iOS,Javascriptから呼び出されるタイプ。
https://firebase.google.com/docs/functions/callable?hl=ja
2はSDKがない場合、汎用のWebAPIとして作成するタイプ。
https://firebase.google.com/docs/functions/http-events?hl=ja
タイトルのCORSが~といわれるのは2のタイプで作成していて、レスポンスにCORSのためのヘッダーが設定されていないため。
1を利用した場合、その辺の面倒な部分は内部で処理して利用者が意識しなくていいようです。
あれ、でも自分はonCall
を使ってるからCORSにはならないはず、、?
そうか、開発環境でlocalhostからアクセスしてるからか!と思いきや
if (process.env.NODE_ENV === 'development') {
functions.useFunctionsEmulator('http://localhost:5001');
}
API側を上記のように修正してもエラーに変化なし。onCall
は優秀だからlocalhostでもCORSにはならないはず
結局regionの違いに気づいたのはコンソールを見てた時
あれ、northeastに設定したはずなのにエラーはus-centralになってる、、?