2

I'm adding callable functions to an existing Angular/Firebase project. I've used what I believe to be the current configuration standards, but the project is still calling the production endpoints, leading to a cors exception.

configuration:

@NgModule({
  declarations: [
    AppComponent,
    routingComponents,
    ...
  ],
  imports: [
    ...
    provideFirebaseApp(() => initializeApp(environment.firebase)),
    provideAuth(() => {
      const auth = getAuth();
      if (environment.useEmulators) {
        connectAuthEmulator(auth, 'http://localhost:5005', { disableWarnings: true });
      }
      return auth;
    }),

-- FUNCTIONS CONFIG CODE --

    provideFunctions(() => {
      const functions = getFunctions();
      if (environment.useEmulators) {
        connectFunctionsEmulator(functions, 'localhost', 5001);
      }
      return functions;
    }),

-- FUNCTIONS CONFIG CODE --

    provideFirestore(() => {
      const firestore = getFirestore();
      if (environment.useEmulators) {
        connectFirestoreEmulator(firestore, 'localhost', 5006);
      }
      return firestore;
    }),
    //provideStorage(() => getStorage()),
    provideAnalytics(() => getAnalytics()),
    ...
  ],
  exports: [],
  providers: [...],
  bootstrap: [AppComponent]
})

The emulator is logging:

✔ functions[us-central1-addMessage2]: http function initialized (http://127.0.0.1:5001/{project-name}/us-central1/addMessage2).

The angular call to the endpoint is failing cors with:

Access to fetch at 'https://us-central1-{project-name}.cloudfunctions.net/addMessage2' from origin 'http://localhost:4200' 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.

5
  • Sorry if I ask, but do you have started the emulators before you start the angular app? Commented Dec 5, 2022 at 13:11
  • Yes, emulators are running Commented Dec 6, 2022 at 0:24
  • I guess I could ask a bit more specific question about the error message: Am I mistaken in thinking the address in 'us-central1-{project-name}.cloudfunctions.net/addMessage2' in the error message is telling me it is trying to hit the production server vs. the emulator's servers at HTTP://127.0.0.1:5001. Commented Dec 6, 2022 at 1:28
  • Also, when I launch the application and debug the app.module.ts, the debugger never stops in the provideFunctions method. Commented Dec 6, 2022 at 1:35
  • Can you look into my provided answer ? Commented Dec 22, 2022 at 13:21

2 Answers 2

1

I figured it out with this two-part answer:

Part 1:

passed getApp() into getFunctions.

    -- FUNCTIONS CONFIG CODE --

    provideFunctions(() => {
      const functions = getFunctions(getApp());  << Notice <<
      if (environment.useEmulators) {
        connectFunctionsEmulator(functions, 'localhost', 5001);
      }
      return functions;
    }),

    -- FUNCTIONS CONFIG CODE --

Part 2:

Make sure to inject functions into components as apposed to calling getFunctions.

    constructor(private auth: Auth, private firestore: Firestore, 
        public dialog: MatDialog, private userService: UserService, 
        private func: Functions) {}           << Notice <<
Sign up to request clarification or add additional context in comments.

1 Comment

Does this solve your issue ?, because you haven't provided the implementation part in the question. If this resolves your issue accept this answer as other community members will also get help with this accepted answer.
0

You can follow this Instructions provided in this Article to Emulating Firebase Cloud Functions in the local environment for that use :

provideFunctions(() => {
      const functions = getFunctions(getApp());
      if (environment.useEmulators) {
        connectFunctionsEmulator(functions, 'localhost', 5001);
      }
      return functions;
    })

In that article it is mentioned how to set CORS header also like this :

export const helloWorld = functions.https.onRequest((request, response) => {
  response.set('Access-Control-Allow-Origin', '*');
  response.send({ message: 'Hello from Firebase emulator!' });
});

3 Comments

This does solve the CORS issue, but that is not the problem. I was failing CORS because the dev configuration was not pointing at the local emulator. It was failing because, instead, it was pointing at the production URL, which fails CORS.
Sorry, I tried to edit the above, but ran out of time. This does solve the CORS issue, but that was not the root cause of my problem. It failed CORS because the dev configuration was not accessing the local emulator endpoint. Instead, it was attempting to access the production URL, which then fails CORS. Also, you should look into your getFunctions(getApp()) to leverage Firebase's built-in App and Auth checks when using httpsCallable() to functions.https.onCall().
@DaveB I think your environment.useEmulators is set to false that's why it is hitting the production URL check your src/environments/environment.ts in that ensure the following variable set to useEmulators: true , because there is no way angular will point to production URL until and unless that if case fails.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.