I have implemented a custom oidc authentication provider with firebase. (Which was very easy!)
For reference, the oidc provider I implemented is for Xero (accounting app)
I want to implement authenticated httpsCallable functions that use the accessToken that is returned from the callback but I can't seem to access it in the firebase function.
Ultimately the getTokenSetFromDatabase function from this example is what I need to recreate somehow in firebase function:
https://github.com/XeroAPI/xero-node#accounting-api
The context.auth info in the firebase functions contains some authentication data but not any jwts or tokens.
export const getTenants = functions.https.onCall(async (data, context) => {
await xero.initialize()
// Can I get the token set somehow from the context
// Or do I need to save a users token in the firebase database when they login from the front end?
const tokenSet = getTokenSetFromDatabase(context.auth?.uid)
await xero.setTokenSet(tokenSet)
if (tokenSet.expired()) {
const validTokenSet = await xero.refreshToken()
// save the new tokenset
}
await xero.updateTenants()
const activeTenantId = xero.tenants[0].tenantId
return activeTenantId
})
The console log of context.auth.token is:
{
"name": "Jialx",
"iss": "https://securetoken.google.com/firebase-app-name",
"aud": "firebase-app-name",
"auth_time": 1658994364,
"user_id": "0000000000000000000000",
"sub": "0000000000000000000000",
"iat": 1659007170,
"exp": 1659010770,
"email": "example@email.com",
"email_verified": false,
"firebase": {
"identities": { "oidc.xero": [], "email": [] },
"sign_in_provider": "oidc.xero",
"sign_in_attributes": {
"at_hash": "xx-xxxx-xxxx",
"preferred_username": "example@gmail.com",
"sid": "000000000000000000000000000",
"global_session_id": "000000000000000000000000000",
"xero_userid": "000000000000000000000000000"
}
},
"uid": "0000000000000000000000"
}
Discovery
So i've stumbled across the blocking functions feature when beforeSignIn function can access these oAuth credentials; so I figure that this would be a great place to save them to the DB and retrieve them later (what its built for).
It does work but its buggy (See answer for details)
