LoginSignup
8
4

More than 3 years have passed since last update.

firebase functionsはregionを間違えてもCORSになる

Last updated at Posted at 2020-03-16

発生したエラー

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
image.png

勘違いポイント

「functions cors」とぐぐるとこういう記事が出てくる
https://qiita.com/qrusadorz/items/40234ac0b5c5c2315cad

FirebaseのCloud Functionsには2つの関数があります。
1. functions.https.onCall
2. 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の違いに気づいたのはコンソールを見てた時
image.png
あれ、northeastに設定したはずなのにエラーはus-centralになってる、、?

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4