15
votes

I have been trying new firebase callable cloud functions in firebase functions:shell I keep on getting following error

Request has incorrect Content-Type.

and

RESPONSE RECEIVED FROM FUNCTION: 400, {"error":{"status":"INVALID_ARGUMENT","message":"Bad Request"}}

Here is ho w I am trying to call this function on shell

myFunc.post(dataObject)

I have also tried this

myFunc.post().form(dataObject)

But then I get wrong encoding(form) error. dataObject is valid JSON.

Update:

I figured that I need to use firebase serve for local emulation of these callable https functions. Data needs to be passed in post request like this(notice how its nested in data parameter)

{
 "data":{
    "applicantId": "XycWNYxqGOhL94ocBl9eWQ6wxHn2",
    "openingId": "-L8kYvb_jza8bPNVENRN"
 }
}

What I can't figure still is how do I pass dummy auth info while calling that function via a REST client

4
What you're trying to do is not really well supported at the moment. You have to understand the wire protocol for callable in order to manipulate them, and that's not yet been documented.Doug Stevenson

4 Answers

18
votes

I managed to get it working running this from within the functions shell:

myFunc.post('').json({"message": "Hello!"})

3
votes

As far as I can tell, the second parameter to the function contains all of the additional data. Pass an object that contains a headers map and you should be able to specify anything you want.

myFunc.post("", { headers: { "authorization": "Bearer ..." } });

If you're using Express to handle routing, then it just looks like:

myApp.post("/my-endpoint", { headers: { "authorization": "Bearer ..." } });
2
votes

If you take a look at the source code, you can see that it is just a normal https post function With an authentication header that contains a json web token, I'd recommend using the unit test api for https functions and mocking the header methods to return a token from a test user as well as the request body

[Update] Example

const firebase = require("firebase");
var config = {
  your config
};
firebase.initializeApp(config);
const test = require("firebase-functions-test")(
  {
    your config
  },
  "your access token"
);
const admin = require("firebase-admin");
const chai = require("chai");
const sinon = require("sinon");

const email = "test@test.test";
const password = "password";
let myFunctions = require("your function file");
firebase
  .auth()
  .signInWithEmailAndPassword(email, password)
  .then(user => user.getIdToken())
  .then(token => {
    const req = {
      body: { data: { your:"data"} },
      method: "POST",
      contentType: "application/json",
      header: name =>
        name === "Authorization"
          ? `Bearer ${token}`
          : name === "Content-Type" ? "application/json" : null,
      headers: { origin: "" }
    };
    const res = {
      status: status => {
        console.log("Status: ", status);
        return {
          send: result => {
            console.log("result", result);
          }
        };
      },
      getHeader: () => {},
      setHeader: () => {}
    };
    myFunctions.yourFunction(req, res);
  })
  .catch(console.error);
1
votes

The correct syntax for the CLI has changed to myFunc({"message": "Hello!"})