firebase-functions: Node 10 callable function returning unauthenticated

Related issues

[REQUIRED] Version info

node:

v10.15.2

firebase-functions: 2.3.0

firebase-tools:

6.8.0

firebase-admin: 7.3.0

[REQUIRED] Test case

Create a callable function:

exports.hello = functions.https.onCall(async (data, context) => {
  return { message: 'Hello World' };
});

In client side javascript, call the function after the user has logged in:

firebase.auth().onAuthStateChanged(user => {
  if (user) {
    firebase.functions()
      .httpsCallable('hello')()
      .then(result => {
        console.log(result);
      })
      .catch(err => {
        console.error(err);
      });
  }
});

[REQUIRED] Steps to reproduce

Deploy the function using the node 10 engine configured in the functions package.json. Deploy the html with the client side code for authenticating and calling the function to firebase hosting. Navigate to the page hosted on firebase and login.

[REQUIRED] Expected behavior

See the response from the callable function output in the browser console. This is when deployed using node 8:

{ data: { message: 'Hello World' } }

[REQUIRED] Actual behavior

Unauthenticated error response from calling the function. This does not happen when the function is deployed using node 8 as the engine.

Navigated to https://boilerplate-user-management.firebaseapp.com/
hello:1 POST https://us-central1-boilerplate-user-management.cloudfunctions.net/hello 401
index.js:26 Error: Unauthenticated
    at new i (error.ts:65)
    at error.ts:172
    at e.<anonymous> (service.ts:215)
    at tslib.es6.js:97
    at Object.next (tslib.es6.js:78)
    at n (tslib.es6.js:68)
(anonymous) @ index.js:26
Promise.catch (async)
(anonymous) @ index.js:25
(anonymous) @ subscribe.ts:104
(anonymous) @ subscribe.ts:225
Promise.then (async)
t.sendOne @ subscribe.ts:222
t.forEachObserver @ subscribe.ts:213
t.next @ subscribe.ts:103
n @ auth.js:1281
(anonymous) @ auth.js:1807
e.g @ promise.js:832
Ct @ promise.js:1171
Rt @ promise.js:1145
t.Yb @ promise.js:1116
dt @ run.js:132
Promise.then (async)
rt @ run.js:63
ht @ run.js:42
_t @ promise.js:1034
Nt @ promise.js:927
(anonymous) @ promise.js:175
t.onsuccess @ indexeddb.js:397
IndexedDB (async)
(anonymous) @ indexeddb.js:503
e.g @ promise.js:832
Ct @ promise.js:1171
Rt @ promise.js:1145
t.Yb @ promise.js:1116
dt @ run.js:132
Promise.then (async)
rt @ run.js:63
ht @ run.js:42
_t @ promise.js:1034
Nt @ promise.js:927
(anonymous) @ promise.js:175
t.onsuccess @ indexeddb.js:397
IndexedDB (async)
(anonymous) @ indexeddb.js:503
e.g @ promise.js:832
Ct @ promise.js:1171
Rt @ promise.js:1145
t.Yb @ promise.js:1116
dt @ run.js:132
Promise.then (async)
rt @ run.js:63
ht @ run.js:42
_t @ promise.js:1034
Nt @ promise.js:927
(anonymous) @ promise.js:175
t.onsuccess @ indexeddb.js:397
IndexedDB (async)
(anonymous) @ indexeddb.js:436
e.g @ promise.js:832
Ct @ promise.js:1171
Rt @ promise.js:1145
t.Yb @ promise.js:1116
dt @ run.js:132
Promise.then (async)
rt @ run.js:63
ht @ run.js:42
_t @ promise.js:1034
Nt @ promise.js:927
(anonymous) @ promise.js:175
t.onsuccess @ indexeddb.js:397
IndexedDB (async)
(anonymous) @ indexeddb.js:426
e.g @ promise.js:832
Ct @ promise.js:1171
Rt @ promise.js:1145
t.Yb @ promise.js:1116
dt @ run.js:132
Promise.then (async)
rt @ run.js:63
ht @ run.js:42
_t @ promise.js:1034
Nt @ promise.js:927
(anonymous) @ promise.js:175
(anonymous) @ rpchandler.js:789
(anonymous) @ rpchandler.js:520
Ce @ eventtarget.js:285
_e.dispatchEvent @ eventtarget.js:383
Wo @ xhrio.js:872
t.yc @ xhrio.js:818
t.Jb @ xhrio.js:802
XMLHttpRequest.send (async)
Ko @ xhrio.js:632
da.m @ rpchandler.js:549
Ta @ rpchandler.js:455
(anonymous) @ rpchandler.js:777
pt @ promise.js:171
(anonymous) @ rpchandler.js:772
(anonymous) @ rpchandler.js:758
e.g @ promise.js:832
Ct @ promise.js:1171
Rt @ promise.js:1145
t.Yb @ promise.js:1116
dt @ run.js:132
Promise.then (async)
rt @ run.js:63
ht @ run.js:42
_t @ promise.js:1034
Nt @ promise.js:927
(anonymous) @ promise.js:175
t.onsuccess @ indexeddb.js:397
IndexedDB (async)
(anonymous) @ indexeddb.js:503
e.g @ promise.js:832
Ct @ promise.js:1171
Rt @ promise.js:1145
t.Yb @ promise.js:1116
dt @ run.js:132
Promise.then (async)
rt @ run.js:63
ht @ run.js:42
_t @ promise.js:1034
Nt @ promise.js:927
(anonymous) @ promise.js:175
t.onsuccess @ indexeddb.js:397
IndexedDB (async)
(anonymous) @ indexeddb.js:503
e.g @ promise.js:832
Ct @ promise.js:1171
Rt @ promise.js:1145
t.Yb @ promise.js:1116
dt @ run.js:132
Promise.then (async)
rt @ run.js:63
ht @ run.js:42
_t @ promise.js:1034
Nt @ promise.js:927
(anonymous) @ promise.js:175
t.onsuccess @ indexeddb.js:397
IndexedDB (async)
(anonymous) @ indexeddb.js:503
e.g @ promise.js:832
Ct @ promise.js:1171
Rt @ promise.js:1145
t.Yb @ promise.js:1116
dt @ run.js:132
Promise.then (async)
rt @ run.js:63
ht @ run.js:42
_t @ promise.js:1034
Nt @ promise.js:927
(anonymous) @ promise.js:175
t.onsuccess @ indexeddb.js:397
IndexedDB (async)
(anonymous) @ indexeddb.js:526
e.g @ promise.js:832
Ct @ promise.js:1171
Rt @ promise.js:1145
t.Yb @ promise.js:1116
dt @ run.js:132
Promise.then (async)
rt @ run.js:63
ht @ run.js:42
_t @ promise.js:1034
Nt @ promise.js:927
(anonymous) @ promise.js:175
t.onsuccess @ indexeddb.js:397
IndexedDB (async)
(anonymous) @ indexeddb.js:503
e.g @ promise.js:832
Ct @ promise.js:1171
Rt @ promise.js:1145
t.Yb @ promise.js:1116
dt @ run.js:132
Promise.then (async)
rt @ run.js:63
ht @ run.js:42
_t @ promise.js:1034
Nt @ promise.js:927
(anonymous) @ promise.js:175
t.onsuccess @ indexeddb.js:397
IndexedDB (async)
(anonymous) @ indexeddb.js:443
e.g @ promise.js:832
Ct @ promise.js:1171
Rt @ promise.js:1145
t.Yb @ promise.js:1116
dt @ run.js:132
Promise.then (async)
rt @ run.js:63
ht @ run.js:42
_t @ promise.js:1034
Nt @ promise.js:927
(anonymous) @ promise.js:175
t.onsuccess @ indexeddb.js:397
IndexedDB (async)
(anonymous) @ indexeddb.js:426
e.g @ promise.js:832
Ct @ promise.js:1171
Rt @ promise.js:1145
t.Yb @ promise.js:1116
dt @ run.js:132
Promise.then (async)
rt @ run.js:63
ht @ run.js:42
_t @ promise.js:1034
Nt @ promise.js:927
(anonymous) @ promise.js:175
t.onsuccess @ indexeddb.js:322
IndexedDB (async)
(anonymous) @ indexeddb.js:282
pt @ promise.js:171
xs @ indexeddb.js:283
Ms @ indexeddb.js:339
set @ indexeddb.js:421
(anonymous) @ indexeddb.js:251
e.g @ promise.js:832
Ct @ promise.js:1171
Rt @ promise.js:1145
t.Yb @ promise.js:1116
dt @ run.js:132
Promise.then (async)
rt @ run.js:63
ht @ run.js:42
_t @ promise.js:1034
Nt @ promise.js:927
It @ promise.js:353
Ws @ hybridindexeddb.js:57
ou @ factory.js:118
au @ authstorage.js:229
Kc @ storageusermanager.js:89
Jc @ auth.js:121
qh.INTERNAL.extendNamespace.User @ exports_auth.js:634
t._getService @ firebaseApp.ts:161
An.<computed> @ firebaseNamespace.ts:226
(anonymous) @ exports_auth.js:696
(anonymous) @ firebaseNamespace.ts:250
p @ firebaseNamespace.ts:242
initializeApp @ firebaseNamespace.ts:158
(anonymous) @ init.js:2

Were you able to successfully deploy your functions?

Yes, they successfully deployed, there are no error messages when deploying.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 5
  • Comments: 23 (11 by maintainers)

Most upvoted comments

I’m new to firebase and this took me a few hours to find this bug report.

I discovered an interesting property - in node 10 engine for callable function when ‘Authorization’ header is missing the function is executed fine, but when it’s present (either valid or invalid) the function is never executed and firebase returns {"error":{"status":"UNAUTHENTICATED","message":"Unauthenticated"}}.

I just deployed and tested with: “dependencies”: { “firebase”: “^6.2.0”, “firebase-admin”: “~8.1.0”, “firebase-functions”: “^3.0.1”, “firebase-tools”: “^7.0.0”, },

and “engines”: { “node”: “10” }

and everything worked just fine

@doowb @enbyted The fix has been rolled out to production. Please let me know if you’re still seeing issues.

Thanks everyone for your feedback - this does indeed look like a bug on our side specific to Node 10 functions. We are working on a fix. Please see https://github.com/firebase/firebase-functions/issues/433 for more context. Thanks for your patience!