Search code examples
firebasegoogle-cloud-functionsangularfire

AngularFire: how do I connect to deployed Cloud functions in a preview channel? (CORS)


I have an AngularFire project where I use Cloud Functions' onCall to define a few server-side functions. I deployed the latest version of those functions to my domain (using firebase deploy --only functions). Then I deployed a preview channel (using firebase:hosting:channel:deploy). When I try to use the functions in the preview channel, I get a CORS error:

"Access to fetch at [my function URL] from origin [my preview channel URL] has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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."

How do I convince my app in the preview channel to connect to my domain's Cloud Functions?


Solution

  • The basic behavior of the app and server seem to be as follows:

    1. App sends out an OPTIONS request (called 'preflight request' by Chrome). The OPTIONS request contains an origin of the preview channel URL. The host is the functions URL.
    2. Cloud Functions responds with a header that is missing Access-Control-Allow-Origin.

    The problematic response from Cloud Functions is the immediate cause of the error.

    The solution is apparently to change AngularFire's ORIGIN setting for Functions to the preview URL, describe at the end of this documentation. That seems to result in this behavior:

    1. App sends out an OPTIONS request (called 'preflight request' by Chrome). The OPTIONS request contains an origin of the preview channel URL. The host is the preview channel URL. (Although called ORIGIN, ORIGIN seems to change the host request header.)
    2. Cloud Functions responds with a header that includes Access-Control-Allow-Origin.

    The overall steps to successful deployment to a preview channel using AngularFire seem to be:

    1. Deploy your latest functions to your regular app domain using firebase deploy --only functions.
    2. Deploy your app to a preview channel using firebase:hosting:channel:deploy.
    3. Take note of the preview channel URL returned.
    4. Wherever you set the ORIGIN for your functions, use the preview channel URL instead of your normal app domain.
    5. Deploy your app to the preview channel again using firebase:hosting:channel:deploy.