I want to test a a cloud function that creates users.
In normal cases, inside the browser i generate an idToken
and i send it to server via headers: Authorization : Bearer etcIdToken
But I want to test this function without the browser. In my mocha tests i have:
before(done => { firebase = require firebase.. -- this is suppose to be like the browser lib. admin = require admin.. idToken = null; uid = "AY8HrgYIeuQswolbLl53pjdJw8b2"; admin.auth() .createCustomToken(uid) -- admin creates a customToken .then(customToken => { return firebase.auth() -- this is like browser code. customToken get's passed to the browser. .signInWithCustomToken(customToken) -- browser signs in. .then(signedInUser => firebase.auth() -- now i want to get an idToken. But this gives me an error. .currentUser.getIdToken()) }) .then(idToken_ => { idToken = idToken_ done(); }) .catch(err => done(err)); })
The error i'm getting is:
firebase.auth(...).currentUser.getIdToken is not a function
- getting the idToken like this works on client - and is documented here.
I tried directly with signedInUser.getIdToken()
. Same problem:
signedInUser.getIdToken is not a function
- not documented. just a test.
I think this is because firebase
object is not intended for node.js
use like i'm doing here. When signing in - stuff get's saved in browser local storage - and maybe this is why.
But the question still remains. How can i get an idToken inside node.js in order to be able to test:
return chai.request(myFunctions.manageUsers) .post("/create") .set("Authorization", "Bearer " + idToken) --- i need the idToken here - like would be if i'm getting it from the browser. .send({ displayName: "jony", email: "[email protected]", password: "123456" })
am I approaching this wrong? I know that if i can get the idToken
it will work. Do i rely need the browser for this? Thanks :)
When a user or device successfully signs in, Firebase creates a corresponding ID token that uniquely identifies them and grants them access to several resources, such as Firebase Realtime Database and Cloud Storage. You can re-use that ID token to identify the user or device on your custom backend server.
Get an ID token from the Credentials object After you retrieve a user's credentials, check if the Credentials object includes an ID token. If it does, call getIdTokens to retrieve it, and send it to your backend by HTTPS POST.
From Exchange custom token for an ID and refresh token, you can transform a custom token to an id token with the api. Hence, you just have to generate a custom token first from the uid, then transform it in a custom token. Here is my sample:
const admin = require('firebase-admin'); const config = require('config'); const rp = require('request-promise'); module.exports.getIdToken = async uid => { const customToken = await admin.auth().createCustomToken(uid) const res = await rp({ url: `https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyCustomToken?key=${config.get('firebase.apiKey')}`, method: 'POST', body: { token: customToken, returnSecureToken: true }, json: true, }); return res.idToken; };
L. Meyer's Answer Worked for me.
But, the rp
npm package is deprecated and is no longer used. Here is the modified working code using axios.
const axios = require('axios').default; const admin = require('firebase-admin'); const FIREBASE_API_KEY = 'YOUR_API_KEY_FROM_FIREBASE_CONSOLE'; const createIdTokenfromCustomToken = async uid => { try { const customToken = await admin.auth().createCustomToken(uid); const res = await axios({ url: `https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyCustomToken?key=${FIREBASE_API_KEY}`, method: 'post', data: { token: customToken, returnSecureToken: true }, json: true, }); return res.data.idToken; } catch (e) { console.log(e); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With