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

2

6

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?

Pebbly answered 11/9, 2018 at 19:2 Comment(0)
S
4

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).

Spouse answered 11/9, 2018 at 19:32 Comment(2)
Nice, very good thing. Could you write an example, in firebase shell, of call of a 'callable' with data structure for authentication ? i.e. second parameter of a callable. I cannot find any example anywhere.... :(Chervonets
Would love to see an example of authentication for testing callable functions, I find the docs a little light around that :)Cerell
A
0

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

Authorize answered 21/10 at 4:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.