I'm using a google cloud function to get an token from Firestore, check if it is still active, if so return access token. Else:
- Get refresh token from secretmanager
- Refresh
- Update refresh token in secret manager
- Update access token in firebase
Now i get this error sometimes... This function is minimally called every 15 minutes from an different cloud function. The error occurs like 5 times a day. I've seen this post but can't wrap my head around to get this translated to my code.
Error:
FetchError: request to https://europe-west1-project.cloudfunctions.net/getToken failed, reason: socket hang up
at ClientRequest.<anonymous> (/workspace/node_modules/node-fetch/lib/index.js:1461:11)
at ClientRequest.emit (events.js:315:20)
at ClientRequest.EventEmitter.emit (domain.js:467:12)
at TLSSocket.socketOnEnd (_http_client.js:493:9)
at TLSSocket.emit (events.js:327:22)
at TLSSocket.EventEmitter.emit (domain.js:529:15)
at endReadableNT (internal/streams/readable.js:1327:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21)
Code:
const { SecretManagerServiceClient } = require("@google-cloud/secret-manager");
const client = new SecretManagerServiceClient();
const name = `projects/${process.env["PROJECT"]}/secrets/TOKEN/versions/latest`;
const axios = require("axios");
const milliseconds = new Date().getTime()
const now = Math.round(milliseconds / 1000);
const { Firestore } = require("@google-cloud/firestore");
const firestore = new Firestore();
const tokens = firestore.collection("tokens");
module.exports = async function getToken() {
let responseData;
await tokens.where("system", "==", "x").limit(1).get()
.then((res) => {
res.forEach((snap) => {
responseData = snap.data();
});
})
.catch((err) => {
console.error(JSON.stringify(err));
});
console.log(`custom_log: now = ${now}`)
console.log(JSON.stringify(responseData))
if (now - responseData.timestamp < 250) {
console.log(`custom_log: Returning access token from Firebase`)
return responseData.access_token;
} else {
console.log(`custom_log: Return new access token`)
return await refreshToken();
}
};
async function refreshToken() {
const [version] = await client.accessSecretVersion({ name: name });
const secret = version.payload.data.toString();
const config = {
method: "post",
url: "https://login.webpage.com/token?grant_type=client_credentials",
headers: {
Authorization: `Basic ${secret}`,
},
};
return axios(config)
.then((response) => {
updateAccesToken(response.data.access_token)
return response.data.access_token;
})
.catch((error) => {
console.error(`custom_error: Error refresh token: ${error.message}`);
});
}
async function updateAccesToken(token) {
await tokens.doc('token').update({
timestamp: now,
access_token: token,
dateTime: new Date(milliseconds).toISOString()
})
console.log('custom_log: access_token updated in Firestore')
}
