firebasefirebase-authenticationgoogle-cloud-functions

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?


Solution

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