Red-Tune-84
Red-Tune-84

Reputation: 387

How to test an onCall function as an authenticated user in the functions:shell

I want to test an onCall function via firebase functions:shell as an authenticated usr

I’ve tried many of the combinations of calls from https://firebase.google.com/docs/functions/local-emulator#invoke_https_functions As well as downloading and setting the GOOGLE_APPLICATION_CREDENTIALS env var

My function looks like this:

exports.sendMessage = functions.https.onCall((data, context) => { 
    if (!context.auth) {
        throw new functions.https.HttpsError('failed-precondition', 'The function must be called while authenticated.');
    }
    // Other logic

}

It works fine once deployed and hit from my ios app, but i can’t get it running in the shell.

The following command will actually hit the function:

sendMessage.post({headers: {'content-type' : 'application/json'},body: JSON.stringify({data: {'messageId':'test'} }) })

and returns

RESPONSE RECEIVED FROM FUNCTION: 400, {“error”:{“status”:“FAILED_PRECONDITION”,“message”:“The function must be called while authenticated.“}}

Which is correct but I want an authenticated user now. When I try to add auth like the docs recommend:

sendMessage('data', {auth:{uid:'USERUID'}}).post({headers: {'content-type' : 'application/json'},body: JSON.stringify({data: {'messageId':'test'} }) })

I end up getting ERROR SENDING REQUEST: Error: no auth mechanism defined

If I try following the Authorization headers on this page https://firebase.google.com/docs/functions/callable-reference like so:

sendMessage.post({headers: {'Authorization': 'Bearer USERUID', 'content-type' : 'application/json'},body: JSON.stringify({data: {'messageId':'test'} }) })

I get back:

RESPONSE RECEIVED FROM FUNCTION: 401, {"error":{"status":"UNAUTHENTICATED","message":"Unauthenticated"}}

How do you send the request as an authenticated user?

Related Links How to test `functions.https.onCall` firebase cloud functions locally?

Upvotes: 6

Views: 4143

Answers (2)

Fernando Leal
Fernando Leal

Reputation: 106

For anyone that need how is done fast.

First, get the bearer token:

curl -X POST \
  'http://localhost:9099/identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=fake-api-key' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "[email protected]",
    "password": "testPassword123",
    "returnSecureToken": true
  }'

Then use the bearer token on your function:

curl --location 'http://127.0.0.1:5001/{project_name}/us-central1/{function_name}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {token}' \
--data '{
    "data":{
    }
}'

change the variables, tip when you start the firebase emulators it says the URLs of your functions , hope it helps

Upvotes: 0

Doug Stevenson
Doug Stevenson

Reputation: 317467

According to the documentation, the Authorization header requires an authentication id token, not a user id. You'll have to generate a token somehow and pass that to the function. The callable function will then validate that token and provide the user id to the function via context.auth.

It looks like you can use the Firebase Auth REST API to get one of these tokens. Or you can generate one in a client app that uses Firebase Auth client libraries, log it and copy its value, and use it until it expires (1 hour).

Upvotes: 4

Related Questions