3
votes

I'm trying to call functions from app but it doesn't work and I'm getting the following error from the console:

index.esm.js:402 OPTIONS https://us-central1-undefined.cloudfunctions.net/addMessage 404 () Failed to load https://us-central1-undefined.cloudfunctions.net/addMessage: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://MYWEBADDRESS' is therefore not allowed access. The response had HTTP status code 404. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

firebase.json:

{
  "database": {
    "rules": "database.rules.json"
  },
  "hosting": {
    "public": "public",
    "rewrites": [
      {
        "source": "**",
        "function": "addMessage"
      }
    ]
  },
  "functions": {
    "predeploy": [
      "npm --prefix $RESOURCE_DIR run lint"
    ],
    "source": "functions"
  }
}

index.js

const functions = require('firebase-functions');

const admin = require('firebase-admin');
admin.initializeApp();


exports.addMessage = functions.https.onCall((data, context) => {

    // Message text passed from the client.
    const text = data.text;

        // Checking attribute.
    if (!(typeof text === 'string') || text.length === 0) {
      // Throwing an HttpsError so that the client gets the error details.
      throw new functions.https.HttpsError('invalid-argument', 'The function must be called with ' +
          'one arguments "text" containing the message text to add.');
    }
    // Checking that the user is authenticated.
    if (!context.auth) {
      // Throwing an HttpsError so that the client gets the error details.
      throw new functions.https.HttpsError('failed-precondition', 'The function must be called ' +
          'while authenticated.');
    }

    // Saving the new message to the Realtime Database.
    return admin.database().ref('/messages').push({
      text: text
    }).then(() => {
      console.log('New Message written');
      // Returning the sanitized message to the client.
      return { text: sanitizedMessage };
    }).catch((error) => {
    // Re-throwing the error as an HttpsError so that the client gets the error details.
    throw new functions.https.HttpsError('unknown', error.message, error);
  });
});

my script in index.html

var addMessage = firebase.functions().httpsCallable('addMessage');
addMessage({text: "messageText"}).then(function(result) {
     var message = result.data.text;
     console.log(message);
});

How I initialize Firebase:

  <script src="https://www.gstatic.com/firebasejs/5.0.4/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/5.0.4/firebase-auth.js"></script>
  <script src="https://www.gstatic.com/firebasejs/5.0.4/firebase-database.js"></script>
  <script src="https://www.gstatic.com/firebasejs/5.0.4/firebase-functions.js"></script>
    <script>
      // Initialize Firebase
      var config = {
        apiKey: "**",
        authDomain: "***",
        databaseURL: "***",
        storageBucket: "***",
      };
      firebase.initializeApp(config);
      var functions = firebase.functions();
    </script>
1
Is https://us-central1-undefined.cloudfunctions.net/addMessag the actual URL in the error message or did you replace something with undefined? - abraham
Yes it is the actual URL - mutlucan96
How are you initializing the Firebase SDK in the web client? - Doug Stevenson
And also, what versions of each SDK are you using, both client and server? - Doug Stevenson
@doug I edited my question by adding the initializing code. By the way, I also use Realtime Database and I don't have a problem with it. I use 5.0.4 on the client. What server? I don't have a server. My Firebase CLI version is 3.18.5. - mutlucan96

1 Answers

4
votes

I was having the same exact problem, found your question without an answer, but managed to figure it out in the end.

As @Doug Stevenson mentioned above in the comments, the problem is that the Cloud Functions URL you are seeing has undefined instead of your project ID as the last piece of the url subdomain.

The reason it is undefined is because your project ID is not part of your initial Firebase config object. Like me, you likely copied and pasted the starter snippet from Firebase for the JS SDK, but you did it before they started including the Project ID as part of it. For some reason, even though the project ID is now needed to construct the cloud functions URL, the SDK doesn't error / warn if you don't include it.

All you need to do is add the following field to your config object:

projectId: <YOUR_PROJECT_ID_HERE>

Then you should see the requests no longer 404.